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