| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | /**************************************************************************
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-06-17 00:01:27 +10:00
										 |  |  | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Commercial Usage | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Licensees holding valid Qt Commercial licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the Qt Commercial License Agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							|  |  |  | ** a written agreement between you and Nokia. | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** GNU Lesser General Public License Usage | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
					
						
							|  |  |  | ** General Public License version 2.1 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation and appearing in the file LICENSE.LGPL included in the | 
					
						
							|  |  |  | ** packaging of this file.  Please review the following information to | 
					
						
							|  |  |  | ** ensure the GNU Lesser General Public License version 2.1 requirements | 
					
						
							|  |  |  | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** If you are unsure which license is appropriate for your use, please | 
					
						
							| 
									
										
										
										
											2009-08-14 09:30:56 +02:00
										 |  |  | ** contact the sales department at http://qt.nokia.com/contact.
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | **************************************************************************/ | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "ResolveExpression.h"
 | 
					
						
							|  |  |  | #include "LookupContext.h"
 | 
					
						
							|  |  |  | #include "Overview.h"
 | 
					
						
							| 
									
										
										
										
											2009-10-26 12:41:13 +01:00
										 |  |  | #include "GenTemplateInstance.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <Control.h>
 | 
					
						
							|  |  |  | #include <AST.h>
 | 
					
						
							|  |  |  | #include <Scope.h>
 | 
					
						
							|  |  |  | #include <Names.h>
 | 
					
						
							|  |  |  | #include <Symbols.h>
 | 
					
						
							|  |  |  | #include <Literals.h>
 | 
					
						
							|  |  |  | #include <CoreTypes.h>
 | 
					
						
							|  |  |  | #include <TypeVisitor.h>
 | 
					
						
							|  |  |  | #include <NameVisitor.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:09:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  | #include <QtCore/QList>
 | 
					
						
							| 
									
										
										
										
											2009-05-19 13:24:20 +02:00
										 |  |  | #include <QtCore/QVarLengthArray>
 | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  | #include <QtCore/QtDebug>
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | using namespace CPlusPlus; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-09 15:25:01 +01:00
										 |  |  | namespace { | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  | template <typename _Tp> | 
					
						
							|  |  |  | static QList<_Tp> removeDuplicates(const QList<_Tp> &results) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<_Tp> uniqueList; | 
					
						
							|  |  |  |     QSet<_Tp> processed; | 
					
						
							|  |  |  |     foreach (const _Tp &r, results) { | 
					
						
							|  |  |  |         if (processed.contains(r)) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         processed.insert(r); | 
					
						
							|  |  |  |         uniqueList.append(r); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return uniqueList; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } // end of anonymous namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // ResolveExpression
 | 
					
						
							|  |  |  | /////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | ResolveExpression::ResolveExpression(const LookupContext &context) | 
					
						
							| 
									
										
										
										
											2009-11-17 13:28:20 +01:00
										 |  |  |     : ASTVisitor(context.expressionDocument()->translationUnit()), | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |       _context(context), | 
					
						
							| 
									
										
										
										
											2009-11-17 13:28:20 +01:00
										 |  |  |       sem(context.expressionDocument()->translationUnit()) | 
					
						
							| 
									
										
										
										
											2009-08-25 10:12:37 +02:00
										 |  |  | { } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | ResolveExpression::~ResolveExpression() | 
					
						
							|  |  |  | { } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  | QList<LookupItem> ResolveExpression::operator()(ExpressionAST *ast) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     const QList<LookupItem> previousResults = switchResults(QList<LookupItem>()); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     accept(ast); | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |     return removeDuplicates(switchResults(previousResults)); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  | QList<LookupItem> | 
					
						
							|  |  |  | ResolveExpression::switchResults(const QList<LookupItem> &results) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     const QList<LookupItem> previousResults = _results; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     _results = results; | 
					
						
							|  |  |  |     return previousResults; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  | void ResolveExpression::addResults(const QList<LookupItem> &results) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     foreach (const LookupItem r, results) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         addResult(r); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ResolveExpression::addResult(const FullySpecifiedType &ty, Symbol *symbol) | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  | { return addResult(LookupItem(ty, symbol)); } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  | void ResolveExpression::addResult(const LookupItem &r) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     LookupItem p = r; | 
					
						
							| 
									
										
										
										
											2009-08-07 13:02:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     if (! p.lastVisibleSymbol()) | 
					
						
							|  |  |  |         p.setLastVisibleSymbol(_context.symbol()); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (! _results.contains(p)) | 
					
						
							|  |  |  |         _results.append(p); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  | QList<Scope *> ResolveExpression::visibleScopes(const LookupItem &result) const | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { return _context.visibleScopes(result); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-04 15:52:17 +01:00
										 |  |  | bool ResolveExpression::visit(BinaryExpressionAST *ast) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-04 15:52:17 +01:00
										 |  |  |     accept(ast->left_expression); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(CastExpressionAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-17 11:11:21 +02:00
										 |  |  |     addResult(sem.check(ast->type_id, _context.expressionDocument()->globalSymbols())); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(ConditionAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // nothing to do.
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-23 14:53:44 +02:00
										 |  |  | bool ResolveExpression::visit(ConditionalExpressionAST *ast) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-23 14:53:44 +02:00
										 |  |  |     if (ast->left_expression) | 
					
						
							|  |  |  |         accept(ast->left_expression); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     else if (ast->right_expression) | 
					
						
							|  |  |  |         accept(ast->right_expression); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(CppCastExpressionAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-17 11:11:21 +02:00
										 |  |  |     addResult(sem.check(ast->type_id, _context.expressionDocument()->globalSymbols())); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(DeleteExpressionAST *) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-23 14:53:44 +02:00
										 |  |  |     FullySpecifiedType ty(control()->voidType()); | 
					
						
							|  |  |  |     addResult(ty); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(ArrayInitializerAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // nothing to do.
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-23 14:53:44 +02:00
										 |  |  | bool ResolveExpression::visit(NewExpressionAST *ast) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-23 14:53:44 +02:00
										 |  |  |     if (ast->new_type_id) { | 
					
						
							|  |  |  |         Scope *scope = _context.expressionDocument()->globalSymbols(); | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |         FullySpecifiedType ty = sem.check(ast->new_type_id->type_specifier_list, scope); | 
					
						
							|  |  |  |         ty = sem.check(ast->new_type_id->ptr_operator_list, ty, scope); | 
					
						
							| 
									
										
										
										
											2009-10-23 14:53:44 +02:00
										 |  |  |         FullySpecifiedType ptrTy(control()->pointerType(ty)); | 
					
						
							|  |  |  |         addResult(ptrTy); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     // nothing to do.
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(TypeidExpressionAST *) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *std_type_info[2]; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     std_type_info[0] = control()->nameId(control()->findOrInsertIdentifier("std")); | 
					
						
							|  |  |  |     std_type_info[1] = control()->nameId(control()->findOrInsertIdentifier("type_info")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *q = control()->qualifiedNameId(std_type_info, 2, /*global=*/ true); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     FullySpecifiedType ty(control()->namedType(q)); | 
					
						
							|  |  |  |     addResult(ty); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(TypenameCallExpressionAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // nothing to do
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(TypeConstructorCallAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // nothing to do.
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(PostfixExpressionAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     accept(ast->base_expression); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     for (PostfixListAST *it = ast->postfix_expression_list; it; it = it->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 14:24:32 +01:00
										 |  |  |         accept(it->value); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(SizeofExpressionAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     FullySpecifiedType ty(control()->integerType(IntegerType::Int)); | 
					
						
							|  |  |  |     ty.setUnsigned(true); | 
					
						
							|  |  |  |     addResult(ty); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-10 17:07:47 +02:00
										 |  |  | bool ResolveExpression::visit(NumericLiteralAST *ast) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-07-10 17:07:47 +02:00
										 |  |  |     Type *type = 0; | 
					
						
							| 
									
										
										
										
											2009-12-01 11:33:13 +01:00
										 |  |  |     const NumericLiteral *literal = numericLiteral(ast->literal_token); | 
					
						
							| 
									
										
										
										
											2009-07-10 17:07:47 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (literal->isChar()) | 
					
						
							|  |  |  |         type = control()->integerType(IntegerType::Char); | 
					
						
							|  |  |  |     else if (literal->isWideChar()) | 
					
						
							|  |  |  |         type = control()->integerType(IntegerType::WideChar); | 
					
						
							|  |  |  |     else if (literal->isInt()) | 
					
						
							|  |  |  |         type = control()->integerType(IntegerType::Int); | 
					
						
							|  |  |  |     else if (literal->isLong()) | 
					
						
							|  |  |  |         type = control()->integerType(IntegerType::Long); | 
					
						
							|  |  |  |     else if (literal->isLongLong()) | 
					
						
							|  |  |  |         type = control()->integerType(IntegerType::LongLong); | 
					
						
							|  |  |  |     else if (literal->isFloat()) | 
					
						
							|  |  |  |         type = control()->floatType(FloatType::Float); | 
					
						
							|  |  |  |     else if (literal->isDouble()) | 
					
						
							|  |  |  |         type = control()->floatType(FloatType::Double); | 
					
						
							|  |  |  |     else if (literal->isLongDouble()) | 
					
						
							|  |  |  |         type = control()->floatType(FloatType::LongDouble); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         type = control()->integerType(IntegerType::Int); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     FullySpecifiedType ty(type); | 
					
						
							|  |  |  |     if (literal->isUnsigned()) | 
					
						
							|  |  |  |         ty.setUnsigned(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     addResult(ty); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(BoolLiteralAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     FullySpecifiedType ty(control()->integerType(IntegerType::Bool)); | 
					
						
							|  |  |  |     addResult(ty); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(ThisExpressionAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! _context.symbol()) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Scope *scope = _context.symbol()->scope(); | 
					
						
							|  |  |  |     for (; scope; scope = scope->enclosingScope()) { | 
					
						
							|  |  |  |         if (scope->isFunctionScope()) { | 
					
						
							|  |  |  |             Function *fun = scope->owner()->asFunction(); | 
					
						
							|  |  |  |             if (Scope *cscope = scope->enclosingClassScope()) { | 
					
						
							|  |  |  |                 Class *klass = cscope->owner()->asClass(); | 
					
						
							|  |  |  |                 FullySpecifiedType classTy(control()->namedType(klass->name())); | 
					
						
							|  |  |  |                 FullySpecifiedType ptrTy(control()->pointerType(classTy)); | 
					
						
							|  |  |  |                 addResult(ptrTy, fun); | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |             } else if (const QualifiedNameId *q = fun->name()->asQualifiedNameId()) { | 
					
						
							|  |  |  |                 const Name *nestedNameSpecifier = 0; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                 if (q->nameCount() == 1 && q->isGlobal()) | 
					
						
							|  |  |  |                     nestedNameSpecifier = q->nameAt(0); | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     nestedNameSpecifier = control()->qualifiedNameId(q->names(), q->nameCount() - 1); | 
					
						
							|  |  |  |                 FullySpecifiedType classTy(control()->namedType(nestedNameSpecifier)); | 
					
						
							|  |  |  |                 FullySpecifiedType ptrTy(control()->pointerType(classTy)); | 
					
						
							|  |  |  |                 addResult(ptrTy, fun); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(NestedExpressionAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     accept(ast->expression); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(StringLiteralAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     FullySpecifiedType charTy = control()->integerType(IntegerType::Char); | 
					
						
							|  |  |  |     charTy.setConst(true); | 
					
						
							|  |  |  |     FullySpecifiedType ty(control()->pointerType(charTy)); | 
					
						
							|  |  |  |     addResult(ty); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(ThrowExpressionAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(TypeIdAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(UnaryExpressionAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     accept(ast->expression); | 
					
						
							|  |  |  |     unsigned unaryOp = tokenKind(ast->unary_op_token); | 
					
						
							|  |  |  |     if (unaryOp == T_AMPER) { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |         QMutableListIterator<LookupItem > it(_results); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         while (it.hasNext()) { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |             LookupItem p = it.next(); | 
					
						
							|  |  |  |             FullySpecifiedType ty = p.type(); | 
					
						
							|  |  |  |             ty.setType(control()->pointerType(ty)); | 
					
						
							|  |  |  |             p.setType(ty); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             it.setValue(p); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } else if (unaryOp == T_STAR) { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |         QMutableListIterator<LookupItem > it(_results); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         while (it.hasNext()) { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |             LookupItem p = it.next(); | 
					
						
							|  |  |  |             if (PointerType *ptrTy = p.type()->asPointerType()) { | 
					
						
							|  |  |  |                 p.setType(ptrTy->elementType()); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                 it.setValue(p); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 it.remove(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-13 16:03:46 +01:00
										 |  |  | bool ResolveExpression::visit(CompoundLiteralAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     accept(ast->type_id); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | bool ResolveExpression::visit(QualifiedNameAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-12-31 10:57:27 +01:00
										 |  |  |     ResolveClass resolveClass; | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *name = ast->name; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QList<Symbol *> symbols = _context.resolve(name); | 
					
						
							|  |  |  |     foreach (Symbol *symbol, symbols) { | 
					
						
							|  |  |  |         if (symbol->isTypedef()) { | 
					
						
							|  |  |  |             if (NamedType *namedTy = symbol->type()->asNamedType()) { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                 const LookupItem r(namedTy, symbol); | 
					
						
							| 
									
										
										
										
											2008-12-31 10:57:27 +01:00
										 |  |  |                 const QList<Symbol *> resolvedClasses = | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |                         resolveClass(namedTy->name(), r, _context); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                 if (resolvedClasses.count()) { | 
					
						
							|  |  |  |                     foreach (Symbol *s, resolvedClasses) { | 
					
						
							|  |  |  |                         addResult(s->type(), s); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         addResult(symbol->type(), symbol); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(OperatorFunctionIdAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(ConversionFunctionIdAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(SimpleNameAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-17 11:11:21 +02:00
										 |  |  |     QList<Symbol *> symbols = _context.resolve(ast->name); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     foreach (Symbol *symbol, symbols) | 
					
						
							|  |  |  |         addResult(symbol->type(), symbol); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(DestructorNameAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     FullySpecifiedType ty(control()->voidType()); | 
					
						
							|  |  |  |     addResult(ty); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(TemplateIdAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-17 11:11:21 +02:00
										 |  |  |     QList<Symbol *> symbols = _context.resolve(ast->name); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     foreach (Symbol *symbol, symbols) | 
					
						
							|  |  |  |         addResult(symbol->type(), symbol); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-16 12:22:33 +02:00
										 |  |  | bool ResolveExpression::maybeValidPrototype(Function *funTy, unsigned actualArgumentCount) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     unsigned minNumberArguments = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (; minNumberArguments < funTy->argumentCount(); ++minNumberArguments) { | 
					
						
							|  |  |  |         Argument *arg = funTy->argumentAt(minNumberArguments)->asArgument(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (arg->hasInitializer()) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (actualArgumentCount < minNumberArguments) { | 
					
						
							|  |  |  |         // not enough arguments.
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (! funTy->isVariadic() && actualArgumentCount > funTy->argumentCount()) { | 
					
						
							|  |  |  |         // too many arguments.
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | bool ResolveExpression::visit(CallAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-16 12:22:33 +02:00
										 |  |  |     ResolveClass resolveClass; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     const QList<LookupItem> baseResults = _results; | 
					
						
							| 
									
										
										
										
											2009-10-16 12:22:33 +02:00
										 |  |  |     _results.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     // Compute the types of the actual arguments.
 | 
					
						
							| 
									
										
										
										
											2009-10-28 13:43:06 +01:00
										 |  |  |     int actualArgumentCount = 0; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-28 13:43:06 +01:00
										 |  |  |     //QList< QList<Result> > arguments;
 | 
					
						
							|  |  |  |     for (ExpressionListAST *exprIt = ast->expression_list; exprIt; exprIt = exprIt->next) { | 
					
						
							|  |  |  |         //arguments.append(operator()(exprIt->expression));
 | 
					
						
							|  |  |  |         ++actualArgumentCount; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *functionCallOp = control()->operatorNameId(OperatorNameId::FunctionCallOp); | 
					
						
							| 
									
										
										
										
											2009-10-16 12:22:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     foreach (const LookupItem &result, baseResults) { | 
					
						
							|  |  |  |         FullySpecifiedType ty = result.type().simplified(); | 
					
						
							|  |  |  |         Symbol *lastVisibleSymbol = result.lastVisibleSymbol(); | 
					
						
							| 
									
										
										
										
											2009-10-16 12:22:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (NamedType *namedTy = ty->asNamedType()) { | 
					
						
							|  |  |  |             const QList<Symbol *> classObjectCandidates = resolveClass(namedTy->name(), result, _context); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             foreach (Symbol *classObject, classObjectCandidates) { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                 const QList<LookupItem> overloads = resolveMember(functionCallOp, classObject->asClass(), namedTy->name()); | 
					
						
							| 
									
										
										
										
											2009-10-16 12:22:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                 foreach (const LookupItem &o, overloads) { | 
					
						
							|  |  |  |                     FullySpecifiedType overloadTy = o.type().simplified(); | 
					
						
							| 
									
										
										
										
											2009-10-16 12:22:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     if (Function *funTy = overloadTy->asFunctionType()) { | 
					
						
							|  |  |  |                         if (maybeValidPrototype(funTy, actualArgumentCount)) | 
					
						
							|  |  |  |                             addResult(funTy->returnType().simplified(), lastVisibleSymbol); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-10-16 12:22:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-29 21:33:57 +01:00
										 |  |  |         } else if (Function *funTy = ty->asFunctionType()) { | 
					
						
							| 
									
										
										
										
											2009-10-16 12:22:33 +02:00
										 |  |  |             if (maybeValidPrototype(funTy, actualArgumentCount)) | 
					
						
							|  |  |  |                 addResult(funTy->returnType().simplified(), lastVisibleSymbol); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } else if (Class *classTy = ty->asClassType()) { | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             // Constructor call
 | 
					
						
							| 
									
										
										
										
											2009-10-16 12:22:33 +02:00
										 |  |  |             FullySpecifiedType ctorTy = control()->namedType(classTy->name()); | 
					
						
							|  |  |  |             addResult(ctorTy, lastVisibleSymbol); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(ArrayAccessAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     const QList<LookupItem> baseResults = _results; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     _results.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     const QList<LookupItem> indexResults = operator()(ast->expression); | 
					
						
							| 
									
										
										
										
											2009-10-16 11:43:13 +02:00
										 |  |  |     ResolveClass resolveClass; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *arrayAccessOp = control()->operatorNameId(OperatorNameId::ArrayAccessOp); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     foreach (const LookupItem &result, baseResults) { | 
					
						
							|  |  |  |         FullySpecifiedType ty = result.type().simplified(); | 
					
						
							|  |  |  |         Symbol *contextSymbol = result.lastVisibleSymbol(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (PointerType *ptrTy = ty->asPointerType()) { | 
					
						
							| 
									
										
										
										
											2009-10-16 11:43:13 +02:00
										 |  |  |             addResult(ptrTy->elementType().simplified(), contextSymbol); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } else if (ArrayType *arrTy = ty->asArrayType()) { | 
					
						
							| 
									
										
										
										
											2009-10-16 11:43:13 +02:00
										 |  |  |             addResult(arrTy->elementType().simplified(), contextSymbol); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } else if (NamedType *namedTy = ty->asNamedType()) { | 
					
						
							| 
									
										
										
										
											2008-12-30 11:54:42 +01:00
										 |  |  |             const QList<Symbol *> classObjectCandidates = | 
					
						
							| 
									
										
										
										
											2009-10-16 11:43:13 +02:00
										 |  |  |                     resolveClass(namedTy->name(), result, _context); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             foreach (Symbol *classObject, classObjectCandidates) { | 
					
						
							| 
									
										
										
										
											2009-10-16 11:43:13 +02:00
										 |  |  |                 Q_ASSERT(classObject->isClass()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                 const QList<LookupItem> overloads = | 
					
						
							| 
									
										
										
										
											2009-10-16 11:43:13 +02:00
										 |  |  |                         resolveMember(arrayAccessOp, classObject->asClass(), namedTy->name()); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                 foreach (LookupItem r, overloads) { | 
					
						
							|  |  |  |                     FullySpecifiedType ty = r.type().simplified(); | 
					
						
							| 
									
										
										
										
											2009-10-16 11:43:13 +02:00
										 |  |  |                     if (Function *funTy = ty->asFunctionType()) { | 
					
						
							|  |  |  |                         ty = funTy->returnType().simplified(); | 
					
						
							|  |  |  |                         addResult(ty, funTy); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ResolveExpression::visit(MemberAccessAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // The candidate types for the base expression are stored in
 | 
					
						
							|  |  |  |     // _results.
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     QList<LookupItem> baseResults = _results; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Evaluate the expression-id that follows the access operator.
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *memberName = 0; | 
					
						
							| 
									
										
										
										
											2009-06-17 11:11:21 +02:00
										 |  |  |     if (ast->member_name) | 
					
						
							|  |  |  |         memberName = ast->member_name->name; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Remember the access operator.
 | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |     const int accessOp = tokenKind(ast->access_token); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     _results = resolveMemberExpression(baseResults, accessOp, memberName); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  | QList<LookupItem> | 
					
						
							|  |  |  | ResolveExpression::resolveBaseExpression(const QList<LookupItem> &baseResults, int accessOp, | 
					
						
							| 
									
										
										
										
											2009-10-16 11:08:06 +02:00
										 |  |  |                                          bool *replacedDotOperator) const | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     QList<LookupItem> results; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |     if (baseResults.isEmpty()) | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |         return results; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     LookupItem result = baseResults.first(); | 
					
						
							|  |  |  |     FullySpecifiedType ty = result.type().simplified(); | 
					
						
							|  |  |  |     Symbol *lastVisibleSymbol = result.lastVisibleSymbol(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-27 16:08:23 +01:00
										 |  |  |     if (Function *funTy = ty->asFunctionType()) { | 
					
						
							|  |  |  |         if (funTy->isAmbiguous()) | 
					
						
							|  |  |  |             ty = funTy->returnType().simplified(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |     if (accessOp == T_ARROW)  { | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |         if (lastVisibleSymbol && ty->isClassType() && ! lastVisibleSymbol->isClass()) { | 
					
						
							|  |  |  |             // ### remove ! lastVisibleSymbol->isClass() from the condition.
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |             results.append(LookupItem(ty, lastVisibleSymbol)); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |         } else if (NamedType *namedTy = ty->asNamedType()) { | 
					
						
							|  |  |  |             // ### This code is pretty slow.
 | 
					
						
							|  |  |  |             const QList<Symbol *> candidates = _context.resolve(namedTy->name()); | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |             foreach (Symbol *candidate, candidates) { | 
					
						
							|  |  |  |                 if (candidate->isTypedef()) { | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |                     FullySpecifiedType declTy = candidate->type().simplified(); | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                     const LookupItem r(declTy, candidate); | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     // update the result
 | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |                     result = r; | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     // refresh the cached ty and lastVisibileSymbol.
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                     ty = result.type().simplified(); | 
					
						
							|  |  |  |                     lastVisibleSymbol = result.lastVisibleSymbol(); | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |                     break; | 
					
						
							| 
									
										
										
										
											2009-06-10 14:45:27 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (NamedType *namedTy = ty->asNamedType()) { | 
					
						
							|  |  |  |             ResolveClass resolveClass; | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |             const Name *arrowAccessOp = control()->operatorNameId(OperatorNameId::ArrowOp); | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |             const QList<Symbol *> candidates = resolveClass(namedTy->name(), result, _context); | 
					
						
							| 
									
										
										
										
											2009-10-16 11:43:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-29 21:33:57 +01:00
										 |  |  |             foreach (Symbol *classObject, candidates) { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                 const QList<LookupItem> overloads = resolveMember(arrowAccessOp, classObject->asClass(), | 
					
						
							| 
									
										
										
										
											2009-10-16 11:43:13 +02:00
										 |  |  |                                                               namedTy->name()); | 
					
						
							| 
									
										
										
										
											2009-06-10 14:45:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                 foreach (const LookupItem &r, overloads) { | 
					
						
							|  |  |  |                     FullySpecifiedType typeOfOverloadFunction = r.type().simplified(); | 
					
						
							|  |  |  |                     Symbol *lastVisibleSymbol = r.lastVisibleSymbol(); | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |                     Function *funTy = typeOfOverloadFunction->asFunctionType(); | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |                     if (! funTy) | 
					
						
							|  |  |  |                         continue; | 
					
						
							| 
									
										
										
										
											2009-06-10 14:45:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |                     typeOfOverloadFunction = funTy->returnType().simplified(); | 
					
						
							| 
									
										
										
										
											2009-06-10 14:45:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |                     if (PointerType *ptrTy = typeOfOverloadFunction->asPointerType()) { | 
					
						
							|  |  |  |                         FullySpecifiedType elementTy = ptrTy->elementType().simplified(); | 
					
						
							| 
									
										
										
										
											2009-06-10 14:45:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |                         if (elementTy->isNamedType()) | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                             results.append(LookupItem(elementTy, lastVisibleSymbol)); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |         } else if (PointerType *ptrTy = ty->asPointerType()) { | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |             FullySpecifiedType elementTy = ptrTy->elementType().simplified(); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |             if (elementTy->isNamedType() || elementTy->isClassType()) | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                 results.append(LookupItem(elementTy, lastVisibleSymbol)); | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } else if (accessOp == T_DOT) { | 
					
						
							| 
									
										
										
										
											2009-10-16 11:08:06 +02:00
										 |  |  |         if (replacedDotOperator) { | 
					
						
							|  |  |  |             if (PointerType *ptrTy = ty->asPointerType()) { | 
					
						
							|  |  |  |                 *replacedDotOperator = true; | 
					
						
							|  |  |  |                 ty = ptrTy->elementType().simplified(); | 
					
						
							|  |  |  |             } else if (ArrayType *arrTy = ty->asArrayType()) { | 
					
						
							|  |  |  |                 *replacedDotOperator = true; | 
					
						
							|  |  |  |                 ty = arrTy->elementType().simplified(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-28 12:26:08 +01:00
										 |  |  |         if (NamedType *namedTy = ty->asNamedType()) { | 
					
						
							|  |  |  |             const QList<Scope *> visibleScopes = _context.visibleScopes(result); | 
					
						
							| 
									
										
										
										
											2009-12-08 12:38:27 +01:00
										 |  |  |             const QList<Symbol *> candidates = _context.resolve(namedTy->name(), visibleScopes); | 
					
						
							|  |  |  |             foreach (Symbol *candidate, candidates) { | 
					
						
							|  |  |  |                 if (candidate->isTypedef() && candidate->type()->isNamedType()) { | 
					
						
							|  |  |  |                     ty = candidate->type(); | 
					
						
							|  |  |  |                     lastVisibleSymbol = candidate; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } else if (TypenameArgument *arg = candidate->asTypenameArgument()) { | 
					
						
							|  |  |  |                     ty = arg->type(); | 
					
						
							|  |  |  |                     lastVisibleSymbol = candidate; | 
					
						
							| 
									
										
										
										
											2009-10-28 12:26:08 +01:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |             results.append(LookupItem(ty, lastVisibleSymbol)); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-28 12:26:08 +01:00
										 |  |  |         } else if (Function *fun = ty->asFunctionType()) { | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |             Scope *funScope = fun->scope(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (funScope && (funScope->isBlockScope() || funScope->isNamespaceScope())) { | 
					
						
							|  |  |  |                 FullySpecifiedType retTy = fun->returnType().simplified(); | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                 results.append(LookupItem(retTy, lastVisibleSymbol)); | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |     return removeDuplicates(results); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  | QList<LookupItem> | 
					
						
							|  |  |  | ResolveExpression::resolveMemberExpression(const QList<LookupItem> &baseResults, | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  |                                            unsigned accessOp, | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |                                            const Name *memberName, | 
					
						
							| 
									
										
										
										
											2009-10-16 11:08:06 +02:00
										 |  |  |                                            bool *replacedDotOperator) const | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |     ResolveClass resolveClass; | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     QList<LookupItem> results; | 
					
						
							| 
									
										
										
										
											2008-12-30 11:54:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     const QList<LookupItem> classObjectResults = resolveBaseExpression(baseResults, accessOp, replacedDotOperator); | 
					
						
							|  |  |  |     foreach (const LookupItem &r, classObjectResults) { | 
					
						
							|  |  |  |         FullySpecifiedType ty = r.type(); | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (Class *klass = ty->asClassType()) | 
					
						
							|  |  |  |             results += resolveMember(memberName, klass); | 
					
						
							| 
									
										
										
										
											2008-12-30 11:54:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |         else if (NamedType *namedTy = ty->asNamedType()) { | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |             const Name *className = namedTy->name(); | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |             const QList<Symbol *> classes = resolveClass(className, r, _context); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             foreach (Symbol *c, classes) { | 
					
						
							|  |  |  |                 if (Class *klass = c->asClass()) | 
					
						
							|  |  |  |                     results += resolveMember(memberName, klass, className); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |     return removeDuplicates(results); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  | QList<LookupItem> | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  | ResolveExpression::resolveMember(const Name *memberName, Class *klass, | 
					
						
							|  |  |  |                                  const Name *className) const | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     QList<LookupItem> results; | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |     if (! className) | 
					
						
							|  |  |  |         className = klass->name(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (! className) | 
					
						
							|  |  |  |         return results; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     QList<Scope *> scopes; | 
					
						
							|  |  |  |     _context.expand(klass->members(), _context.visibleScopes(), &scopes); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-26 17:54:32 +01:00
										 |  |  |     const QList<Symbol *> candidates = _context.resolve(memberName, scopes); | 
					
						
							| 
									
										
										
										
											2009-09-30 11:49:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     foreach (Symbol *candidate, candidates) { | 
					
						
							|  |  |  |         FullySpecifiedType ty = candidate->type(); | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |         const Name *unqualifiedNameId = className; | 
					
						
							| 
									
										
										
										
											2010-01-29 21:33:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |         if (const QualifiedNameId *q = className->asQualifiedNameId()) | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |             unqualifiedNameId = q->unqualifiedNameId(); | 
					
						
							| 
									
										
										
										
											2010-01-29 21:33:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |         if (const TemplateNameId *templId = unqualifiedNameId->asTemplateNameId()) { | 
					
						
							| 
									
										
										
										
											2009-10-26 12:41:13 +01:00
										 |  |  |             GenTemplateInstance::Substitution subst; | 
					
						
							| 
									
										
										
										
											2010-01-29 21:33:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |             for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) { | 
					
						
							|  |  |  |                 FullySpecifiedType templArgTy = templId->templateArgumentAt(i); | 
					
						
							| 
									
										
										
										
											2010-01-29 21:33:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-26 17:54:32 +01:00
										 |  |  |                 if (i < klass->templateParameterCount()) { | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |                     const Name *templArgName = klass->templateParameterAt(i)->name(); | 
					
						
							| 
									
										
										
										
											2009-10-26 17:54:32 +01:00
										 |  |  |                     if (templArgName && templArgName->identifier()) { | 
					
						
							| 
									
										
										
										
											2009-12-01 11:33:13 +01:00
										 |  |  |                         const Identifier *templArgId = templArgName->identifier(); | 
					
						
							| 
									
										
										
										
											2009-10-26 17:54:32 +01:00
										 |  |  |                         subst.append(qMakePair(templArgId, templArgTy)); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-01-29 21:33:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-26 17:54:32 +01:00
										 |  |  |             GenTemplateInstance inst(_context, subst); | 
					
						
							|  |  |  |             ty = inst(candidate); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-01-29 21:33:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |         results.append(LookupItem(ty, candidate)); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |     return removeDuplicates(results); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  | QList<LookupItem> | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  | ResolveExpression::resolveMember(const Name *memberName, ObjCClass *klass) const | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     QList<LookupItem> results; | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!memberName || !klass) | 
					
						
							|  |  |  |         return results; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QList<Scope *> scopes; | 
					
						
							|  |  |  |     _context.expand(klass->members(), _context.visibleScopes(), &scopes); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QList<Symbol *> candidates = _context.resolve(memberName, scopes); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (Symbol *candidate, candidates) { | 
					
						
							|  |  |  |         FullySpecifiedType ty = candidate->type(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |         results.append(LookupItem(ty, candidate)); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return removeDuplicates(results); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | bool ResolveExpression::visit(PostIncrDecrAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-29 11:53:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | bool ResolveExpression::visit(ObjCMessageExpressionAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     QList<LookupItem> receiverResults = operator()(ast->receiver_expression); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!receiverResults.isEmpty()) { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |         LookupItem result = receiverResults.first(); | 
					
						
							|  |  |  |         FullySpecifiedType ty = result.type().simplified(); | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |         const Name *klassName = 0; | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (const ObjCClass *classTy = ty->asObjCClassType()) { | 
					
						
							|  |  |  |             // static access, e.g.:
 | 
					
						
							|  |  |  |             // [NSObject description];
 | 
					
						
							|  |  |  |             klassName = classTy->name(); | 
					
						
							|  |  |  |         } else if (const PointerType *ptrTy = ty->asPointerType()) { | 
					
						
							|  |  |  |             const FullySpecifiedType pointeeTy = ptrTy->elementType(); | 
					
						
							|  |  |  |             if (pointeeTy && pointeeTy->isNamedType()) { | 
					
						
							|  |  |  |                 // dynamic access, e.g.:
 | 
					
						
							|  |  |  |                 // NSObject *obj = ...; [obj release];
 | 
					
						
							|  |  |  |                 klassName = pointeeTy->asNamedType()->name(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (klassName&&ast->selector && ast->selector->selector_name) { | 
					
						
							|  |  |  |             ResolveObjCClass resolveObjCClass; | 
					
						
							|  |  |  |             QList<Symbol *> resolvedSymbols = resolveObjCClass(klassName, result, _context); | 
					
						
							|  |  |  |             foreach (Symbol *resolvedSymbol, resolvedSymbols) | 
					
						
							|  |  |  |                 if (ObjCClass *klass = resolvedSymbol->asObjCClass()) | 
					
						
							|  |  |  |                     _results.append(resolveMember(ast->selector->selector_name, klass)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-29 11:53:40 +01:00
										 |  |  | ////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2008-12-30 12:03:49 +01:00
										 |  |  | ResolveClass::ResolveClass() | 
					
						
							| 
									
										
										
										
											2008-12-29 12:26:02 +01:00
										 |  |  | { } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  | QList<Symbol *> ResolveClass::operator()(const Name *name, | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                                          const LookupItem &p, | 
					
						
							| 
									
										
										
										
											2008-12-31 10:57:27 +01:00
										 |  |  |                                          const LookupContext &context) | 
					
						
							| 
									
										
										
										
											2008-12-29 12:26:02 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     const QList<LookupItem> previousBlackList = _blackList; | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |     const QList<Symbol *> symbols = resolveClass(name, p, context); | 
					
						
							| 
									
										
										
										
											2008-12-29 12:26:02 +01:00
										 |  |  |     _blackList = previousBlackList; | 
					
						
							|  |  |  |     return symbols; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  | QList<Symbol *> ResolveClass::resolveClass(const Name *name, | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                                            const LookupItem &p, | 
					
						
							| 
									
										
										
										
											2008-12-31 10:57:27 +01:00
										 |  |  |                                            const LookupContext &context) | 
					
						
							| 
									
										
										
										
											2008-12-29 11:53:40 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QList<Symbol *> resolvedSymbols; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (_blackList.contains(p)) | 
					
						
							|  |  |  |         return resolvedSymbols; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _blackList.append(p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const QList<Symbol *> candidates = | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |             context.resolve(name, context.visibleScopes(p)); | 
					
						
							| 
									
										
										
										
											2008-12-29 11:53:40 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     foreach (Symbol *candidate, candidates) { | 
					
						
							|  |  |  |         if (Class *klass = candidate->asClass()) { | 
					
						
							|  |  |  |             if (resolvedSymbols.contains(klass)) | 
					
						
							|  |  |  |                 continue; // we already know about `klass'
 | 
					
						
							|  |  |  |             resolvedSymbols.append(klass); | 
					
						
							|  |  |  |         } else if (candidate->isTypedef()) { | 
					
						
							|  |  |  |             if (Declaration *decl = candidate->asDeclaration()) { | 
					
						
							| 
									
										
										
										
											2009-10-16 11:29:09 +02:00
										 |  |  |                 if (Class *asClass = decl->type()->asClassType()) { | 
					
						
							| 
									
										
										
										
											2008-12-29 11:53:40 +01:00
										 |  |  |                     // typedef struct { } Point;
 | 
					
						
							|  |  |  |                     // Point pt;
 | 
					
						
							|  |  |  |                     // pt.
 | 
					
						
							|  |  |  |                     resolvedSymbols.append(asClass); | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     // typedef Point Boh;
 | 
					
						
							|  |  |  |                     // Boh b;
 | 
					
						
							|  |  |  |                     // b.
 | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |                     FullySpecifiedType declType = decl->type().simplified(); | 
					
						
							|  |  |  |                     if (NamedType *namedTy = declType->asNamedType()) { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                         const LookupItem r(declType, decl); | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |                         resolvedSymbols += resolveClass(namedTy->name(), r, context); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2008-12-29 11:53:40 +01:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else if (Declaration *decl = candidate->asDeclaration()) { | 
					
						
							| 
									
										
										
										
											2009-02-09 17:44:06 +01:00
										 |  |  |             if (Function *funTy = decl->type()->asFunctionType()) { | 
					
						
							| 
									
										
										
										
											2008-12-29 11:53:40 +01:00
										 |  |  |                 // QString foo("ciao");
 | 
					
						
							|  |  |  |                 // foo.
 | 
					
						
							| 
									
										
										
										
											2009-07-09 16:20:20 +02:00
										 |  |  |                 if (funTy->scope() && (funTy->scope()->isBlockScope() || funTy->scope()->isNamespaceScope())) { | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |                     FullySpecifiedType retTy = funTy->returnType().simplified(); | 
					
						
							|  |  |  |                     if (NamedType *namedTy = retTy->asNamedType()) { | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                         const LookupItem r(retTy, decl); | 
					
						
							| 
									
										
										
										
											2009-10-05 11:38:54 +02:00
										 |  |  |                         resolvedSymbols += resolveClass(namedTy->name(), r, context); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2008-12-29 11:53:40 +01:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return resolvedSymbols; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | ResolveObjCClass::ResolveObjCClass() | 
					
						
							|  |  |  | {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  | QList<Symbol *> ResolveObjCClass::operator ()(const Name *name, | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |                                               const LookupItem &p, | 
					
						
							| 
									
										
										
										
											2009-11-11 09:21:06 +01:00
										 |  |  |                                               const LookupContext &context) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<Symbol *> resolvedSymbols; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const QList<Symbol *> candidates = | 
					
						
							|  |  |  |             context.resolve(name, context.visibleScopes(p)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     foreach (Symbol *candidate, candidates) { | 
					
						
							|  |  |  |         if (ObjCClass *klass = candidate->asObjCClass()) { | 
					
						
							|  |  |  |             if (resolvedSymbols.contains(klass)) | 
					
						
							|  |  |  |                 continue; // we already know about `klass'
 | 
					
						
							|  |  |  |             resolvedSymbols.append(klass); | 
					
						
							|  |  |  |         } else if (candidate->isTypedef()) { | 
					
						
							|  |  |  |             if (Declaration *decl = candidate->asDeclaration()) { | 
					
						
							|  |  |  |                 if (decl->type()->isObjCClassType()) { | 
					
						
							|  |  |  |                     ObjCClass *klass = decl->type()->asObjCClassType(); | 
					
						
							|  |  |  |                     if (resolvedSymbols.contains(klass)) | 
					
						
							|  |  |  |                         continue; | 
					
						
							|  |  |  |                     resolvedSymbols.append(klass); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return resolvedSymbols; | 
					
						
							|  |  |  | } |