| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | /**************************************************************************
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Commercial Usage | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** 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. | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** GNU Lesser General Public License Usage | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** 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.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** If you are unsure which license is appropriate for your use, please | 
					
						
							|  |  |  | ** contact the sales department at http://qt.nokia.com/contact.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | **************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "FindUsages.h"
 | 
					
						
							|  |  |  | #include "TypeOfExpression.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <Control.h>
 | 
					
						
							|  |  |  | #include <Literals.h>
 | 
					
						
							|  |  |  | #include <Names.h>
 | 
					
						
							|  |  |  | #include <Symbols.h>
 | 
					
						
							|  |  |  | #include <AST.h>
 | 
					
						
							| 
									
										
										
										
											2009-12-03 11:59:37 +01:00
										 |  |  | #include <TranslationUnit.h>
 | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <QtCore/QDir>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using namespace CPlusPlus; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-04 13:04:20 +01:00
										 |  |  | FindUsages::FindUsages(Document::Ptr doc, const Snapshot &snapshot) | 
					
						
							| 
									
										
										
										
											2009-11-17 13:28:20 +01:00
										 |  |  |     : ASTVisitor(doc->translationUnit()), | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |       _doc(doc), | 
					
						
							|  |  |  |       _snapshot(snapshot), | 
					
						
							|  |  |  |       _source(_doc->source()), | 
					
						
							| 
									
										
										
										
											2009-11-17 13:28:20 +01:00
										 |  |  |       _sem(doc->translationUnit()), | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |       _inSimpleDeclaration(0) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _snapshot.insert(_doc); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FindUsages::setGlobalNamespaceBinding(NamespaceBindingPtr globalNamespaceBinding) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _globalNamespaceBinding = globalNamespaceBinding; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 17:31:41 +01:00
										 |  |  | QList<Usage> FindUsages::usages() const | 
					
						
							|  |  |  | { return _usages; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QList<int> FindUsages::references() const | 
					
						
							|  |  |  | { return _references; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-03 11:59:37 +01:00
										 |  |  | void FindUsages::operator()(Symbol *symbol) | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-04 12:02:19 +01:00
										 |  |  |     _processed.clear(); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |     _references.clear(); | 
					
						
							| 
									
										
										
										
											2009-12-01 17:31:41 +01:00
										 |  |  |     _usages.clear(); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |     _declSymbol = symbol; | 
					
						
							| 
									
										
										
										
											2010-02-11 10:18:05 +01:00
										 |  |  |     _inSimpleDeclaration = 0; | 
					
						
							| 
									
										
										
										
											2009-12-03 11:59:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     _id = 0; | 
					
						
							| 
									
										
										
										
											2010-01-08 14:58:21 +01:00
										 |  |  |     if (_declSymbol && 0 != (_id = _declSymbol->identifier())) | 
					
						
							| 
									
										
										
										
											2009-12-03 11:59:37 +01:00
										 |  |  |         _id = _doc->control()->findOrInsertIdentifier(_id->chars(), _id->size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (_id) { | 
					
						
							| 
									
										
										
										
											2009-10-27 18:04:19 +01:00
										 |  |  |         _exprDoc = Document::create("<references>"); | 
					
						
							| 
									
										
										
										
											2009-12-03 11:59:37 +01:00
										 |  |  |         accept(_doc->translationUnit()->ast()); | 
					
						
							| 
									
										
										
										
											2009-10-27 18:04:19 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString FindUsages::matchingLine(const Token &tk) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *beg = _source.constData(); | 
					
						
							|  |  |  |     const char *cp = beg + tk.offset; | 
					
						
							|  |  |  |     for (; cp != beg - 1; --cp) { | 
					
						
							|  |  |  |         if (*cp == '\n') | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ++cp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const char *lineEnd = cp + 1; | 
					
						
							|  |  |  |     for (; *lineEnd; ++lineEnd) { | 
					
						
							|  |  |  |         if (*lineEnd == '\n') | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const QString matchingLine = QString::fromUtf8(cp, lineEnd - cp); | 
					
						
							|  |  |  |     return matchingLine; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FindUsages::reportResult(unsigned tokenIndex, const QList<Symbol *> &candidates) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-04 12:02:19 +01:00
										 |  |  |     if (_processed.contains(tokenIndex)) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |     const bool isStrongResult = checkCandidates(candidates); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (isStrongResult) | 
					
						
							|  |  |  |         reportResult(tokenIndex); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FindUsages::reportResult(unsigned tokenIndex) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-04 12:02:19 +01:00
										 |  |  |     if (_processed.contains(tokenIndex)) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _processed.insert(tokenIndex); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |     const Token &tk = tokenAt(tokenIndex); | 
					
						
							|  |  |  |     const QString lineText = matchingLine(tk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned line, col; | 
					
						
							|  |  |  |     getTokenStartPosition(tokenIndex, &line, &col); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (col) | 
					
						
							|  |  |  |         --col;  // adjust the column position.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const int len = tk.f.length; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-04 13:04:20 +01:00
										 |  |  |     const Usage u(_doc->fileName(), lineText, line, col, len); | 
					
						
							| 
									
										
										
										
											2009-12-01 17:31:41 +01:00
										 |  |  |     _usages.append(u); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |     _references.append(tokenIndex); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::checkCandidates(const QList<Symbol *> &candidates) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(candidates, _globalNamespaceBinding.data())) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2009-10-27 12:31:49 +01:00
										 |  |  |         Symbol *c = candidates.first(); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |         qDebug() << "*** canonical symbol:" << canonicalSymbol->fileName() | 
					
						
							|  |  |  |                 << canonicalSymbol->line() << canonicalSymbol->column() | 
					
						
							| 
									
										
										
										
											2009-10-27 12:31:49 +01:00
										 |  |  |                 << "candidates:" << candidates.size() | 
					
						
							|  |  |  |                 << c->fileName() << c->line() << c->column(); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return checkSymbol(canonicalSymbol); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::checkScope(Symbol *symbol, Symbol *otherSymbol) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! (symbol && otherSymbol)) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     else if (symbol->scope() == otherSymbol->scope()) | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     else if (symbol->name() && otherSymbol->name()) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (! symbol->name()->isEqualTo(otherSymbol->name())) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (symbol->name() != otherSymbol->name()) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return checkScope(symbol->enclosingSymbol(), otherSymbol->enclosingSymbol()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::checkSymbol(Symbol *symbol) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! symbol) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (symbol == _declSymbol) { | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (symbol->line() == _declSymbol->line() && symbol->column() == _declSymbol->column()) { | 
					
						
							|  |  |  |         if (! qstrcmp(symbol->fileName(), _declSymbol->fileName())) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (symbol->isForwardClassDeclaration() && (_declSymbol->isClass() || | 
					
						
							|  |  |  |                                                        _declSymbol->isForwardClassDeclaration())) { | 
					
						
							|  |  |  |         return checkScope(symbol, _declSymbol); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (_declSymbol->isForwardClassDeclaration() && (symbol->isClass() || | 
					
						
							|  |  |  |                                                             symbol->isForwardClassDeclaration())) { | 
					
						
							|  |  |  |         return checkScope(symbol, _declSymbol); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LookupContext FindUsages::currentContext(AST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     unsigned line, column; | 
					
						
							|  |  |  |     getTokenStartPosition(ast->firstToken(), &line, &column); | 
					
						
							|  |  |  |     Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (lastVisibleSymbol && lastVisibleSymbol == _previousContext.symbol()) | 
					
						
							|  |  |  |         return _previousContext; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     LookupContext ctx(lastVisibleSymbol, _exprDoc, _doc, _snapshot); | 
					
						
							|  |  |  |     _previousContext = ctx; | 
					
						
							|  |  |  |     return ctx; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FindUsages::ensureNameIsValid(NameAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (ast && ! ast->name) | 
					
						
							|  |  |  |         ast->name = _sem.check(ast, /*scope = */ 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(MemInitializerAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (ast->name && ast->name->asSimpleName() != 0) { | 
					
						
							|  |  |  |         ensureNameIsValid(ast->name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         SimpleNameAST *simple = ast->name->asSimpleName(); | 
					
						
							|  |  |  |         if (identifier(simple->identifier_token) == _id) { | 
					
						
							|  |  |  |             LookupContext context = currentContext(ast); | 
					
						
							|  |  |  |             const QList<Symbol *> candidates = context.resolve(simple->name); | 
					
						
							|  |  |  |             reportResult(simple->identifier_token, candidates); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-11-13 12:36:51 +01:00
										 |  |  |     accept(ast->expression_list); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(PostfixExpressionAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _postfixExpressionStack.append(ast); | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FindUsages::endVisit(PostfixExpressionAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _postfixExpressionStack.removeLast(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(MemberAccessAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (ast->member_name) { | 
					
						
							|  |  |  |         if (SimpleNameAST *simple = ast->member_name->asSimpleName()) { | 
					
						
							|  |  |  |             if (identifier(simple->identifier_token) == _id) { | 
					
						
							|  |  |  |                 Q_ASSERT(! _postfixExpressionStack.isEmpty()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 checkExpression(_postfixExpressionStack.last()->firstToken(), | 
					
						
							|  |  |  |                                 simple->identifier_token); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void FindUsages::checkExpression(unsigned startToken, unsigned endToken) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const unsigned begin = tokenAt(startToken).begin(); | 
					
						
							|  |  |  |     const unsigned end = tokenAt(endToken).end(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const QString expression = _source.mid(begin, end - begin); | 
					
						
							|  |  |  |     // qDebug() << "*** check expression:" << expression;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TypeOfExpression typeofExpression; | 
					
						
							|  |  |  |     typeofExpression.setSnapshot(_snapshot); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned line, column; | 
					
						
							|  |  |  |     getTokenStartPosition(startToken, &line, &column); | 
					
						
							|  |  |  |     Symbol *lastVisibleSymbol = _doc->findSymbolAt(line, column); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     const QList<LookupItem> results = typeofExpression(expression, _doc, lastVisibleSymbol, | 
					
						
							|  |  |  |                                                    TypeOfExpression::Preprocess); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     QList<Symbol *> candidates; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-17 14:21:46 +01:00
										 |  |  |     foreach (const LookupItem &r, results) { | 
					
						
							|  |  |  |         Symbol *lastVisibleSymbol = r.lastVisibleSymbol(); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |         candidates.append(lastVisibleSymbol); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reportResult(endToken, candidates); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(QualifiedNameAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 15:12:04 +01:00
										 |  |  |         NestedNameSpecifierAST *nested_name_specifier = it->value; | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (NameAST *class_or_namespace_name = nested_name_specifier->class_or_namespace_name) { | 
					
						
							|  |  |  |             SimpleNameAST *simple_name = class_or_namespace_name->asSimpleName(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             TemplateIdAST *template_id = 0; | 
					
						
							|  |  |  |             if (! simple_name) { | 
					
						
							|  |  |  |                 template_id = class_or_namespace_name->asTemplateId(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (template_id) { | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |                     for (TemplateArgumentListAST *arg_it = template_id->template_argument_list; arg_it; arg_it = arg_it->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 15:12:04 +01:00
										 |  |  |                         accept(arg_it->value); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (simple_name || template_id) { | 
					
						
							|  |  |  |                 const unsigned identifier_token = simple_name | 
					
						
							|  |  |  |                            ? simple_name->identifier_token | 
					
						
							|  |  |  |                            : template_id->identifier_token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (identifier(identifier_token) == _id) | 
					
						
							|  |  |  |                     checkExpression(ast->firstToken(), identifier_token); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (NameAST *unqualified_name = ast->unqualified_name) { | 
					
						
							|  |  |  |         unsigned identifier_token = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (SimpleNameAST *simple_name = unqualified_name->asSimpleName()) | 
					
						
							|  |  |  |             identifier_token = simple_name->identifier_token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         else if (DestructorNameAST *dtor_name = unqualified_name->asDestructorName()) | 
					
						
							|  |  |  |             identifier_token = dtor_name->identifier_token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         TemplateIdAST *template_id = 0; | 
					
						
							|  |  |  |         if (! identifier_token) { | 
					
						
							|  |  |  |             template_id = unqualified_name->asTemplateId(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (template_id) { | 
					
						
							|  |  |  |                 identifier_token = template_id->identifier_token; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |                 for (TemplateArgumentListAST *template_arguments = template_id->template_argument_list; | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |                      template_arguments; template_arguments = template_arguments->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 12:37:46 +01:00
										 |  |  |                     accept(template_arguments->value); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (identifier_token && identifier(identifier_token) == _id) | 
					
						
							|  |  |  |             checkExpression(ast->firstToken(), identifier_token); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(EnumeratorAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-01 11:33:13 +01:00
										 |  |  |     const Identifier *id = identifier(ast->identifier_token); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |     if (id == _id) { | 
					
						
							|  |  |  |         LookupContext context = currentContext(ast); | 
					
						
							|  |  |  |         const QList<Symbol *> candidates = context.resolve(control()->nameId(id)); | 
					
						
							|  |  |  |         reportResult(ast->identifier_token, candidates); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     accept(ast->expression); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(SimpleNameAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-01 11:33:13 +01:00
										 |  |  |     const Identifier *id = identifier(ast->identifier_token); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |     if (id == _id) { | 
					
						
							|  |  |  |         LookupContext context = currentContext(ast); | 
					
						
							|  |  |  |         const QList<Symbol *> candidates = context.resolve(ast->name); | 
					
						
							|  |  |  |         reportResult(ast->identifier_token, candidates); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(DestructorNameAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-01 11:33:13 +01:00
										 |  |  |     const Identifier *id = identifier(ast->identifier_token); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |     if (id == _id) { | 
					
						
							|  |  |  |         LookupContext context = currentContext(ast); | 
					
						
							|  |  |  |         const QList<Symbol *> candidates = context.resolve(ast->name); | 
					
						
							|  |  |  |         reportResult(ast->identifier_token, candidates); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(TemplateIdAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (_id == identifier(ast->identifier_token)) { | 
					
						
							|  |  |  |         LookupContext context = currentContext(ast); | 
					
						
							|  |  |  |         const QList<Symbol *> candidates = context.resolve(ast->name); | 
					
						
							|  |  |  |         reportResult(ast->identifier_token, candidates); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     for (TemplateArgumentListAST *template_arguments = ast->template_argument_list; | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |          template_arguments; template_arguments = template_arguments->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 12:37:46 +01:00
										 |  |  |         accept(template_arguments->value); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(ParameterDeclarationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     for (SpecifierListAST *it = ast->type_specifier_list; it; it = it->next) | 
					
						
							| 
									
										
										
										
											2009-11-10 16:00:22 +01:00
										 |  |  |         accept(it->value); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (DeclaratorAST *declarator = ast->declarator) { | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |         for (SpecifierListAST *it = declarator->attribute_list; it; it = it->next) | 
					
						
							| 
									
										
										
										
											2009-11-10 16:00:22 +01:00
										 |  |  |             accept(it->value); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |         for (PtrOperatorListAST *it = declarator->ptr_operator_list; it; it = it->next) | 
					
						
							| 
									
										
										
										
											2009-11-10 15:30:16 +01:00
										 |  |  |             accept(it->value); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (! _inSimpleDeclaration) // visit the core declarator only if we are not in simple-declaration.
 | 
					
						
							|  |  |  |             accept(declarator->core_declarator); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |         for (PostfixDeclaratorListAST *it = declarator->postfix_declarator_list; it; it = it->next) | 
					
						
							| 
									
										
										
										
											2009-11-10 14:33:51 +01:00
										 |  |  |             accept(it->value); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |         for (SpecifierListAST *it = declarator->post_attribute_list; it; it = it->next) | 
					
						
							| 
									
										
										
										
											2009-11-10 16:00:22 +01:00
										 |  |  |             accept(it->value); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         accept(declarator->initializer); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     accept(ast->expression); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(ExpressionOrDeclarationStatementAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     accept(ast->declaration); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(FunctionDeclaratorAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     accept(ast->parameters); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) | 
					
						
							| 
									
										
										
										
											2009-11-10 16:00:22 +01:00
										 |  |  |         accept(it->value); | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     accept(ast->exception_specification); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-11 10:18:05 +01:00
										 |  |  | bool FindUsages::visit(SimpleDeclarationAST *ast) | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-11 10:18:05 +01:00
										 |  |  |     for  (SpecifierListAST *it = ast->decl_specifier_list; it; it = it->next) | 
					
						
							|  |  |  |         accept(it->value); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  |     ++_inSimpleDeclaration; | 
					
						
							| 
									
										
										
										
											2010-02-11 10:18:05 +01:00
										 |  |  |     for (DeclaratorListAST *it = ast->declarator_list; it; it = it->next) | 
					
						
							|  |  |  |         accept(it->value); | 
					
						
							|  |  |  |     --_inSimpleDeclaration; | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2009-10-27 12:01:45 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-08 09:34:51 +01:00
										 |  |  | bool FindUsages::visit(ObjCSelectorWithoutArgumentsAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const Identifier *id = identifier(ast->name_token); | 
					
						
							|  |  |  |     if (id == _id) { | 
					
						
							|  |  |  |         LookupContext context = currentContext(ast); | 
					
						
							|  |  |  |         const QList<Symbol *> candidates = context.resolve(ast->selector_name); | 
					
						
							|  |  |  |         reportResult(ast->name_token, candidates); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool FindUsages::visit(ObjCSelectorWithArgumentsAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (ObjCSelectorArgumentListAST *iter = ast->selector_argument_list; iter; | 
					
						
							|  |  |  |          iter = iter->next) { | 
					
						
							|  |  |  |         const Identifier *id = identifier(iter->value->name_token); | 
					
						
							|  |  |  |         if (id == _id) { | 
					
						
							|  |  |  |             LookupContext context = currentContext(iter->value); | 
					
						
							|  |  |  |             const QList<Symbol *> candidates = context.resolve(ast->selector_name); | 
					
						
							|  |  |  |             reportResult(iter->value->name_token, candidates); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } |