CIndexHigh.cpp revision c6f5c6a58d34833d1fe458a518d5f59462926c7b
1aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis//===- CIndexHigh.cpp - Higher level API functions ------------------------===// 2aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis// 3aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 4aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis// 5aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 6aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 7aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis// 8aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 9aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 10e2079cf54ded1eda9e35d215aef6628373368276Argyrios Kyrtzidis#include "CursorVisitor.h" 11aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#include "CXCursor.h" 12aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#include "CXSourceLocation.h" 13aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#include "CXTranslationUnit.h" 14c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis#include "CLog.h" 15aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis#include "clang/AST/DeclObjC.h" 16f59edb96b2d0bfe612b732f19519ab84bb995bd4Chandler Carruth#include "clang/Frontend/ASTUnit.h" 17aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 18aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisusing namespace clang; 19e2079cf54ded1eda9e35d215aef6628373368276Argyrios Kyrtzidisusing namespace cxcursor; 20c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidisusing namespace cxindex; 21aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 22aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisstatic void getTopOverriddenMethods(CXTranslationUnit TU, 23aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Decl *D, 24aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis SmallVectorImpl<Decl *> &Methods) { 2516ed0e6fda74800595cb98d11969fc4afcc00bacArgyrios Kyrtzidis if (!D) 2616ed0e6fda74800595cb98d11969fc4afcc00bacArgyrios Kyrtzidis return; 27aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (!isa<ObjCMethodDecl>(D) && !isa<CXXMethodDecl>(D)) 28aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return; 29aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 30aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis SmallVector<CXCursor, 8> Overridden; 31aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis cxcursor::getOverriddenCursors(cxcursor::MakeCXCursor(D, TU), Overridden); 32aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 33aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (Overridden.empty()) { 34aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Methods.push_back(D->getCanonicalDecl()); 35aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return; 36aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 37aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 38aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis for (SmallVector<CXCursor, 8>::iterator 39aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis I = Overridden.begin(), E = Overridden.end(); I != E; ++I) 40aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis getTopOverriddenMethods(TU, cxcursor::getCursorDecl(*I), Methods); 41aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 42aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 43aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisnamespace { 44aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 45aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisstruct FindFileIdRefVisitData { 46aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXTranslationUnit TU; 47aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis FileID FID; 48aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Decl *Dcl; 49aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis int SelectorIdIdx; 50aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXCursorAndRangeVisitor visitor; 51aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 52aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis typedef SmallVector<Decl *, 8> TopMethodsTy; 53aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis TopMethodsTy TopMethods; 54aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 55aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis FindFileIdRefVisitData(CXTranslationUnit TU, FileID FID, 56aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Decl *D, int selectorIdIdx, 57aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXCursorAndRangeVisitor visitor) 58aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis : TU(TU), FID(FID), SelectorIdIdx(selectorIdIdx), visitor(visitor) { 59aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Dcl = getCanonical(D); 60aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis getTopOverriddenMethods(TU, Dcl, TopMethods); 61aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 62aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 63aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis ASTContext &getASTContext() const { 64aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return static_cast<ASTUnit *>(TU->TUData)->getASTContext(); 65aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 66aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 67aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis /// \brief We are looking to find all semantically relevant identifiers, 68aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis /// so the definition of "canonical" here is different than in the AST, e.g. 69aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis /// 70aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis /// \code 71aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis /// class C { 72aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis /// C() {} 73aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis /// }; 74aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis /// \endcode 75aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis /// 76aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis /// we consider the canonical decl of the constructor decl to be the class 77aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis /// itself, so both 'C' can be highlighted. 78aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Decl *getCanonical(Decl *D) const { 79e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis if (!D) 80e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis return 0; 81e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis 82aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis D = D->getCanonicalDecl(); 83aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 84e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D)) { 85e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis if (ImplD->getClassInterface()) 86e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis return getCanonical(ImplD->getClassInterface()); 87e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis 88e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis } else if (CXXConstructorDecl *CXXCtorD = dyn_cast<CXXConstructorDecl>(D)) { 89aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return getCanonical(CXXCtorD->getParent()); 90e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis } 91aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 92aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return D; 93aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 94aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 95aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis bool isHit(Decl *D) const { 96e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis if (!D) 97e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis return false; 98e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis 99aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis D = getCanonical(D); 100aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (D == Dcl) 101aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return true; 102aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 103aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (isa<ObjCMethodDecl>(D) || isa<CXXMethodDecl>(D)) 104aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return isOverriddingMethod(D); 105aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 106aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return false; 107aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 108aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 109aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisprivate: 110aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis bool isOverriddingMethod(Decl *D) const { 111aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (std::find(TopMethods.begin(), TopMethods.end(), D) != 112aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis TopMethods.end()) 113aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return true; 114aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 115aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis TopMethodsTy methods; 116aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis getTopOverriddenMethods(TU, D, methods); 117aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis for (TopMethodsTy::iterator 118aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis I = methods.begin(), E = methods.end(); I != E; ++I) { 119aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (std::find(TopMethods.begin(), TopMethods.end(), *I) != 120aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis TopMethods.end()) 121aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return true; 122aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 123aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 124aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return false; 125aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 126aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis}; 127aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 128aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} // end anonymous namespace. 129aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 130aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis/// \brief For a macro \arg Loc, returns the file spelling location and sets 131aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis/// to \arg isMacroArg whether the spelling resides inside a macro definition or 132aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis/// a macro argument. 133aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisstatic SourceLocation getFileSpellingLoc(SourceManager &SM, 134aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis SourceLocation Loc, 135aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis bool &isMacroArg) { 136aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis assert(Loc.isMacroID()); 137aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis SourceLocation SpellLoc = SM.getImmediateSpellingLoc(Loc); 138aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (SpellLoc.isMacroID()) 139aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return getFileSpellingLoc(SM, SpellLoc, isMacroArg); 140aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 141aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis isMacroArg = SM.isMacroArgExpansion(Loc); 142aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return SpellLoc; 143aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 144aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 145aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisstatic enum CXChildVisitResult findFileIdRefVisit(CXCursor cursor, 146aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXCursor parent, 147aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXClientData client_data) { 148aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXCursor declCursor = clang_getCursorReferenced(cursor); 149aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (!clang_isDeclaration(declCursor.kind)) 150aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return CXChildVisit_Recurse; 151aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 152aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Decl *D = cxcursor::getCursorDecl(declCursor); 15316ed0e6fda74800595cb98d11969fc4afcc00bacArgyrios Kyrtzidis if (!D) 15416ed0e6fda74800595cb98d11969fc4afcc00bacArgyrios Kyrtzidis return CXChildVisit_Continue; 15516ed0e6fda74800595cb98d11969fc4afcc00bacArgyrios Kyrtzidis 156aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis FindFileIdRefVisitData *data = (FindFileIdRefVisitData *)client_data; 157aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (data->isHit(D)) { 158aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis cursor = cxcursor::getSelectorIdentifierCursor(data->SelectorIdIdx, cursor); 159aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 160aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // We are looking for identifiers to highlight so for objc methods (and 161aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // not a parameter) we can only highlight the selector identifiers. 162aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if ((cursor.kind == CXCursor_ObjCClassMethodDecl || 163aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis cursor.kind == CXCursor_ObjCInstanceMethodDecl) && 164aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis cxcursor::getSelectorIdentifierIndex(cursor) == -1) 165aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return CXChildVisit_Recurse; 166aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 167aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (clang_isExpression(cursor.kind)) { 168aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (cursor.kind == CXCursor_DeclRefExpr || 169aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis cursor.kind == CXCursor_MemberRefExpr) { 170aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // continue.. 171aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 172aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } else if (cursor.kind == CXCursor_ObjCMessageExpr && 173aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis cxcursor::getSelectorIdentifierIndex(cursor) != -1) { 174aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // continue.. 175aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 176aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } else 177aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return CXChildVisit_Recurse; 178aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 179aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 180aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis SourceLocation 181aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Loc = cxloc::translateSourceLocation(clang_getCursorLocation(cursor)); 182aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis SourceLocation SelIdLoc = cxcursor::getSelectorIdentifierLoc(cursor); 183aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (SelIdLoc.isValid()) 184aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Loc = SelIdLoc; 185aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 186b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis ASTContext &Ctx = data->getASTContext(); 187b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis SourceManager &SM = Ctx.getSourceManager(); 188aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis bool isInMacroDef = false; 189aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (Loc.isMacroID()) { 190aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis bool isMacroArg; 191aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Loc = getFileSpellingLoc(SM, Loc, isMacroArg); 192aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis isInMacroDef = !isMacroArg; 193aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 194aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 195aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // We are looking for identifiers in a specific file. 196aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); 197aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (LocInfo.first != data->FID) 198aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return CXChildVisit_Recurse; 199aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 200aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (isInMacroDef) { 201aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // FIXME: For a macro definition make sure that all expansions 202aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // of it expand to the same reference before allowing to point to it. 203b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis return CXChildVisit_Recurse; 204aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 205aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 206aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis data->visitor.visit(data->visitor.context, cursor, 207b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis cxloc::translateSourceRange(Ctx, Loc)); 208aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 209aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return CXChildVisit_Recurse; 210aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 211aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 212aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisstatic void findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor, 213aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis const FileEntry *File, 214aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXCursorAndRangeVisitor Visitor) { 215aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis assert(clang_isDeclaration(declCursor.kind)); 216aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis ASTUnit *Unit = static_cast<ASTUnit*>(TU->TUData); 217aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis SourceManager &SM = Unit->getSourceManager(); 218aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 219aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis FileID FID = SM.translateFile(File); 220aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Decl *Dcl = cxcursor::getCursorDecl(declCursor); 221e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis if (!Dcl) 222e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis return; 223e368a641a03617983dabb1e092d880e1089f576aArgyrios Kyrtzidis 224aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis FindFileIdRefVisitData data(TU, FID, Dcl, 225aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis cxcursor::getSelectorIdentifierIndex(declCursor), 226aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis Visitor); 227aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 228aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (DeclContext *DC = Dcl->getParentFunctionOrMethod()) { 229aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis clang_visitChildren(cxcursor::MakeCXCursor(cast<Decl>(DC), TU), 230aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis findFileIdRefVisit, &data); 231aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return; 232aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 233aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 234e2079cf54ded1eda9e35d215aef6628373368276Argyrios Kyrtzidis SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID)); 235e2079cf54ded1eda9e35d215aef6628373368276Argyrios Kyrtzidis CursorVisitor FindIdRefsVisitor(TU, 236e2079cf54ded1eda9e35d215aef6628373368276Argyrios Kyrtzidis findFileIdRefVisit, &data, 237e2079cf54ded1eda9e35d215aef6628373368276Argyrios Kyrtzidis /*VisitPreprocessorLast=*/true, 238e2079cf54ded1eda9e35d215aef6628373368276Argyrios Kyrtzidis /*VisitIncludedEntities=*/false, 239b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis Range, 240b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis /*VisitDeclsOnly=*/true); 241e2079cf54ded1eda9e35d215aef6628373368276Argyrios Kyrtzidis FindIdRefsVisitor.visitFileRegion(); 242aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 243aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 244b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidisnamespace { 245b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 246b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidisstruct FindFileMacroRefVisitData { 247b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis ASTUnit &Unit; 248b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis const FileEntry *File; 249b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis const IdentifierInfo *Macro; 250b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis CXCursorAndRangeVisitor visitor; 251b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 252b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis FindFileMacroRefVisitData(ASTUnit &Unit, const FileEntry *File, 253b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis const IdentifierInfo *Macro, 254b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis CXCursorAndRangeVisitor visitor) 255b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis : Unit(Unit), File(File), Macro(Macro), visitor(visitor) { } 256b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 257b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis ASTContext &getASTContext() const { 258b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis return Unit.getASTContext(); 259b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis } 260b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis}; 261b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 262b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis} // anonymous namespace 263b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 264b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidisstatic enum CXChildVisitResult findFileMacroRefVisit(CXCursor cursor, 265b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis CXCursor parent, 266b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis CXClientData client_data) { 267b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis const IdentifierInfo *Macro = 0; 268b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis if (cursor.kind == CXCursor_MacroDefinition) 269b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis Macro = getCursorMacroDefinition(cursor)->getName(); 270b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis else if (cursor.kind == CXCursor_MacroExpansion) 271664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis Macro = getCursorMacroExpansion(cursor).getName(); 272b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis if (!Macro) 273b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis return CXChildVisit_Continue; 274b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 275b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis FindFileMacroRefVisitData *data = (FindFileMacroRefVisitData *)client_data; 276b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis if (data->Macro != Macro) 277b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis return CXChildVisit_Continue; 278b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 279b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis SourceLocation 280b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis Loc = cxloc::translateSourceLocation(clang_getCursorLocation(cursor)); 281b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 282b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis ASTContext &Ctx = data->getASTContext(); 283b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis SourceManager &SM = Ctx.getSourceManager(); 284b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis bool isInMacroDef = false; 285b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis if (Loc.isMacroID()) { 286b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis bool isMacroArg; 287b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis Loc = getFileSpellingLoc(SM, Loc, isMacroArg); 288b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis isInMacroDef = !isMacroArg; 289b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis } 290b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 291b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis // We are looking for identifiers in a specific file. 292b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); 293b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis if (SM.getFileEntryForID(LocInfo.first) != data->File) 294b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis return CXChildVisit_Continue; 295b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 296b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis if (isInMacroDef) { 297b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis // FIXME: For a macro definition make sure that all expansions 298b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis // of it expand to the same reference before allowing to point to it. 299b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis return CXChildVisit_Continue; 300b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis } 301b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 302b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis data->visitor.visit(data->visitor.context, cursor, 303b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis cxloc::translateSourceRange(Ctx, Loc)); 304b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis return CXChildVisit_Continue; 305b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis} 306b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 307b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidisstatic void findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor, 308b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis const FileEntry *File, 309b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis CXCursorAndRangeVisitor Visitor) { 310b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis if (Cursor.kind != CXCursor_MacroDefinition && 311b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis Cursor.kind != CXCursor_MacroExpansion) 312b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis return; 313b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 314b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis ASTUnit *Unit = static_cast<ASTUnit*>(TU->TUData); 315b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis SourceManager &SM = Unit->getSourceManager(); 316b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 317b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis FileID FID = SM.translateFile(File); 318b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis const IdentifierInfo *Macro = 0; 319b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis if (Cursor.kind == CXCursor_MacroDefinition) 320b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis Macro = getCursorMacroDefinition(Cursor)->getName(); 321b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis else 322664b06f9bd2ea83443ddc8553feba8ba48880752Argyrios Kyrtzidis Macro = getCursorMacroExpansion(Cursor).getName(); 323b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis if (!Macro) 324b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis return; 325b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 326b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis FindFileMacroRefVisitData data(*Unit, File, Macro, Visitor); 327b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 328b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID)); 329b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis CursorVisitor FindMacroRefsVisitor(TU, 330b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis findFileMacroRefVisit, &data, 331b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis /*VisitPreprocessorLast=*/false, 332b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis /*VisitIncludedEntities=*/false, 333b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis Range); 334b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis FindMacroRefsVisitor.visitPreprocessedEntitiesInRegion(); 335b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis} 336b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 337aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 338aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 339aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis// libclang public APIs. 340aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 341aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 342aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisextern "C" { 343aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 344aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisvoid clang_findReferencesInFile(CXCursor cursor, CXFile file, 345aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXCursorAndRangeVisitor visitor) { 346c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis LogRef Log = Logger::make(__func__); 347aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 348aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (clang_Cursor_isNull(cursor)) { 349c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis if (Log) 350c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis *Log << "Null cursor"; 351aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return; 352aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 3534451746d8f658b51eaf15dd24664a488457063a9Argyrios Kyrtzidis if (cursor.kind == CXCursor_NoDeclFound) { 354c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis if (Log) 355c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis *Log << "Got CXCursor_NoDeclFound"; 3564451746d8f658b51eaf15dd24664a488457063a9Argyrios Kyrtzidis return; 3574451746d8f658b51eaf15dd24664a488457063a9Argyrios Kyrtzidis } 358aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (!file) { 359c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis if (Log) 360c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis *Log << "Null file"; 361aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return; 362aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 363aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (!visitor.visit) { 364c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis if (Log) 365c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis *Log << "Null visitor"; 366aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return; 367aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 368aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 3695c2a1f741e133fcad4782b855a18d3b220243b11Argyrios Kyrtzidis ASTUnit *CXXUnit = cxcursor::getCursorASTUnit(cursor); 3705c2a1f741e133fcad4782b855a18d3b220243b11Argyrios Kyrtzidis if (!CXXUnit) 3715c2a1f741e133fcad4782b855a18d3b220243b11Argyrios Kyrtzidis return; 3725c2a1f741e133fcad4782b855a18d3b220243b11Argyrios Kyrtzidis 3735c2a1f741e133fcad4782b855a18d3b220243b11Argyrios Kyrtzidis ASTUnit::ConcurrencyCheck Check(*CXXUnit); 3745c2a1f741e133fcad4782b855a18d3b220243b11Argyrios Kyrtzidis 375b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis if (cursor.kind == CXCursor_MacroDefinition || 376b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis cursor.kind == CXCursor_MacroExpansion) { 377b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis findMacroRefsInFile(cxcursor::getCursorTU(cursor), 378b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis cursor, 379b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis static_cast<const FileEntry *>(file), 380b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis visitor); 381b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis return; 382b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis } 383b49e728a4d1a84b72f3aebf60ff494684f9cb004Argyrios Kyrtzidis 384aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // We are interested in semantics of identifiers so for C++ constructor exprs 385aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // prefer type references, e.g.: 386aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // 387aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // return MyStruct(); 388aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // 389aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // for 'MyStruct' we'll have a cursor pointing at the constructor decl but 390aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis // we are actually interested in the type declaration. 391aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis cursor = cxcursor::getTypeRefCursor(cursor); 392aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 393aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXCursor refCursor = clang_getCursorReferenced(cursor); 394aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 395aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis if (!clang_isDeclaration(refCursor.kind)) { 396c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis if (Log) 397c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis *Log << "cursor is not referencing a declaration"; 398aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return; 399aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis } 400aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 401aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis findIdRefsInFile(cxcursor::getCursorTU(cursor), 402aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis refCursor, 403aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis static_cast<const FileEntry *>(file), 404aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis visitor); 405aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 406aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 407aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisstatic enum CXVisitorResult _visitCursorAndRange(void *context, 408aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXCursor cursor, 409aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXSourceRange range) { 410aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXCursorAndRangeVisitorBlock block = (CXCursorAndRangeVisitorBlock)context; 411aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return INVOKE_BLOCK2(block, cursor, range); 412aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 413aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 414aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidisvoid clang_findReferencesInFileWithBlock(CXCursor cursor, 415aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXFile file, 416aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXCursorAndRangeVisitorBlock block) { 417aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis CXCursorAndRangeVisitor visitor = { block, 418aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis block ? _visitCursorAndRange : 0 }; 419aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis return clang_findReferencesInFile(cursor, file, visitor); 420aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} 421aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 422aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis} // end: extern "C" 423aed123ec3cc37e457fe20a6158fdadf8849ad916Argyrios Kyrtzidis 424