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