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