CIndex.cpp revision 6045878f1fa7fad19d826634617991db99d3bd22
1d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===// 2d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// 3d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// The LLVM Compiler Infrastructure 4d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// 5d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// This file is distributed under the University of Illinois Open Source 6d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// License. See LICENSE.TXT for details. 70d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar// 8d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//===----------------------------------------------------------------------===// 9d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// 10ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// This file implements the main API hooks in the Clang-C Source Indexing 11ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// library. 12d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// 13d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//===----------------------------------------------------------------------===// 14d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek 15ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "CIndexer.h" 1616c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "CXCursor.h" 1795f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek#include "CXType.h" 18a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek#include "CXSourceLocation.h" 195352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor#include "CIndexDiagnostic.h" 20ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek 2104bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek#include "clang/Basic/Version.h" 22936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor 2350398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff#include "clang/AST/DeclVisitor.h" 24fb5704295c6137685a7b90b92cd6b958028740c8Steve Naroff#include "clang/AST/StmtVisitor.h" 257d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor#include "clang/AST/TypeLocVisitor.h" 26b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Basic/Diagnostic.h" 27b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Frontend/ASTUnit.h" 28b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Frontend/CompilerInstance.h" 29936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor#include "clang/Frontend/FrontendDiagnostic.h" 30d8210650ed948de65a08a8daf16d291b747717c4Ted Kremenek#include "clang/Lex/Lexer.h" 31b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Lex/PreprocessingRecord.h" 3233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor#include "clang/Lex/Preprocessor.h" 33a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor#include "llvm/ADT/STLExtras.h" 34d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek#include "llvm/ADT/Optional.h" 35d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek#include "clang/Analysis/Support/SaveAndRestore.h" 36c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar#include "llvm/Support/CrashRecoveryContext.h" 3748615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar#include "llvm/Support/PrettyStackTrace.h" 3802465750c8c3fa96b1e7e596b02297e24361dc4fDouglas Gregor#include "llvm/Support/MemoryBuffer.h" 39358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor#include "llvm/Support/raw_ostream.h" 407a07fcb8f10fe45ea65a0a41798eb1c40777bde4Douglas Gregor#include "llvm/Support/Timer.h" 418c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor#include "llvm/System/Mutex.h" 420829a839b05c687d3f11af0640d84c5d05f94124Benjamin Kramer#include "llvm/System/Program.h" 430a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor#include "llvm/System/Signals.h" 448c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor#include "llvm/System/Threading.h" 45fc0622155fa61349698a8fd0053773c37d9f7ac4Ted Kremenek 46c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer// Needed to define L_TMPNAM on some systems. 47c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer#include <cstdio> 48c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer 4950398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroffusing namespace clang; 5016c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenekusing namespace clang::cxcursor; 51ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenekusing namespace clang::cxstring; 5250398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff 5333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \brief The result of comparing two source ranges. 5433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregorenum RangeComparisonResult { 5533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief Either the ranges overlap or one of the ranges is invalid. 5633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor RangeOverlap, 57f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 5833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The first range ends before the second range starts. 5933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor RangeBefore, 60f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 6133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The first range starts after the second range ends. 6233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor RangeAfter 6333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor}; 6433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 65f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek/// \brief Compare two source ranges to determine their relative position in 6633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// the translation unit. 67f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekstatic RangeComparisonResult RangeCompare(SourceManager &SM, 68f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek SourceRange R1, 6933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor SourceRange R2) { 7033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor assert(R1.isValid() && "First range is invalid?"); 7133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor assert(R2.isValid() && "Second range is invalid?"); 72a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (R1.getEnd() != R2.getBegin() && 73d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin())) 7433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return RangeBefore; 75a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (R2.getEnd() != R1.getBegin() && 76d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin())) 7733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return RangeAfter; 7833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return RangeOverlap; 7933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor} 8033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 81fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek/// \brief Determine if a source location falls within, before, or after a 82fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek/// a given source range. 83fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekstatic RangeComparisonResult LocationCompare(SourceManager &SM, 84fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation L, SourceRange R) { 85fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek assert(R.isValid() && "First range is invalid?"); 86fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek assert(L.isValid() && "Second range is invalid?"); 87a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (L == R.getBegin() || L == R.getEnd()) 88fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeOverlap; 89fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (SM.isBeforeInTranslationUnit(L, R.getBegin())) 90fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeBefore; 91fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (SM.isBeforeInTranslationUnit(R.getEnd(), L)) 92fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeAfter; 93fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeOverlap; 94fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek} 95fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 9676dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// \brief Translate a Clang source range into a CIndex source range. 9776dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// 9876dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// Clang internally represents ranges where the end location points to the 9976dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// start of the token at the end. However, for external clients it is more 10076dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// useful to have a CXSourceRange be a proper half-open interval. This routine 10176dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// does the appropriate translation. 102f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed KremenekCXSourceRange cxloc::translateSourceRange(const SourceManager &SM, 10376dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar const LangOptions &LangOpts, 1040a76aae8c03cb7dd7bdbe683485560afaf695959Chris Lattner const CharSourceRange &R) { 10576dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar // We want the last character in this location, so we will adjust the 1066a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor // location accordingly. 10776dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar SourceLocation EndLoc = R.getEnd(); 108a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (EndLoc.isValid() && EndLoc.isMacroID()) 109a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor EndLoc = SM.getSpellingLoc(EndLoc); 1100a76aae8c03cb7dd7bdbe683485560afaf695959Chris Lattner if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) { 1116a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts); 11276dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar EndLoc = EndLoc.getFileLocWithOffset(Length); 11376dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar } 11476dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar 11576dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts }, 11676dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar R.getBegin().getRawEncoding(), 11776dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar EndLoc.getRawEncoding() }; 11876dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar return Result; 11976dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar} 1201db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 1218a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek//===----------------------------------------------------------------------===// 12233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor// Cursor visitor. 1238a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek//===----------------------------------------------------------------------===// 1248a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek 12589922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroffnamespace { 126c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 127c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekclass VisitorJob { 128c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekpublic: 129cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind, 1306045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek TypeLocVisitKind, OverloadExprPartsKind }; 131c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekprotected: 132cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek void *dataA; 133cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek void *dataB; 134c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek CXCursor parent; 135c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek Kind K; 136cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0) 137cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek : dataA(d1), dataB(d2), parent(C), K(k) {} 138c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekpublic: 139c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek Kind getKind() const { return K; } 140c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek const CXCursor &getParent() const { return parent; } 141c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek static bool classof(VisitorJob *VJ) { return true; } 142c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek}; 143c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 144c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenektypedef llvm::SmallVector<VisitorJob, 10> VisitorWorkList; 145c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 146c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek#define DEF_JOB(NAME, DATA, KIND)\ 147c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekclass NAME : public VisitorJob {\ 148c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekpublic:\ 149cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \ 150c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\ 151cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek DATA *get() const { return static_cast<DATA*>(dataA); }\ 152c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek}; 153c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 154f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed KremenekDEF_JOB(DeclVisit, Decl, DeclVisitKind) 155c0e1d923231d42fb0ac86e56a29ffc5c754657caTed KremenekDEF_JOB(StmtVisit, Stmt, StmtVisitKind) 156c0e1d923231d42fb0ac86e56a29ffc5c754657caTed KremenekDEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind) 1576045878f1fa7fad19d826634617991db99d3bd22Ted KremenekDEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind) 158c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek#undef DEF_JOB 159c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 160cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenekclass TypeLocVisit : public VisitorJob { 161cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenekpublic: 162cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek TypeLocVisit(TypeLoc tl, CXCursor parent) : 163cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek VisitorJob(parent, VisitorJob::TypeLocVisitKind, 164cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {} 165cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek 166cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek static bool classof(const VisitorJob *VJ) { 167cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek return VJ->getKind() == TypeLocVisitKind; 168cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek } 169cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek 170cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek TypeLoc get() { 171cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek QualType T = QualType::getFromOpaquePtr(dataA); 172cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek return TypeLoc(T, dataB); 173cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek } 174cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek}; 175cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek 176c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenekstatic inline void WLAddStmt(VisitorWorkList &WL, CXCursor Parent, Stmt *S) { 177c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek if (S) 178c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek WL.push_back(StmtVisit(S, Parent)); 179c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek} 180c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenekstatic inline void WLAddDecl(VisitorWorkList &WL, CXCursor Parent, Decl *D) { 181c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek if (D) 182c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek WL.push_back(DeclVisit(D, Parent)); 183c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek} 184cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenekstatic inline void WLAddTypeLoc(VisitorWorkList &WL, CXCursor Parent, 185cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek TypeSourceInfo *TI) { 186cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek if (TI) 187cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent)); 188cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek} 189f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 190b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor// Cursor visitor. 1917d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorclass CursorVisitor : public DeclVisitor<CursorVisitor, bool>, 192a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor public TypeLocVisitor<CursorVisitor, bool>, 193a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor public StmtVisitor<CursorVisitor, bool> 1947d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor{ 19533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The translation unit we are traversing. 196b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor ASTUnit *TU; 197f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 19833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The parent cursor whose children we are traversing. 199b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXCursor Parent; 200f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 20133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The declaration that serves at the parent of any statement or 20233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// expression nodes. 203f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor Decl *StmtParent; 204f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 20533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The visitor function. 206b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXCursorVisitor Visitor; 207f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 20833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The opaque client data, to be passed along to the visitor. 209b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXClientData ClientData; 210f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2117d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor // MaxPCHLevel - the maximum PCH level of declarations that we will pass on 2127d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor // to the visitor. Declarations with a PCH level greater than this value will 2137d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor // be suppressed. 2147d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor unsigned MaxPCHLevel; 21533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 21633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief When valid, a source range to which the cursor should restrict 21733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// its search. 21833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor SourceRange RegionOfInterest; 219f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 220d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // FIXME: Eventually remove. This part of a hack to support proper 221d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // iteration over all Decls contained lexically within an ObjC container. 222d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator *DI_current; 223d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator DE_current; 224d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 225b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor using DeclVisitor<CursorVisitor, bool>::Visit; 2267d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor using TypeLocVisitor<CursorVisitor, bool>::Visit; 227a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor using StmtVisitor<CursorVisitor, bool>::Visit; 228f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 229f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek /// \brief Determine whether this particular source range comes before, comes 230f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek /// after, or overlaps the region of interest. 23133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// 232d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar /// \param R a half-open source range retrieved from the abstract syntax tree. 233f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek RangeComparisonResult CompareRegionOfInterest(SourceRange R); 234f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2350f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek class SetParentRAII { 2360f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek CXCursor &Parent; 2370f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek Decl *&StmtParent; 2380f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek CXCursor OldParent; 2390f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 2400f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek public: 2410f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent) 2420f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) 2430f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek { 2440f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek Parent = NewParent; 2450f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (clang_isDeclaration(Parent.kind)) 2460f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek StmtParent = getCursorDecl(Parent); 2470f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek } 2480f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 2490f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek ~SetParentRAII() { 2500f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek Parent = OldParent; 2510f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (clang_isDeclaration(Parent.kind)) 2520f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek StmtParent = getCursorDecl(Parent); 2530f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek } 2540f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek }; 2550f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 256b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorpublic: 257f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData, 258f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek unsigned MaxPCHLevel, 25933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor SourceRange RegionOfInterest = SourceRange()) 260f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek : TU(TU), Visitor(Visitor), ClientData(ClientData), 261d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest), 262d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DI_current(0) 263b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor { 264b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.kind = CXCursor_NoDeclFound; 265b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.data[0] = 0; 266b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.data[1] = 0; 267b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.data[2] = 0; 268f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor StmtParent = 0; 269b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 270f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 271ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek ASTUnit *getASTUnit() const { return TU; } 272ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek 27333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false); 274788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 275788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> 276788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor getPreprocessedEntities(); 277788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 278b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor bool VisitChildren(CXCursor Parent); 279f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2807d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor // Declaration visitors 28109dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek bool VisitAttributes(Decl *D); 2821ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek bool VisitBlockDecl(BlockDecl *B); 2833064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek bool VisitCXXRecordDecl(CXXRecordDecl *D); 284d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek llvm::Optional<bool> shouldVisitCursor(CXCursor C); 285b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor bool VisitDeclContext(DeclContext *DC); 28679758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitTranslationUnitDecl(TranslationUnitDecl *D); 28779758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitTypedefDecl(TypedefDecl *D); 28879758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitTagDecl(TagDecl *D); 2890ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D); 29074dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor bool VisitClassTemplatePartialSpecializationDecl( 29174dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor ClassTemplatePartialSpecializationDecl *D); 292fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); 2934540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitEnumConstantDecl(EnumConstantDecl *D); 29479758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitDeclaratorDecl(DeclaratorDecl *DD); 2954540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitFunctionDecl(FunctionDecl *ND); 29679758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitFieldDecl(FieldDecl *D); 29779758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitVarDecl(VarDecl *); 29884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); 299fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D); 30039d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor bool VisitClassTemplateDecl(ClassTemplateDecl *D); 30184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); 30279758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCMethodDecl(ObjCMethodDecl *ND); 3034540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitObjCContainerDecl(ObjCContainerDecl *D); 30479758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND); 30579758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID); 30623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD); 30779758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); 3084540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitObjCImplDecl(ObjCImplDecl *D); 30979758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); 3101ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor bool VisitObjCImplementationDecl(ObjCImplementationDecl *D); 31179758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations. 31279758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); 31379758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCClassDecl(ObjCClassDecl *D); 314a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek bool VisitLinkageSpecDecl(LinkageSpecDecl *D); 3158f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek bool VisitNamespaceDecl(NamespaceDecl *D); 3166931900f43cea558c6974075256c07728dbfecc6Douglas Gregor bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D); 3170a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D); 3187e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor bool VisitUsingDecl(UsingDecl *D); 3197e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); 3207e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); 3210a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 32201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Name visitor 32301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor bool VisitDeclarationNameInfo(DeclarationNameInfo Name); 324c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range); 32501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 326fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // Template visitors 327fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateParameters(const TemplateParameterList *Params); 3280b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor bool VisitTemplateName(TemplateName Name, SourceLocation Loc); 329fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL); 330fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 3317d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor // Type visitors 33201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL); 333f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL); 3347d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor bool VisitTypedefTypeLoc(TypedefTypeLoc TL); 335f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL); 336f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitTagTypeLoc(TagTypeLoc TL); 337fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL); 338f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL); 339c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL); 340f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL); 341f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitPointerTypeLoc(PointerTypeLoc TL); 342f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL); 343f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL); 344f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL); 345f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL); 34601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false); 347f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitArrayTypeLoc(ArrayTypeLoc TL); 348fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL); 3492332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor // FIXME: Implement visitors here when the unimplemented TypeLocs get 3502332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor // implemented 3512332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL); 3522332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL); 353f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 354a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor // Statement visitors 355a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor bool VisitStmt(Stmt *S); 356a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor bool VisitDeclStmt(DeclStmt *S); 35736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor bool VisitGotoStmt(GotoStmt *S); 358f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 359336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor // Expression visitors 3608947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor bool VisitDeclRefExpr(DeclRefExpr *E); 3611ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek bool VisitBlockExpr(BlockExpr *B); 3621ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek bool VisitExplicitCastExpr(ExplicitCastExpr *E); 363c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregor bool VisitObjCMessageExpr(ObjCMessageExpr *E); 36481d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor bool VisitObjCEncodeExpr(ObjCEncodeExpr *E); 3658ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor bool VisitOffsetOfExpr(OffsetOfExpr *E); 3661ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); 36736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor bool VisitAddrLabelExpr(AddrLabelExpr *E); 368648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor bool VisitTypesCompatibleExpr(TypesCompatibleExpr *E); 369648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor bool VisitVAArgExpr(VAArgExpr *E); 370fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor bool VisitDesignatedInitExpr(DesignatedInitExpr *E); 371948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor bool VisitCXXTypeidExpr(CXXTypeidExpr *E); 3723d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor bool VisitCXXUuidofExpr(CXXUuidofExpr *E); 373da135b14ad5366f27143c9cd9f51ad2320e62758Douglas Gregor bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { return false; } 374ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor bool VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E); 375ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor bool VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); 3761bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor bool VisitCXXNewExpr(CXXNewExpr *E); 3776f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor bool VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); 3783d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor bool VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E); 379bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); 380ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor bool VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E); 38125d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); 382c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 383c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek#define DATA_RECURSIVE_VISIT(NAME)\ 384c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekbool Visit##NAME(NAME *S) { return VisitDataRecursive(S); } 385c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek DATA_RECURSIVE_VISIT(BinaryOperator) 386cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek DATA_RECURSIVE_VISIT(CompoundLiteralExpr) 387c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek DATA_RECURSIVE_VISIT(CXXMemberCallExpr) 3888c269ac75569454a049385b1246140db5f2b6faaTed Kremenek DATA_RECURSIVE_VISIT(CXXOperatorCallExpr) 389bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek DATA_RECURSIVE_VISIT(DoStmt) 390c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek DATA_RECURSIVE_VISIT(IfStmt) 391a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek DATA_RECURSIVE_VISIT(InitListExpr) 392bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek DATA_RECURSIVE_VISIT(ForStmt) 393c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek DATA_RECURSIVE_VISIT(MemberExpr) 3946045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek DATA_RECURSIVE_VISIT(OverloadExpr) 395f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek DATA_RECURSIVE_VISIT(SwitchStmt) 396bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek DATA_RECURSIVE_VISIT(WhileStmt) 3976045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek DATA_RECURSIVE_VISIT(UnresolvedMemberExpr) 398a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek 399c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Data-recursive visitor functions. 400c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek bool IsInRegionOfInterest(CXCursor C); 401c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek bool RunVisitorWorkList(VisitorWorkList &WL); 402c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek void EnqueueWorkList(VisitorWorkList &WL, Stmt *S); 403c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek bool VisitDataRecursive(Stmt *S); 404b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor}; 405f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 406b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} // end anonymous namespace 4070d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 408a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorstatic SourceRange getRawCursorExtent(CXCursor C); 409a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 41033e9abd21083a0191a7676a04b497006d2da184dDouglas GregorRangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) { 41133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return RangeCompare(TU->getSourceManager(), R, RegionOfInterest); 41233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor} 41333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 414b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \brief Visit the given cursor and, if requested by the visitor, 415b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// its children. 416b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// 41733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \param Cursor the cursor to visit. 41833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// 41933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \param CheckRegionOfInterest if true, then the caller already checked that 42033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// this cursor is within the region of interest. 42133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// 422b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \returns true if the visitation should be aborted, false if it 423b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// should continue. 42433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregorbool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) { 425b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isInvalid(Cursor.kind)) 426b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 427f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 428b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isDeclaration(Cursor.kind)) { 429b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Decl *D = getCursorDecl(Cursor); 430b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor assert(D && "Invalid declaration cursor"); 431b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (D->getPCHLevel() > MaxPCHLevel) 432b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 433b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor 434b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (D->isImplicit()) 435b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 436b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 4370d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 43833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // If we have a range of interest, and this cursor doesn't intersect with it, 43933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // we're done. 44033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) { 441a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor SourceRange Range = getRawCursorExtent(Cursor); 442f408f32aa9ae3d97bc656267dc5d78fa7d03499bDaniel Dunbar if (Range.isInvalid() || CompareRegionOfInterest(Range)) 44333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return false; 44433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor } 445f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 446b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor switch (Visitor(Cursor, Parent, ClientData)) { 447b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor case CXChildVisit_Break: 448b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 4490d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 450b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor case CXChildVisit_Continue: 451b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 4522e331b938b38057e333fab0ba841130ea8467794Douglas Gregor 453b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor case CXChildVisit_Recurse: 454b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return VisitChildren(Cursor); 455b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 4560d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 457fd64377225a6a140bddb3f997d52a036486f9360Douglas Gregor return false; 458b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} 4590d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 460788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregorstd::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> 461788f5a1242c04762f91eaa7565c07b9865846d88Douglas GregorCursorVisitor::getPreprocessedEntities() { 462788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor PreprocessingRecord &PPRec 463788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = *TU->getPreprocessor().getPreprocessingRecord(); 464788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 465788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor bool OnlyLocalDecls 466788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = !TU->isMainFileAST() && TU->getOnlyLocalDecls(); 467788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 468788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // There is no region of interest; we have to walk everything. 469788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (RegionOfInterest.isInvalid()) 470788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor return std::make_pair(PPRec.begin(OnlyLocalDecls), 471788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor PPRec.end(OnlyLocalDecls)); 472788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 473788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // Find the file in which the region of interest lands. 474788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor SourceManager &SM = TU->getSourceManager(); 475788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor std::pair<FileID, unsigned> Begin 476788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin()); 477788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor std::pair<FileID, unsigned> End 478788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd()); 479788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 480788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // The region of interest spans files; we have to walk everything. 481788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (Begin.first != End.first) 482788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor return std::make_pair(PPRec.begin(OnlyLocalDecls), 483788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor PPRec.end(OnlyLocalDecls)); 484788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 485788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap 486788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = TU->getPreprocessedEntitiesByFile(); 487788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (ByFileMap.empty()) { 488788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // Build the mapping from files to sets of preprocessed entities. 489788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor for (PreprocessingRecord::iterator E = PPRec.begin(OnlyLocalDecls), 490788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor EEnd = PPRec.end(OnlyLocalDecls); 491788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor E != EEnd; ++E) { 492788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor std::pair<FileID, unsigned> P 493788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin()); 494788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor ByFileMap[P.first].push_back(*E); 495788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor } 496788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor } 497788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 498788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor return std::make_pair(ByFileMap[Begin.first].begin(), 499788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor ByFileMap[Begin.first].end()); 500788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor} 501788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 502b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \brief Visit the children of the given cursor. 503b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// 504b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \returns true if the visitation should be aborted, false if it 505b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// should continue. 506f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekbool CursorVisitor::VisitChildren(CXCursor Cursor) { 507a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor if (clang_isReference(Cursor.kind)) { 508a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor // By definition, references have no children. 509a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return false; 510a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor } 511f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 512f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek // Set the Parent field to Cursor, then back to its old value once we're 513b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor // done. 5140f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek SetParentRAII SetParent(Parent, StmtParent, Cursor); 515f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 516b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isDeclaration(Cursor.kind)) { 517b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Decl *D = getCursorDecl(Cursor); 518b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor assert(D && "Invalid declaration cursor"); 519539311e0221df256c70c1c3080c8af847cd29dffTed Kremenek return VisitAttributes(D) || Visit(D); 520b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 521f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 522a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor if (clang_isStatement(Cursor.kind)) 523a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return Visit(getCursorStmt(Cursor)); 524a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor if (clang_isExpression(Cursor.kind)) 525a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return Visit(getCursorExpr(Cursor)); 526f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 527b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isTranslationUnit(Cursor.kind)) { 528b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor ASTUnit *CXXUnit = getCursorASTUnit(Cursor); 52933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() && 53033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor RegionOfInterest.isInvalid()) { 531eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(), 532eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TLEnd = CXXUnit->top_level_end(); 533eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TL != TLEnd; ++TL) { 534eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (Visit(MakeCXCursor(*TL, CXXUnit), true)) 5357b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor return true; 5367b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor } 5370396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor } else if (VisitDeclContext( 5380396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor CXXUnit->getASTContext().getTranslationUnitDecl())) 5390396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor return true; 5403178cb674ac8c3b59e1791e14d38d48619a1b621Bob Wilson 5410396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // Walk the preprocessing record. 5428de30ffa2b60dbc672c0f3bcdaa07a8efcc3bcf8Daniel Dunbar if (CXXUnit->getPreprocessor().getPreprocessingRecord()) { 5430396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // FIXME: Once we have the ability to deserialize a preprocessing record, 5440396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // do so. 545788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor PreprocessingRecord::iterator E, EEnd; 546788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) { 5470396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { 5480396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (Visit(MakeMacroInstantiationCursor(MI, CXXUnit))) 5490396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor return true; 550788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 5510396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor continue; 5520396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor } 5530396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor 5540396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { 5550396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (Visit(MakeMacroDefinitionCursor(MD, CXXUnit))) 5560396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor return true; 5570396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor 5580396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor continue; 5590396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor } 560ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 561ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) { 562ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (Visit(MakeInclusionDirectiveCursor(ID, CXXUnit))) 563ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return true; 564ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 565ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor continue; 566ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor } 5670396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor } 5680396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor } 5697b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor return false; 570b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 571f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 572b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor // Nothing to visit at the moment. 573b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 574dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 575dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 5761ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenekbool CursorVisitor::VisitBlockDecl(BlockDecl *B) { 577fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall if (Visit(B->getSignatureAsWritten()->getTypeLoc())) 578fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall return true; 5791ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek 580664cffd330611d78fc0286f539589920a37ca328Ted Kremenek if (Stmt *Body = B->getBody()) 581664cffd330611d78fc0286f539589920a37ca328Ted Kremenek return Visit(MakeCXCursor(Body, StmtParent, TU)); 582664cffd330611d78fc0286f539589920a37ca328Ted Kremenek 583664cffd330611d78fc0286f539589920a37ca328Ted Kremenek return false; 5841ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek} 5851ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek 586d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenekllvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) { 587d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (RegionOfInterest.isValid()) { 588d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceRange Range = getRawCursorExtent(Cursor); 589d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (Range.isInvalid()) 590d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return llvm::Optional<bool>(); 59109dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek 592d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek switch (CompareRegionOfInterest(Range)) { 593d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek case RangeBefore: 594d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // This declaration comes before the region of interest; skip it. 595d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return llvm::Optional<bool>(); 59623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 597d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek case RangeAfter: 598d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // This declaration comes after the region of interest; we're done. 599d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 600d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar 601d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek case RangeOverlap: 602d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // This declaration overlaps the region of interest; visit it. 603d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 604d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 605d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 606d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return true; 607d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek} 608f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 609d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenekbool CursorVisitor::VisitDeclContext(DeclContext *DC) { 610d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); 611f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 612d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // FIXME: Eventually remove. This part of a hack to support proper 613d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // iteration over all Decls contained lexically within an ObjC container. 614d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I); 615d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E); 616f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 617d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek for ( ; I != E; ++I) { 618d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek Decl *D = *I; 619d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (D->getLexicalDeclContext() != DC) 620d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 621d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek CXCursor Cursor = MakeCXCursor(D, TU); 622d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek const llvm::Optional<bool> &V = shouldVisitCursor(Cursor); 623d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.hasValue()) 624d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 625d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.getValue()) 626d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 627d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar if (Visit(Cursor, true)) 628b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 629b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 630b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 631dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 632dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 6331ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) { 6341ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor llvm_unreachable("Translation units are visited directly by Visit()"); 6351ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 6361ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 6371ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 6381ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) { 6391ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo()) 6401ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(TSInfo->getTypeLoc()); 641f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 6421ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 6431ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 6441ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 6451ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTagDecl(TagDecl *D) { 6461ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitDeclContext(D); 6471ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 6481ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 6490ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregorbool CursorVisitor::VisitClassTemplateSpecializationDecl( 6500ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor ClassTemplateSpecializationDecl *D) { 6510ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor bool ShouldVisitBody = false; 6520ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor switch (D->getSpecializationKind()) { 6530ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_Undeclared: 6540ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ImplicitInstantiation: 6550ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor // Nothing to visit 6560ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return false; 6570ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6580ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ExplicitInstantiationDeclaration: 6590ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ExplicitInstantiationDefinition: 6600ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor break; 6610ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6620ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ExplicitSpecialization: 6630ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor ShouldVisitBody = true; 6640ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor break; 6650ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor } 6660ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6670ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor // Visit the template arguments used in the specialization. 6680ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) { 6690ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor TypeLoc TL = SpecType->getTypeLoc(); 6700ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (TemplateSpecializationTypeLoc *TSTLoc 6710ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) { 6720ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I) 6730ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I))) 6740ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return true; 6750ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor } 6760ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor } 6770ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6780ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (ShouldVisitBody && VisitCXXRecordDecl(D)) 6790ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return true; 6800ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6810ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return false; 6820ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor} 6830ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 68474dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregorbool CursorVisitor::VisitClassTemplatePartialSpecializationDecl( 68574dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor ClassTemplatePartialSpecializationDecl *D) { 68674dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor // FIXME: Visit the "outer" template parameter lists on the TagDecl 68774dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor // before visiting these template parameters. 68874dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 68974dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return true; 69074dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor 69174dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor // Visit the partial specialization arguments. 69274dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten(); 69374dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I) 69474dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor if (VisitTemplateArgumentLoc(TemplateArgs[I])) 69574dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return true; 69674dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor 69774dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return VisitCXXRecordDecl(D); 69874dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor} 69974dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor 700fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { 70184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor // Visit the default argument. 70284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) 70384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo()) 70484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (Visit(DefArg->getTypeLoc())) 70584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 70684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 707fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 708fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 709fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 7101ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) { 7111ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Expr *Init = D->getInitExpr()) 7121ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(MakeCXCursor(Init, StmtParent, TU)); 7131ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 7141ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 7151ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 7167d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorbool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { 7177d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo()) 7187d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor if (Visit(TSInfo->getTypeLoc())) 7197d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor return true; 7207d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 7217d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor return false; 7227d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor} 7237d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 724a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor/// \brief Compare two base or member initializers based on their source order. 725a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregorstatic int CompareCXXBaseOrMemberInitializers(const void* Xp, const void *Yp) { 726a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor CXXBaseOrMemberInitializer const * const *X 727a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor = static_cast<CXXBaseOrMemberInitializer const * const *>(Xp); 728a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor CXXBaseOrMemberInitializer const * const *Y 729a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor = static_cast<CXXBaseOrMemberInitializer const * const *>(Yp); 730a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 731a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if ((*X)->getSourceOrder() < (*Y)->getSourceOrder()) 732a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return -1; 733a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder()) 734a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return 1; 735a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor else 736a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return 0; 737a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor} 738a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 739b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { 74001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) { 74101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Visit the function declaration's syntactic components in the order 74201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // written. This requires a bit of work. 74301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor TypeLoc TL = TSInfo->getTypeLoc(); 74401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL); 74501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 74601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // If we have a function declared directly (without the use of a typedef), 74701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // visit just the return type. Otherwise, just visit the function's type 74801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // now. 74901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) || 75001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor (!FTL && Visit(TL))) 75101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return true; 75201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 753c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit the nested-name-specifier, if present. 754c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = ND->getQualifier()) 755c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, ND->getQualifierRange())) 756c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 75701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 75801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Visit the declaration name. 75901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (VisitDeclarationNameInfo(ND->getNameInfo())) 76001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return true; 76101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 76201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // FIXME: Visit explicitly-specified template arguments! 76301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 76401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Visit the function parameters, if we have a function type. 76501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (FTL && VisitFunctionTypeLoc(*FTL, true)) 76601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return true; 76701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 76801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // FIXME: Attributes? 76901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor } 77001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 771a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (ND->isThisDeclarationADefinition()) { 772a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) { 773a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Find the initializers that were written in the source. 774a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor llvm::SmallVector<CXXBaseOrMemberInitializer *, 4> WrittenInits; 775a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(), 776a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor IEnd = Constructor->init_end(); 777a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor I != IEnd; ++I) { 778a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (!(*I)->isWritten()) 779a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor continue; 780a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 781a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor WrittenInits.push_back(*I); 782a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 783a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 784a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Sort the initializers in source order 785a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(), 786a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor &CompareCXXBaseOrMemberInitializers); 787a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 788a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Visit the initializers in source order 789a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) { 790a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor CXXBaseOrMemberInitializer *Init = WrittenInits[I]; 791a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Init->isMemberInitializer()) { 792a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Visit(MakeCursorMemberRef(Init->getMember(), 793a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor Init->getMemberLocation(), TU))) 794a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 795a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) { 796a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Visit(BaseInfo->getTypeLoc())) 797a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 798a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 799a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 800a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Visit the initializer value. 801a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Expr *Initializer = Init->getInit()) 802a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Visit(MakeCXCursor(Initializer, ND, TU))) 803a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 804a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 805a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 806a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 807a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) 808a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 809a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 810f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 811b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 812b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} 813dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 8141ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitFieldDecl(FieldDecl *D) { 8151ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (VisitDeclaratorDecl(D)) 8161ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 817f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8181ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Expr *BitWidth = D->getBitWidth()) 8191ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(MakeCXCursor(BitWidth, StmtParent, TU)); 820f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8211ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 8221ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 8231ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 8241ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitVarDecl(VarDecl *D) { 8251ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (VisitDeclaratorDecl(D)) 8261ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 827f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8281ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Expr *Init = D->getInit()) 8291ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(MakeCXCursor(Init, StmtParent, TU)); 830f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8311ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 8321ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 8331ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 83484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregorbool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { 83584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (VisitDeclaratorDecl(D)) 83684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 83784b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 83884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) 83984b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (Expr *DefArg = D->getDefaultArgument()) 84084b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return Visit(MakeCXCursor(DefArg, StmtParent, TU)); 84184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 84284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return false; 84384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor} 84484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 845fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { 846fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // FIXME: Visit the "outer" template parameter lists on the FunctionDecl 847fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // before visiting these template parameters. 848fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 849fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return true; 850fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 851fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return VisitFunctionDecl(D->getTemplatedDecl()); 852fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 853fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 85439d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregorbool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) { 85539d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor // FIXME: Visit the "outer" template parameter lists on the TagDecl 85639d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor // before visiting these template parameters. 85739d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 85839d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor return true; 85939d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor 86039d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor return VisitCXXRecordDecl(D->getTemplatedDecl()); 86139d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor} 86239d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor 86384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregorbool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { 86484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 86584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 86684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 86784b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() && 86884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor VisitTemplateArgumentLoc(D->getDefaultArgument())) 86984b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 87084b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 87184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return false; 87284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor} 87384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 8741ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) { 8754bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo()) 8764bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor if (Visit(TSInfo->getTypeLoc())) 8774bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor return true; 8784bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor 879f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek for (ObjCMethodDecl::param_iterator P = ND->param_begin(), 8801ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor PEnd = ND->param_end(); 8811ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor P != PEnd; ++P) { 8821ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Visit(MakeCXCursor(*P, TU))) 8831ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 8841ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor } 885f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8861ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (ND->isThisDeclarationADefinition() && 8871ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) 8881ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 889f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8901ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 8911ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 8921ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 893d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremeneknamespace { 894d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek struct ContainerDeclsSort { 895d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceManager &SM; 896d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek ContainerDeclsSort(SourceManager &sm) : SM(sm) {} 897d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek bool operator()(Decl *A, Decl *B) { 898d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation L_A = A->getLocStart(); 899d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation L_B = B->getLocStart(); 900d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek assert(L_A.isValid() && L_B.isValid()); 901d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return SM.isBeforeInTranslationUnit(L_A, L_B); 902d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 903d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek }; 904d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek} 905d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 906a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregorbool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) { 907d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially 908d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // an @implementation can lexically contain Decls that are not properly 909d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // nested in the AST. When we identify such cases, we need to retrofit 910d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // this nesting here. 911d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!DI_current) 912d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return VisitDeclContext(D); 913d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 914d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Scan the Decls that immediately come after the container 915d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // in the current DeclContext. If any fall within the 916d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // container's lexical region, stash them into a vector 917d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // for later processing. 918d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek llvm::SmallVector<Decl *, 24> DeclsInContainer; 919d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation EndLoc = D->getSourceRange().getEnd(); 920d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceManager &SM = TU->getSourceManager(); 921d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (EndLoc.isValid()) { 922d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator next = *DI_current; 923d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek while (++next != DE_current) { 924d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek Decl *D_next = *next; 925d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!D_next) 926d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 927d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation L = D_next->getLocStart(); 928d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!L.isValid()) 929d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 930d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (SM.isBeforeInTranslationUnit(L, EndLoc)) { 931d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek *DI_current = next; 932d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclsInContainer.push_back(D_next); 933d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 934d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 935d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 936d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 937d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 938d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 939d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // The common case. 940d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (DeclsInContainer.empty()) 941d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return VisitDeclContext(D); 942d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 943d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Get all the Decls in the DeclContext, and sort them with the 944d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // additional ones we've collected. Then visit them. 945d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end(); 946d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek I!=E; ++I) { 947d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek Decl *subDecl = *I; 9480582c897ec7261b4c6af0fe26dc2a0b6b54d266cTed Kremenek if (!subDecl || subDecl->getLexicalDeclContext() != D || 9490582c897ec7261b4c6af0fe26dc2a0b6b54d266cTed Kremenek subDecl->getLocStart().isInvalid()) 950d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 951d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclsInContainer.push_back(subDecl); 952d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 953d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 954d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Now sort the Decls so that they appear in lexical order. 955d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek std::sort(DeclsInContainer.begin(), DeclsInContainer.end(), 956d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek ContainerDeclsSort(SM)); 957d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 958d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Now visit the decls. 959d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(), 960d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek E = DeclsInContainer.end(); I != E; ++I) { 961d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek CXCursor Cursor = MakeCXCursor(*I, TU); 962d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek const llvm::Optional<bool> &V = shouldVisitCursor(Cursor); 963d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.hasValue()) 964d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 965d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.getValue()) 966d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 967d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (Visit(Cursor, true)) 968d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return true; 969d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 970d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 971a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor} 972a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor 973b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { 974b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(), 975b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor TU))) 976b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 977f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 97878db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin(); 97978db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(), 98078db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor E = ND->protocol_end(); I != E; ++I, ++PL) 981b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 982b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 983f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 984a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return VisitObjCContainerDecl(ND); 985dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 986dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 9871ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { 9881ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin(); 9891ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), 9901ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor E = PID->protocol_end(); I != E; ++I, ++PL) 9911ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 9921ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 993f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 9941ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCContainerDecl(PID); 9951ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 9961ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 99723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenekbool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) { 99883cb94269015bf2770ade71e616c5322ea7e76e1Douglas Gregor if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc())) 999fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall return true; 1000fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall 100123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // FIXME: This implements a workaround with @property declarations also being 100223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // installed in the DeclContext for the @interface. Eventually this code 100323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // should be removed. 100423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext()); 100523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (!CDecl || !CDecl->IsClassExtension()) 100623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 100723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 100823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCInterfaceDecl *ID = CDecl->getClassInterface(); 100923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (!ID) 101023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 101123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 101223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek IdentifierInfo *PropertyId = PD->getIdentifier(); 101323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCPropertyDecl *prevDecl = 101423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId); 101523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 101623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (!prevDecl) 101723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 101823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 101923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // Visit synthesized methods since they will be skipped when visiting 102023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // the @interface. 102123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl()) 1022a054fb46b1fb596d1719b89d2d9a5be3c32a4b0dTed Kremenek if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl) 102323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (Visit(MakeCXCursor(MD, TU))) 102423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return true; 102523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 102623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl()) 1027a054fb46b1fb596d1719b89d2d9a5be3c32a4b0dTed Kremenek if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl) 102823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (Visit(MakeCXCursor(MD, TU))) 102923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return true; 103023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 103123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 103223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek} 103323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 1034b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { 1035dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek // Issue callbacks for super class. 1036b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (D->getSuperClass() && 1037b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), 1038f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek D->getSuperClassLoc(), 1039b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor TU))) 1040b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 1041f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 104278db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); 104378db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), 104478db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor E = D->protocol_end(); I != E; ++I, ++PL) 1045b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 1046b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 1047f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1048a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return VisitObjCContainerDecl(D); 1049dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 1050dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 10511ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) { 10521ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCContainerDecl(D); 10531ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 10541ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 10551ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { 1056ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek // 'ID' could be null when dealing with invalid code. 1057ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek if (ObjCInterfaceDecl *ID = D->getClassInterface()) 1058ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU))) 1059ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek return true; 1060f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 10611ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCImplDecl(D); 10621ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 10631ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 10641ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { 10651ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor#if 0 10661ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor // Issue callbacks for super class. 10671ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor // FIXME: No source location information! 10681ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (D->getSuperClass() && 10691ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), 1070f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek D->getSuperClassLoc(), 10711ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor TU))) 1072a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return true; 10731ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor#endif 1074f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 10751ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCImplDecl(D); 1076dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 1077dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 10781ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { 10791ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); 10801ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(), 10811ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor E = D->protocol_end(); 10821ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor I != E; ++I, ++PL) 1083b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 1084b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 1085f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1086f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return false; 1087dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 1088dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 10891ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) { 10901ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C) 10911ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU))) 10921ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 1093f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 10941ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 1095dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 10965e4bc590b0ea010e38372d0b4a0aab578a746fe6Benjamin Kramer 10978f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenekbool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) { 10988f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek return VisitDeclContext(D); 10998f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek} 11008f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek 11016931900f43cea558c6974075256c07728dbfecc6Douglas Gregorbool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { 1102c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1103c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = D->getQualifier()) 1104c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, D->getQualifierRange())) 1105c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 11066931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 11076931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(), 11086931900f43cea558c6974075256c07728dbfecc6Douglas Gregor D->getTargetNameLoc(), TU)); 11096931900f43cea558c6974075256c07728dbfecc6Douglas Gregor} 11106931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 11117e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUsingDecl(UsingDecl *D) { 1112c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1113c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameDecl()) 1114c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, D->getNestedNameRange())) 1115c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 11167e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 11171f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU))) 11181f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return true; 11191f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 11207e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return VisitDeclarationNameInfo(D->getNameInfo()); 11217e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor} 11227e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 11230a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregorbool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { 1124c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1125c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = D->getQualifier()) 1126c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, D->getQualifierRange())) 1127c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 11280a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 11290a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(), 11300a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor D->getIdentLocation(), TU)); 11310a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor} 11320a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 11337e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { 1134c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1135c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier()) 1136c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange())) 1137c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 1138c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 11397e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return VisitDeclarationNameInfo(D->getNameInfo()); 11407e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor} 11417e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 11427e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUnresolvedUsingTypenameDecl( 11437e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor UnresolvedUsingTypenameDecl *D) { 1144c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1145c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier()) 1146c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange())) 1147c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 1148c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 11497e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return false; 11507e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor} 11517e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 115201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) { 115301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor switch (Name.getName().getNameKind()) { 115401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::Identifier: 115501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXLiteralOperatorName: 115601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXOperatorName: 115701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXUsingDirective: 115801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 115901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 116001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXConstructorName: 116101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXDestructorName: 116201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXConversionFunctionName: 116301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo()) 116401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return Visit(TSInfo->getTypeLoc()); 116501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 116601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 116701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::ObjCZeroArgSelector: 116801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::ObjCOneArgSelector: 116901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::ObjCMultiArgSelector: 117001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // FIXME: Per-identifier location info? 117101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 117201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor } 117301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 117401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 117501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor} 117601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 1177c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregorbool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS, 1178c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor SourceRange Range) { 1179c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // FIXME: This whole routine is a hack to work around the lack of proper 1180c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // source information in nested-name-specifiers (PR5791). Since we do have 1181c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // a beginning source location, we can visit the first component of the 1182c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // nested-name-specifier, if it's a single-token component. 1183c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (!NNS) 1184c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return false; 1185c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1186c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Get the first component in the nested-name-specifier. 1187c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor while (NestedNameSpecifier *Prefix = NNS->getPrefix()) 1188c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor NNS = Prefix; 1189c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1190c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor switch (NNS->getKind()) { 1191c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::Namespace: 1192c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // FIXME: The token at this source location might actually have been a 1193c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // namespace alias, but we don't model that. Lame! 1194c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), 1195c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor TU)); 1196c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1197c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::TypeSpec: { 1198c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // If the type has a form where we know that the beginning of the source 1199c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // range matches up with a reference cursor. Visit the appropriate reference 1200c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // cursor. 1201c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor Type *T = NNS->getAsType(); 1202c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (const TypedefType *Typedef = dyn_cast<TypedefType>(T)) 1203c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU)); 1204c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (const TagType *Tag = dyn_cast<TagType>(T)) 1205c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU)); 1206c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (const TemplateSpecializationType *TST 1207c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor = dyn_cast<TemplateSpecializationType>(T)) 1208c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return VisitTemplateName(TST->getTemplateName(), Range.getBegin()); 1209c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor break; 1210c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor } 1211c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1212c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::TypeSpecWithTemplate: 1213c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::Global: 1214c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::Identifier: 1215c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor break; 1216c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor } 1217c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1218c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return false; 1219c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor} 1220c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1221fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateParameters( 1222fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor const TemplateParameterList *Params) { 1223fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (!Params) 1224fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1225fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1226fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor for (TemplateParameterList::const_iterator P = Params->begin(), 1227fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor PEnd = Params->end(); 1228fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor P != PEnd; ++P) { 1229fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (Visit(MakeCXCursor(*P, TU))) 1230fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return true; 1231fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor } 1232fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1233fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1234fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1235fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 12360b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregorbool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) { 12370b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor switch (Name.getKind()) { 12380b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::Template: 12390b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU)); 12400b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 12410b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::OverloadedTemplate: 12421f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor // Visit the overloaded template set. 12431f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU))) 12441f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return true; 12451f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 12460b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return false; 12470b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 12480b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::DependentTemplate: 12490b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // FIXME: Visit nested-name-specifier. 12500b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return false; 12510b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 12520b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::QualifiedTemplate: 12530b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // FIXME: Visit nested-name-specifier. 12540b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return Visit(MakeCursorTemplateRef( 12550b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor Name.getAsQualifiedTemplateName()->getDecl(), 12560b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor Loc, TU)); 12570b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor } 12580b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 12590b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return false; 12600b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor} 12610b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 1262fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) { 1263fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor switch (TAL.getArgument().getKind()) { 1264fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Null: 1265fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Integral: 1266fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1267fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1268fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Pack: 1269fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // FIXME: Implement when variadic templates come along. 1270fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1271fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1272fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Type: 1273fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo()) 1274fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return Visit(TSInfo->getTypeLoc()); 1275fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1276fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1277fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Declaration: 1278fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (Expr *E = TAL.getSourceDeclExpression()) 1279fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return Visit(MakeCXCursor(E, StmtParent, TU)); 1280fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1281fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1282fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Expression: 1283fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (Expr *E = TAL.getSourceExpression()) 1284fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return Visit(MakeCXCursor(E, StmtParent, TU)); 1285fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1286fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1287fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Template: 12880b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return VisitTemplateName(TAL.getArgument().getAsTemplate(), 12890b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor TAL.getTemplateNameLoc()); 1290fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor } 1291fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1292fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1293fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1294fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1295a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenekbool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) { 1296a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek return VisitDeclContext(D); 1297a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek} 1298a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek 129901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { 130001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return Visit(TL.getUnqualifiedLoc()); 130101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor} 130201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 1303f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { 1304f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor ASTContext &Context = TU->getASTContext(); 1305f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1306f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor // Some builtin types (such as Objective-C's "id", "sel", and 1307f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor // "Class") have associated declarations. Create cursors for those. 1308f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor QualType VisitType; 1309f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor switch (TL.getType()->getAs<BuiltinType>()->getKind()) { 13106b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Void: 1311f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Bool: 13126b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Char_U: 13136b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UChar: 1314f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Char16: 1315f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Char32: 13166b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UShort: 13176b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UInt: 13186b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::ULong: 13196b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::ULongLong: 13206b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UInt128: 1321f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Char_S: 13226b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::SChar: 13236b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::WChar: 13246b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Short: 1325f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Int: 1326f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Long: 1327c4174cc4b9b657abb77d0825de473ea29cf48297Ted Kremenek case BuiltinType::LongLong: 13286b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Int128: 13296b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Float: 13306b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Double: 13316b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::LongDouble: 1332f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::NullPtr: 1333f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Overload: 13346b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Dependent: 1335f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor break; 13366b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek 13376b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UndeducedAuto: // FIXME: Deserves a cursor? 1338f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor break; 13396b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek 1340f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::ObjCId: 1341f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor VisitType = Context.getObjCIdType(); 1342f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor break; 13436b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek 13446b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::ObjCClass: 13456b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek VisitType = Context.getObjCClassType(); 13466b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek break; 13476b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek 1348f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::ObjCSel: 1349f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor VisitType = Context.getObjCSelType(); 1350f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor break; 1351f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor } 1352f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1353f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (!VisitType.isNull()) { 1354f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (const TypedefType *Typedef = VisitType->getAs<TypedefType>()) 1355f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), 1356f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor TU)); 1357f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor } 1358f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1359f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1360f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1361f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 13627d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorbool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) { 13637d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU)); 13647d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor} 13657d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 1366f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { 1367f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 1368f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1369f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1370f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) { 1371f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 1372f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1373f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1374fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { 13751f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor // FIXME: We can't visit the template type parameter, because there's 1376fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // no context information with which we can match up the depth/index in the 1377fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // type to the appropriate 1378fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1379fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1380fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1381f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { 1382f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU))) 1383f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1384f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1385c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall return false; 1386c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall} 1387c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall 1388c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCallbool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { 1389c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc())) 1390c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall return true; 1391c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall 1392f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { 1393f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I), 1394f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor TU))) 1395f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1396f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor } 1397f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1398f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1399f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1400f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1401f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { 1402c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall return Visit(TL.getPointeeLoc()); 1403f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1404f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1405f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) { 1406f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(TL.getPointeeLoc()); 1407f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1408f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1409f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { 1410f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(TL.getPointeeLoc()); 1411f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1412f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1413f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { 1414f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(TL.getPointeeLoc()); 1415f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1416f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1417f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { 1418f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return Visit(TL.getPointeeLoc()); 1419f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1420f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1421f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { 1422f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return Visit(TL.getPointeeLoc()); 1423f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1424f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 142501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL, 142601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor bool SkipResultType) { 142701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (!SkipResultType && Visit(TL.getResultLoc())) 1428f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1429f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1430f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 14315dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek if (Decl *D = TL.getArg(I)) 14325dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek if (Visit(MakeCXCursor(D, TU))) 14335dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek return true; 1434f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1435f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1436f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1437f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1438f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) { 1439f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Visit(TL.getElementLoc())) 1440f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1441f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1442f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Expr *Size = TL.getSizeExpr()) 1443f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(MakeCXCursor(Size, StmtParent, TU)); 1444f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1445f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1446f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1447f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1448fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateSpecializationTypeLoc( 1449fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor TemplateSpecializationTypeLoc TL) { 14500b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // Visit the template name. 14510b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor if (VisitTemplateName(TL.getTypePtr()->getTemplateName(), 14520b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor TL.getTemplateNameLoc())) 14530b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return true; 1454fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1455fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // Visit the template arguments. 1456fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 1457fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (VisitTemplateArgumentLoc(TL.getArgLoc(I))) 1458fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return true; 1459fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1460fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1461fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1462fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 14632332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregorbool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { 14642332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU)); 14652332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor} 14662332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor 14672332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregorbool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { 14682332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo()) 14692332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor return Visit(TSInfo->getTypeLoc()); 14702332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor 14712332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor return false; 14722332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor} 14732332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor 1474a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregorbool CursorVisitor::VisitStmt(Stmt *S) { 1475a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end(); 1476a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor Child != ChildEnd; ++Child) { 14770f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (Stmt *C = *Child) 14780f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (Visit(MakeCXCursor(C, StmtParent, TU))) 14790f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek return true; 1480a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor } 1481f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1482a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return false; 1483a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor} 1484a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor 1485a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregorbool CursorVisitor::VisitDeclStmt(DeclStmt *S) { 1486007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek bool isFirst = true; 1487a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); 1488a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor D != DEnd; ++D) { 1489007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (*D && Visit(MakeCXCursor(*D, TU, isFirst))) 1490a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return true; 1491007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek isFirst = false; 1492a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor } 1493f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1494a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return false; 1495a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor} 1496a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor 149736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregorbool CursorVisitor::VisitGotoStmt(GotoStmt *S) { 149836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return Visit(MakeCursorLabelRef(S->getLabel(), S->getLabelLoc(), TU)); 149936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor} 150036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 15018947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregorbool CursorVisitor::VisitDeclRefExpr(DeclRefExpr *E) { 15028947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor // Visit nested-name-specifier, if present. 15038947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor if (NestedNameSpecifier *Qualifier = E->getQualifier()) 15048947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) 15058947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor return true; 15068947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor 15078947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor // Visit declaration name. 15088947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor if (VisitDeclarationNameInfo(E->getNameInfo())) 15098947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor return true; 15108947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor 15118947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor // Visit explicitly-specified template arguments. 15128947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor if (E->hasExplicitTemplateArgs()) { 15138947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs(); 15148947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor for (TemplateArgumentLoc *Arg = Args.getTemplateArgs(), 15158947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor *ArgEnd = Arg + Args.NumTemplateArgs; 15168947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor Arg != ArgEnd; ++Arg) 15178947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor if (VisitTemplateArgumentLoc(*Arg)) 15188947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor return true; 15198947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor } 15208947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor 15218947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor return false; 15228947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor} 15238947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor 15243064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenekbool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) { 15253064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek if (D->isDefinition()) { 15263064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), 15273064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek E = D->bases_end(); I != E; ++I) { 15283064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU))) 15293064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return true; 15303064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 15313064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 15323064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek 15333064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return VisitTagDecl(D); 15343064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek} 15353064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek 15363064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek 15371ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenekbool CursorVisitor::VisitBlockExpr(BlockExpr *B) { 15381ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek return Visit(B->getBlockDecl()); 15391ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek} 15401ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek 15418ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregorbool CursorVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) { 15428ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor // Visit the type into which we're computing an offset. 15438ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (Visit(E->getTypeSourceInfo()->getTypeLoc())) 15448ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor return true; 15458ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor 15468ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor // Visit the components of the offsetof expression. 15478ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) { 15488ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor typedef OffsetOfExpr::OffsetOfNode OffsetOfNode; 15498ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor const OffsetOfNode &Node = E->getComponent(I); 15508ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor switch (Node.getKind()) { 15518ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor case OffsetOfNode::Array: 15528ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor if (Visit(MakeCXCursor(E->getIndexExpr(Node.getArrayExprIndex()), 15538ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor StmtParent, TU))) 15548ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor return true; 15558ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor break; 15568ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor 15578ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor case OffsetOfNode::Field: 15588ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor if (Visit(MakeCursorMemberRef(Node.getField(), Node.getRange().getEnd(), 15598ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor TU))) 15608ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor return true; 15618ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor break; 15628ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor 15638ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor case OffsetOfNode::Identifier: 15648ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor case OffsetOfNode::Base: 15658ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor continue; 15668ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor } 15678ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor } 15688ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 15698ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor return false; 15708ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor} 15718ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 1572336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregorbool CursorVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { 1573336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor if (E->isArgumentType()) { 1574336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor if (TypeSourceInfo *TSInfo = E->getArgumentTypeInfo()) 1575336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return Visit(TSInfo->getTypeLoc()); 1576f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1577336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return false; 1578336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor } 1579f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1580336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return VisitExpr(E); 1581336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor} 1582336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor 1583336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregorbool CursorVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) { 1584336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeInfoAsWritten()) 1585336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 1586336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return true; 1587f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1588336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return VisitCastExpr(E); 1589336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor} 1590336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor 159136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregorbool CursorVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) { 159236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return Visit(MakeCursorLabelRef(E->getLabel(), E->getLabelLoc(), TU)); 159336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor} 159436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 1595648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregorbool CursorVisitor::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) { 1596648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor return Visit(E->getArgTInfo1()->getTypeLoc()) || 1597648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor Visit(E->getArgTInfo2()->getTypeLoc()); 1598648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor} 1599648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor 1600648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregorbool CursorVisitor::VisitVAArgExpr(VAArgExpr *E) { 1601648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor if (Visit(E->getWrittenTypeInfo()->getTypeLoc())) 1602648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor return true; 1603648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor 1604648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor return Visit(MakeCXCursor(E->getSubExpr(), StmtParent, TU)); 1605648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor} 1606648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor 1607fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregorbool CursorVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) { 1608fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor // Visit the designators. 1609fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor typedef DesignatedInitExpr::Designator Designator; 1610fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor for (DesignatedInitExpr::designators_iterator D = E->designators_begin(), 1611fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor DEnd = E->designators_end(); 1612fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor D != DEnd; ++D) { 1613fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (D->isFieldDesignator()) { 1614fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (FieldDecl *Field = D->getField()) 1615fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (Visit(MakeCursorMemberRef(Field, D->getFieldLoc(), TU))) 1616fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor return true; 1617fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1618fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor continue; 1619fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor } 1620fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1621fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (D->isArrayDesignator()) { 1622fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (Visit(MakeCXCursor(E->getArrayIndex(*D), StmtParent, TU))) 1623fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor return true; 1624fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1625fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor continue; 1626fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor } 1627fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1628fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor assert(D->isArrayRangeDesignator() && "Unknown designator kind"); 1629fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (Visit(MakeCXCursor(E->getArrayRangeStart(*D), StmtParent, TU)) || 1630fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor Visit(MakeCXCursor(E->getArrayRangeEnd(*D), StmtParent, TU))) 1631fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor return true; 1632fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor } 1633fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1634fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor // Visit the initializer value itself. 1635fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor return Visit(MakeCXCursor(E->getInit(), StmtParent, TU)); 1636fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor} 1637fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1638948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregorbool CursorVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) { 1639948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor if (E->isTypeOperand()) { 1640948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeOperandSourceInfo()) 1641948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor return Visit(TSInfo->getTypeLoc()); 1642948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor 1643948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor return false; 1644948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor } 1645948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor 1646948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor return VisitExpr(E); 1647948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor} 1648948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor 16493d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregorbool CursorVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) { 16503d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor if (E->isTypeOperand()) { 16513d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeOperandSourceInfo()) 16523d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor return Visit(TSInfo->getTypeLoc()); 16533d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor 16543d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor return false; 16553d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor } 16563d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor 16573d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor return VisitExpr(E); 16583d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor} 16593d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor 1660ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregorbool CursorVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { 1661ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) 166240749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 166340749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor return true; 1664ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 1665ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor return VisitExpr(E); 1666ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor} 1667ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 1668ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregorbool CursorVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { 1669ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) 1670ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor return Visit(TSInfo->getTypeLoc()); 1671ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 1672ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor return false; 1673ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor} 1674ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 16751bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregorbool CursorVisitor::VisitCXXNewExpr(CXXNewExpr *E) { 16761bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor // Visit placement arguments. 16771bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) 16781bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor if (Visit(MakeCXCursor(E->getPlacementArg(I), StmtParent, TU))) 16791bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor return true; 16801bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor 16811bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor // Visit the allocated type. 16821bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor if (TypeSourceInfo *TSInfo = E->getAllocatedTypeSourceInfo()) 16831bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 16841bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor return true; 16851bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor 16861bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor // Visit the array size, if any. 16871bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor if (E->isArray() && Visit(MakeCXCursor(E->getArraySize(), StmtParent, TU))) 16881bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor return true; 16891bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor 16901bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor // Visit the initializer or constructor arguments. 16911bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) 16921bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor if (Visit(MakeCXCursor(E->getConstructorArg(I), StmtParent, TU))) 16931bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor return true; 16941bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor 16951bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor return false; 16961bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor} 16971bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor 16986f7198f6380581645f416dd48a0079f83d89e884Douglas Gregorbool CursorVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 16996f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor // Visit base expression. 17006f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (Visit(MakeCXCursor(E->getBase(), StmtParent, TU))) 17016f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor return true; 17026f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor 17036f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor // Visit the nested-name-specifier. 17046f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (NestedNameSpecifier *Qualifier = E->getQualifier()) 17056f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) 17066f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor return true; 17076f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor 17086f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor // Visit the scope type that looks disturbingly like the nested-name-specifier 17096f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor // but isn't. 17106f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (TypeSourceInfo *TSInfo = E->getScopeTypeInfo()) 17116f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 17126f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor return true; 17136f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor 17146f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor // Visit the name of the type being destroyed. 17156f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (TypeSourceInfo *TSInfo = E->getDestroyedTypeInfo()) 17166f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 17176f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor return true; 17186f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor 17196f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor return false; 17206f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor} 17216f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor 17223d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregorbool CursorVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { 17233d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor return Visit(E->getQueriedTypeSourceInfo()->getTypeLoc()); 17243d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor} 17253d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor 1726bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregorbool CursorVisitor::VisitDependentScopeDeclRefExpr( 1727bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor DependentScopeDeclRefExpr *E) { 1728bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor // Visit the nested-name-specifier. 1729bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor if (NestedNameSpecifier *Qualifier = E->getQualifier()) 1730bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) 1731bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor return true; 1732bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor 1733bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor // Visit the declaration name. 1734bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor if (VisitDeclarationNameInfo(E->getNameInfo())) 1735bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor return true; 1736bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor 1737bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor // Visit the explicitly-specified template arguments. 1738bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor if (const ExplicitTemplateArgumentList *ArgList 1739bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor = E->getOptionalExplicitTemplateArgs()) { 1740bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(), 1741bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor *ArgEnd = Arg + ArgList->NumTemplateArgs; 1742bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor Arg != ArgEnd; ++Arg) { 1743bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor if (VisitTemplateArgumentLoc(*Arg)) 1744bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor return true; 1745bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor } 1746bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor } 1747bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor 1748bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor return false; 1749bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor} 1750bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor 1751ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregorbool CursorVisitor::VisitCXXUnresolvedConstructExpr( 1752ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor CXXUnresolvedConstructExpr *E) { 1753ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) 1754ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 1755ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor return true; 1756ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 1757ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor return VisitExpr(E); 1758ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor} 1759ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 176025d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregorbool CursorVisitor::VisitCXXDependentScopeMemberExpr( 176125d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor CXXDependentScopeMemberExpr *E) { 176225d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor // Visit the base expression, if there is one. 176325d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (!E->isImplicitAccess() && 176425d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor Visit(MakeCXCursor(E->getBase(), StmtParent, TU))) 176525d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor return true; 176625d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor 176725d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor // Visit the nested-name-specifier. 176825d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (NestedNameSpecifier *Qualifier = E->getQualifier()) 176925d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) 177025d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor return true; 177125d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor 177225d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor // Visit the declaration name. 177325d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (VisitDeclarationNameInfo(E->getMemberNameInfo())) 177425d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor return true; 177525d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor 177625d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor // Visit the explicitly-specified template arguments. 177725d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (const ExplicitTemplateArgumentList *ArgList 177825d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor = E->getOptionalExplicitTemplateArgs()) { 177925d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(), 178025d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor *ArgEnd = Arg + ArgList->NumTemplateArgs; 178125d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor Arg != ArgEnd; ++Arg) { 178225d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (VisitTemplateArgumentLoc(*Arg)) 178325d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor return true; 178425d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor } 178525d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor } 178625d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor 178725d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor return false; 178825d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor} 178925d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor 1790c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregorbool CursorVisitor::VisitObjCMessageExpr(ObjCMessageExpr *E) { 179104badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor if (TypeSourceInfo *TSInfo = E->getClassReceiverTypeInfo()) 179204badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 179304badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor return true; 1794c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregor 1795c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregor return VisitExpr(E); 1796c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregor} 1797c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregor 179881d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregorbool CursorVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { 179981d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor return Visit(E->getEncodedTypeSourceInfo()->getTypeLoc()); 180081d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor} 180181d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor 180281d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor 180309dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenekbool CursorVisitor::VisitAttributes(Decl *D) { 1804cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end(); 1805cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) 1806cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (Visit(MakeCXCursor(*i, D, TU))) 180709dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek return true; 180809dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek 180909dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek return false; 181009dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek} 181109dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek 1812c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===// 1813c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek// Data-recursive visitor methods. 1814c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===// 1815c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 1816a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenekstatic void EnqueueChildren(VisitorWorkList &WL, CXCursor Parent, Stmt *S) { 1817a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek unsigned size = WL.size(); 1818a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end(); 1819a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek Child != ChildEnd; ++Child) { 1820a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek WLAddStmt(WL, Parent, *Child); 1821a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek } 1822a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek if (size == WL.size()) 1823a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek return; 1824a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek // Now reverse the entries we just added. This will match the DFS 1825a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek // ordering performed by the worklist. 1826a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek VisitorWorkList::iterator I = WL.begin() + size, E = WL.end(); 1827a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek std::reverse(I, E); 1828a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek} 1829a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek 18306045878f1fa7fad19d826634617991db99d3bd22Ted Kremenekstatic void EnqueueOverloadExpr(VisitorWorkList &WL, CXCursor Parent, 18316045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek OverloadExpr *E) { 18326045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek WL.push_back(OverloadExprParts(E, Parent)); 18336045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek} 18346045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek 1835c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekvoid CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) { 1836c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek CXCursor C = MakeCXCursor(S, StmtParent, TU); 1837c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek switch (S->getStmtClass()) { 1838a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek default: 1839a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek EnqueueChildren(WL, C, S); 1840c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek break; 1841cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek case Stmt::CompoundLiteralExprClass: { 1842cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek CompoundLiteralExpr *CL = cast<CompoundLiteralExpr>(S); 1843cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek EnqueueChildren(WL, C, CL); 1844cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek WLAddTypeLoc(WL, C, CL->getTypeSourceInfo()); 1845cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek break; 1846cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek } 1847f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek case Stmt::CXXOperatorCallExprClass: { 1848f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek CXXOperatorCallExpr *CE = cast<CXXOperatorCallExpr>(S); 1849f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek // Note that we enqueue things in reverse order so that 1850f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek // they are visited correctly by the DFS. 1851f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek for (unsigned I = 1, N = CE->getNumArgs(); I != N; ++I) 1852ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek WLAddStmt(WL, C, CE->getArg(N-I)); 1853f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek 1854ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek WLAddStmt(WL, C, CE->getCallee()); 1855ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek WLAddStmt(WL, C, CE->getArg(0)); 1856c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek break; 1857c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 1858c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case Stmt::BinaryOperatorClass: { 1859c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek BinaryOperator *B = cast<BinaryOperator>(S); 1860ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek WLAddStmt(WL, C, B->getRHS()); 1861ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek WLAddStmt(WL, C, B->getLHS()); 1862c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek break; 1863c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 1864bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek case Stmt::ForStmtClass: { 1865bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek ForStmt *FS = cast<ForStmt>(S); 1866bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek WLAddStmt(WL, C, FS->getBody()); 1867bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek WLAddStmt(WL, C, FS->getInc()); 1868bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek WLAddStmt(WL, C, FS->getCond()); 1869bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek WLAddDecl(WL, C, FS->getConditionVariable()); 1870bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek WLAddStmt(WL, C, FS->getInit()); 1871bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek break; 1872bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek } 1873c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek case Stmt::IfStmtClass: { 1874c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek IfStmt *If = cast<IfStmt>(S); 1875c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek WLAddStmt(WL, C, If->getElse()); 1876c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek WLAddStmt(WL, C, If->getThen()); 1877c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek WLAddStmt(WL, C, If->getCond()); 1878ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek WLAddDecl(WL, C, If->getConditionVariable()); 1879c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek break; 1880c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek } 1881a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek case Stmt::InitListExprClass: { 1882a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek InitListExpr *IE = cast<InitListExpr>(S); 1883a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek // We care about the syntactic form of the initializer list, only. 1884a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek if (InitListExpr *Syntactic = IE->getSyntacticForm()) 1885a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek IE = Syntactic; 1886a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek EnqueueChildren(WL, C, IE); 1887a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek break; 1888a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek } 1889c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case Stmt::MemberExprClass: { 1890c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek MemberExpr *M = cast<MemberExpr>(S); 1891c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek WL.push_back(MemberExprParts(M, C)); 1892ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek WLAddStmt(WL, C, M->getBase()); 1893c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek break; 1894c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 1895f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek case Stmt::ParenExprClass: { 1896ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek WLAddStmt(WL, C, cast<ParenExpr>(S)->getSubExpr()); 1897f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek break; 1898f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek } 1899f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek case Stmt::SwitchStmtClass: { 1900f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek SwitchStmt *SS = cast<SwitchStmt>(S); 1901ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek WLAddStmt(WL, C, SS->getBody()); 1902ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek WLAddStmt(WL, C, SS->getCond()); 1903ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek WLAddDecl(WL, C, SS->getConditionVariable()); 19048c269ac75569454a049385b1246140db5f2b6faaTed Kremenek break; 19058c269ac75569454a049385b1246140db5f2b6faaTed Kremenek } 1906bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek case Stmt::WhileStmtClass: { 1907bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek WhileStmt *W = cast<WhileStmt>(S); 1908bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek WLAddStmt(WL, C, W->getBody()); 1909bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek WLAddStmt(WL, C, W->getCond()); 1910bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek WLAddDecl(WL, C, W->getConditionVariable()); 1911bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek break; 1912bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek } 19136045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek case Stmt::UnresolvedLookupExprClass: 19146045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek EnqueueOverloadExpr(WL, C, cast<OverloadExpr>(S)); 19156045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek break; 19166045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek case Stmt::UnresolvedMemberExprClass: { 19176045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek UnresolvedMemberExpr *U = cast<UnresolvedMemberExpr>(S); 19186045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek EnqueueOverloadExpr(WL, C, U); 19196045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek if (!U->isImplicitAccess()) 19206045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek WLAddStmt(WL, C, U->getBase()); 19216045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek break; 19226045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek } 1923c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 1924c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek} 1925c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 1926c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekbool CursorVisitor::IsInRegionOfInterest(CXCursor C) { 1927c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (RegionOfInterest.isValid()) { 1928c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek SourceRange Range = getRawCursorExtent(C); 1929c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (Range.isInvalid() || CompareRegionOfInterest(Range)) 1930c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return false; 1931c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 1932c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return true; 1933c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek} 1934c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 1935c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekbool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { 1936c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek while (!WL.empty()) { 1937c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Dequeue the worklist item. 1938c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek VisitorJob LI = WL.back(); WL.pop_back(); 1939c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 1940c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Set the Parent field, then back to its old value once we're done. 1941c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek SetParentRAII SetParent(Parent, StmtParent, LI.getParent()); 1942c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 1943c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek switch (LI.getKind()) { 1944f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek case VisitorJob::DeclVisitKind: { 1945f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek Decl *D = cast<DeclVisit>(LI).get(); 1946f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek if (!D) 1947f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek continue; 1948f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek 1949f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek // For now, perform default visitation for Decls. 1950f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek if (Visit(MakeCXCursor(D, TU))) 1951f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek return true; 1952f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek 1953f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek continue; 1954f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek } 1955cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek case VisitorJob::TypeLocVisitKind: { 1956cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek // Perform default visitation for TypeLocs. 1957cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek if (Visit(cast<TypeLocVisit>(LI).get())) 1958cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek return true; 1959cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek continue; 1960cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek } 1961c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case VisitorJob::StmtVisitKind: { 1962c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek Stmt *S = cast<StmtVisit>(LI).get(); 19638c269ac75569454a049385b1246140db5f2b6faaTed Kremenek if (!S) 19648c269ac75569454a049385b1246140db5f2b6faaTed Kremenek continue; 19658c269ac75569454a049385b1246140db5f2b6faaTed Kremenek 1966f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek // Update the current cursor. 1967c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek CXCursor Cursor = MakeCXCursor(S, StmtParent, TU); 1968c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 1969c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek switch (S->getStmtClass()) { 1970c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek default: { 1971c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Perform default visitation for other cases. 1972c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (Visit(Cursor)) 1973c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return true; 1974c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek continue; 1975c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 1976f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek case Stmt::BinaryOperatorClass: 1977c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case Stmt::CallExprClass: 1978f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek case Stmt::CaseStmtClass: 1979cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek case Stmt::CompoundLiteralExprClass: 1980f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek case Stmt::CompoundStmtClass: 1981c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case Stmt::CXXMemberCallExprClass: 19828c269ac75569454a049385b1246140db5f2b6faaTed Kremenek case Stmt::CXXOperatorCallExprClass: 1983f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek case Stmt::DefaultStmtClass: 1984bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek case Stmt::DoStmtClass: 1985bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek case Stmt::ForStmtClass: 1986c70ebba0e164abee26e6e1dbbe71c777f8f461a0Ted Kremenek case Stmt::IfStmtClass: 1987a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek case Stmt::InitListExprClass: 1988c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case Stmt::MemberExprClass: 1989f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek case Stmt::ParenExprClass: 1990f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek case Stmt::SwitchStmtClass: 1991ae3c220fddb65b63ede3533bbdeed8ac7dcd1b0dTed Kremenek case Stmt::UnaryOperatorClass: 19926045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek case Stmt::UnresolvedLookupExprClass: 19936045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek case Stmt::UnresolvedMemberExprClass: 1994bb67713d5075690d9b0d0a97cf19529f668c2e3fTed Kremenek case Stmt::WhileStmtClass: 1995f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek { 1996c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (!IsInRegionOfInterest(Cursor)) 1997c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek continue; 1998c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek switch (Visitor(Cursor, Parent, ClientData)) { 1999c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case CXChildVisit_Break: 2000c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return true; 2001c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case CXChildVisit_Continue: 2002c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek break; 2003c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case CXChildVisit_Recurse: 2004c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek EnqueueWorkList(WL, S); 2005c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek break; 2006c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2007c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2008c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2009c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek continue; 2010c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2011c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case VisitorJob::MemberExprPartsKind: { 2012c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Handle the other pieces in the MemberExpr besides the base. 2013c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek MemberExpr *M = cast<MemberExprParts>(LI).get(); 2014c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2015c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Visit the nested-name-specifier 2016c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (NestedNameSpecifier *Qualifier = M->getQualifier()) 2017c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (VisitNestedNameSpecifier(Qualifier, M->getQualifierRange())) 2018c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return true; 2019c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2020c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Visit the declaration name. 2021c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (VisitDeclarationNameInfo(M->getMemberNameInfo())) 2022c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return true; 2023c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2024c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Visit the explicitly-specified template arguments, if any. 2025c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (M->hasExplicitTemplateArgs()) { 2026c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(), 2027c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek *ArgEnd = Arg + M->getNumTemplateArgs(); 2028c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek Arg != ArgEnd; ++Arg) { 2029c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (VisitTemplateArgumentLoc(*Arg)) 2030c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return true; 2031c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2032c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2033c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek continue; 2034c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 20356045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek case VisitorJob::OverloadExprPartsKind: { 20366045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek OverloadExpr *O = cast<OverloadExprParts>(LI).get(); 20376045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek // Visit the nested-name-specifier. 20386045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek if (NestedNameSpecifier *Qualifier = O->getQualifier()) 20396045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek if (VisitNestedNameSpecifier(Qualifier, O->getQualifierRange())) 20406045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek return true; 20416045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek // Visit the declaration name. 20426045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek if (VisitDeclarationNameInfo(O->getNameInfo())) 20436045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek return true; 20446045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek // Visit the overloaded declaration reference. 20456045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek if (Visit(MakeCursorOverloadedDeclRef(O, TU))) 20466045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek return true; 20476045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek // Visit the explicitly-specified template arguments. 20486045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek if (const ExplicitTemplateArgumentList *ArgList 20496045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek = O->getOptionalExplicitTemplateArgs()) { 20506045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(), 20516045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek *ArgEnd = Arg + ArgList->NumTemplateArgs; 20526045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek Arg != ArgEnd; ++Arg) { 20536045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek if (VisitTemplateArgumentLoc(*Arg)) 20546045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek return true; 20556045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek } 20566045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek } 20576045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek continue; 20586045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek } 2059c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2060c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2061c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return false; 2062c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek} 2063c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2064c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekbool CursorVisitor::VisitDataRecursive(Stmt *S) { 2065c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek VisitorWorkList WL; 2066c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek EnqueueWorkList(WL, S); 2067c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return RunVisitorWorkList(WL); 2068c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek} 2069c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2070c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===// 2071c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek// Misc. API hooks. 2072c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===// 2073c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 20748c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregorstatic llvm::sys::Mutex EnableMultithreadingMutex; 20758c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregorstatic bool EnabledMultithreading; 20768c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor 20775e4bc590b0ea010e38372d0b4a0aab578a746fe6Benjamin Kramerextern "C" { 20780a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas GregorCXIndex clang_createIndex(int excludeDeclarationsFromPCH, 20790a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor int displayDiagnostics) { 208048615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar // Disable pretty stack trace functionality, which will otherwise be a very 208148615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar // poor citizen of the world and set up all sorts of signal handlers. 208248615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar llvm::DisablePrettyStackTrace = true; 208348615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar 2084c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar // We use crash recovery to make some of our APIs more reliable, implicitly 2085c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar // enable it. 2086c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar llvm::CrashRecoveryContext::Enable(); 2087c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar 20888c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor // Enable support for multithreading in LLVM. 20898c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor { 20908c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor llvm::sys::ScopedLock L(EnableMultithreadingMutex); 20918c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor if (!EnabledMultithreading) { 20928c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor llvm::llvm_start_multithreaded(); 20938c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor EnabledMultithreading = true; 20948c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor } 20958c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor } 20968c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor 2097a030b7cf5e6aad5889b1b662b6979840bc75f87fDouglas Gregor CIndexer *CIdxr = new CIndexer(); 2098e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff if (excludeDeclarationsFromPCH) 2099e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff CIdxr->setOnlyLocalDecls(); 21000a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor if (displayDiagnostics) 21010a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor CIdxr->setDisplayDiagnostics(); 2102e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff return CIdxr; 2103600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff} 2104600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff 21059ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarvoid clang_disposeIndex(CXIndex CIdx) { 21062b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (CIdx) 21072b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor delete static_cast<CIndexer *>(CIdx); 21082bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff} 21092bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff 21109ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXTranslationUnit clang_createTranslationUnit(CXIndex CIdx, 2111a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor const char *ast_filename) { 21122b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (!CIdx) 21132b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor return 0; 2114f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 21157d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); 2116389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis FileSystemOptions FileSystemOpts; 2117389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory(); 21180d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 211928019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags; 2120389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis return ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts, 2121a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor CXXIdx->getOnlyLocalDecls(), 2122a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 0, 0, true); 2123600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff} 2124600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff 2125b1c031be513705d924038f497279b9b599868ba1Douglas Gregorunsigned clang_defaultEditingTranslationUnitOptions() { 21262a2c50b330e7754499f42173616a36865b5f313bDouglas Gregor return CXTranslationUnit_PrecompiledPreamble | 212799ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor CXTranslationUnit_CacheCompletionResults | 212899ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor CXTranslationUnit_CXXPrecompiledPreamble; 2129b1c031be513705d924038f497279b9b599868ba1Douglas Gregor} 2130b1c031be513705d924038f497279b9b599868ba1Douglas Gregor 21319ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXTranslationUnit 21329ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarclang_createTranslationUnitFromSourceFile(CXIndex CIdx, 21339ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar const char *source_filename, 21349ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar int num_command_line_args, 21352ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char * const *command_line_args, 21364db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor unsigned num_unsaved_files, 2137a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor struct CXUnsavedFile *unsaved_files) { 21385a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor return clang_parseTranslationUnit(CIdx, source_filename, 21395a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor command_line_args, num_command_line_args, 21405a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor unsaved_files, num_unsaved_files, 21415a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor CXTranslationUnit_DetailedPreprocessingRecord); 21425a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor} 214319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar 214419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbarstruct ParseTranslationUnitInfo { 214519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar CXIndex CIdx; 214619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar const char *source_filename; 21472ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char *const *command_line_args; 214819ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar int num_command_line_args; 214919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar struct CXUnsavedFile *unsaved_files; 215019ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned num_unsaved_files; 215119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned options; 215219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar CXTranslationUnit result; 215319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar}; 2154b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarstatic void clang_parseTranslationUnit_Impl(void *UserData) { 215519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar ParseTranslationUnitInfo *PTUI = 215619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar static_cast<ParseTranslationUnitInfo*>(UserData); 215719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar CXIndex CIdx = PTUI->CIdx; 215819ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar const char *source_filename = PTUI->source_filename; 21592ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char * const *command_line_args = PTUI->command_line_args; 216019ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar int num_command_line_args = PTUI->num_command_line_args; 216119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files; 216219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned num_unsaved_files = PTUI->num_unsaved_files; 216319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned options = PTUI->options; 216419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar PTUI->result = 0; 21655a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor 21662b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (!CIdx) 216719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar return; 2168f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2169e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); 2170e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff 217144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble; 2172df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool CompleteTranslationUnit 2173df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor = ((options & CXTranslationUnit_Incomplete) == 0); 217487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor bool CacheCodeCompetionResults 217587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor = options & CXTranslationUnit_CacheCompletionResults; 217699ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor bool CXXPrecompilePreamble 217799ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor = options & CXTranslationUnit_CXXPrecompiledPreamble; 217899ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor bool CXXChainedPCH 217999ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor = options & CXTranslationUnit_CXXChainedPCH; 218087c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 21815352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor // Configure the diagnostics. 21825352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor DiagnosticOptions DiagOpts; 218328019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags; 218428019772db70d4547be05a042eb950bc910f134fDouglas Gregor Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); 2185f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 21864db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; 21874db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != num_unsaved_files; ++I) { 2188a0a270c0f1c0a4e3482438bdc5f4a7bd3d25f0a6Chris Lattner llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); 2189f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek const llvm::MemoryBuffer *Buffer 2190a0a270c0f1c0a4e3482438bdc5f4a7bd3d25f0a6Chris Lattner = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); 21914db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, 21924db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor Buffer)); 21934db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 2194f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2195b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor llvm::SmallVector<const char *, 16> Args; 21960d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 2197139ba86a362593da2e350f881e5c7003917aa5a7Ted Kremenek // The 'source_filename' argument is optional. If the caller does not 2198139ba86a362593da2e350f881e5c7003917aa5a7Ted Kremenek // specify it then it is assumed that the source file is specified 2199139ba86a362593da2e350f881e5c7003917aa5a7Ted Kremenek // in the actual argument list. 22000d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar if (source_filename) 2201b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Args.push_back(source_filename); 220252ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor 220352ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // Since the Clang C library is primarily used by batch tools dealing with 220452ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // (often very broken) source code, where spell-checking can have a 220552ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // significant negative impact on performance (particularly when 220652ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // precompiled headers are involved), we disable it by default. 2207b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // Only do this if we haven't found a spell-checking-related argument. 2208b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor bool FoundSpellCheckingArgument = false; 2209b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor for (int I = 0; I != num_command_line_args; ++I) { 2210b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 || 2211b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor strcmp(command_line_args[I], "-fspell-checking") == 0) { 2212b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor FoundSpellCheckingArgument = true; 2213b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor break; 2214e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff } 2215b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor } 2216b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor if (!FoundSpellCheckingArgument) 2217b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Args.push_back("-fno-spell-checking"); 2218b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor 2219b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Args.insert(Args.end(), command_line_args, 2220b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor command_line_args + num_command_line_args); 2221d93256e55673a17d18543397ec462416acb13792Douglas Gregor 222244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Do we need the detailed preprocessing record? 222344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (options & CXTranslationUnit_DetailedPreprocessingRecord) { 2224b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Args.push_back("-Xclang"); 2225b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Args.push_back("-detailed-preprocessing-record"); 222644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 222744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 2228b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor unsigned NumErrors = Diags->getNumErrors(); 2229b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor llvm::OwningPtr<ASTUnit> Unit( 2230b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(), 2231b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Diags, 2232b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXXIdx->getClangResourcesPath(), 2233b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXXIdx->getOnlyLocalDecls(), 2234e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor /*CaptureDiagnostics=*/true, 2235b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor RemappedFiles.data(), 2236b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor RemappedFiles.size(), 2237b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor PrecompilePreamble, 2238b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CompleteTranslationUnit, 223999ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor CacheCodeCompetionResults, 224099ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor CXXPrecompilePreamble, 224199ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor CXXChainedPCH)); 2242b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor 2243b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor if (NumErrors != Diags->getNumErrors()) { 2244b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // Make sure to check that 'Unit' is non-NULL. 2245b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor if (CXXIdx->getDisplayDiagnostics() && Unit.get()) { 2246b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), 2247b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor DEnd = Unit->stored_diag_end(); 2248b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor D != DEnd; ++D) { 2249b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions()); 2250b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXString Msg = clang_formatDiagnostic(&Diag, 2251b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor clang_defaultDiagnosticDisplayOptions()); 2252b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor fprintf(stderr, "%s\n", clang_getCString(Msg)); 2253b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor clang_disposeString(Msg); 2254b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor } 2255274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor#ifdef LLVM_ON_WIN32 2256b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // On Windows, force a flush, since there may be multiple copies of 2257b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // stderr and stdout in the file system, all with different buffers 2258b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // but writing to the same device. 2259b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor fflush(stderr); 2260b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor#endif 2261b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor } 2262a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 2263d93256e55673a17d18543397ec462416acb13792Douglas Gregor 2264b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor PTUI->result = Unit.take(); 226519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar} 226619ffd492a31a25fb691098bf79f317e5f3edf177Daniel DunbarCXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, 226719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar const char *source_filename, 22682ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char * const *command_line_args, 226919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar int num_command_line_args, 22709e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar struct CXUnsavedFile *unsaved_files, 227119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned num_unsaved_files, 227219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned options) { 227319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args, 22749e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar num_command_line_args, unsaved_files, 22759e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar num_unsaved_files, options, 0 }; 227619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar llvm::CrashRecoveryContext CRC; 227719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar 2278bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) { 227960a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "libclang: crash detected during parsing: {\n"); 228060a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'source_filename' : '%s'\n", source_filename); 228160a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'command_line_args' : ["); 228260a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar for (int i = 0; i != num_command_line_args; ++i) { 228360a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar if (i) 228460a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, ", "); 228560a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "'%s'", command_line_args[i]); 228660a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar } 228760a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "],\n"); 228860a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'unsaved_files' : ["); 228960a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar for (unsigned i = 0; i != num_unsaved_files; ++i) { 229060a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar if (i) 229160a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, ", "); 229260a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename, 229360a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar unsaved_files[i].Length); 229460a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar } 229560a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "],\n"); 229660a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'options' : %d,\n", options); 229760a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "}\n"); 229860a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar 229919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar return 0; 230019ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar } 230119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar 230219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar return PTUI.result; 23035b7d8e254f6c2855b37b5521c0aee0a560dab237Steve Naroff} 23045b7d8e254f6c2855b37b5521c0aee0a560dab237Steve Naroff 23051999844e7a18786e61e619e1dc6c789827541863Douglas Gregorunsigned clang_defaultSaveOptions(CXTranslationUnit TU) { 23061999844e7a18786e61e619e1dc6c789827541863Douglas Gregor return CXSaveTranslationUnit_None; 23071999844e7a18786e61e619e1dc6c789827541863Douglas Gregor} 23081999844e7a18786e61e619e1dc6c789827541863Douglas Gregor 23091999844e7a18786e61e619e1dc6c789827541863Douglas Gregorint clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName, 23101999844e7a18786e61e619e1dc6c789827541863Douglas Gregor unsigned options) { 23117ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor if (!TU) 23127ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor return 1; 23137ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 23147ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor return static_cast<ASTUnit *>(TU)->Save(FileName); 23157ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor} 231619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar 23179ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarvoid clang_disposeTranslationUnit(CXTranslationUnit CTUnit) { 2318ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar if (CTUnit) { 2319ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar // If the translation unit has been marked as unsafe to free, just discard 2320ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar // it. 2321ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar if (static_cast<ASTUnit *>(CTUnit)->isUnsafeToFree()) 2322ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return; 2323ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 23242b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor delete static_cast<ASTUnit *>(CTUnit); 2325ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar } 23262bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff} 23270d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 2328e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregorunsigned clang_defaultReparseOptions(CXTranslationUnit TU) { 2329e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor return CXReparse_None; 2330e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor} 2331e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor 2332ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbarstruct ReparseTranslationUnitInfo { 2333ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar CXTranslationUnit TU; 2334ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned num_unsaved_files; 2335ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar struct CXUnsavedFile *unsaved_files; 2336ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned options; 2337ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar int result; 2338ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar}; 2339593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor 2340b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarstatic void clang_reparseTranslationUnit_Impl(void *UserData) { 2341ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar ReparseTranslationUnitInfo *RTUI = 2342ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar static_cast<ReparseTranslationUnitInfo*>(UserData); 2343ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar CXTranslationUnit TU = RTUI->TU; 2344ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned num_unsaved_files = RTUI->num_unsaved_files; 2345ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files; 2346ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned options = RTUI->options; 2347ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar (void) options; 2348ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar RTUI->result = 1; 2349ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 2350abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor if (!TU) 2351ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return; 2352593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor 2353593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 2354593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor ASTUnit::ConcurrencyCheck Check(*CXXUnit); 2355abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 2356abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; 2357abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor for (unsigned I = 0; I != num_unsaved_files; ++I) { 2358abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); 2359abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor const llvm::MemoryBuffer *Buffer 23601abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); 2361abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, 2362abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Buffer)); 2363abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor } 2364abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 2365593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor if (!CXXUnit->Reparse(RemappedFiles.data(), RemappedFiles.size())) 2366593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor RTUI->result = 0; 2367abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 2368593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor 2369ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbarint clang_reparseTranslationUnit(CXTranslationUnit TU, 2370ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned num_unsaved_files, 2371ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar struct CXUnsavedFile *unsaved_files, 2372ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned options) { 2373ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files, 2374ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar options, 0 }; 2375ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar llvm::CrashRecoveryContext CRC; 2376ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 2377bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) { 2378b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar fprintf(stderr, "libclang: crash detected during reparsing\n"); 2379ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar static_cast<ASTUnit *>(TU)->setUnsafeToFree(true); 2380ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return 1; 2381ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar } 2382ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 23831dfb26af4d6aa4f7818e256659a79f1ec2cba784Ted Kremenek 2384ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return RTUI.result; 2385ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar} 2386ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 2387df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 23889ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) { 23892b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (!CTUnit) 2390ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 2391f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 239277accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroff ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit); 2393ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(CXXUnit->getOriginalSourceFileName(), true); 2394af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff} 23951eb79b58e56b99cf557d5d353586a10c5360364dDaniel Dunbar 23967eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas GregorCXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) { 2397b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } }; 23987eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor return Result; 23997eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor} 24007eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor 2401fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C" 2402600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff 2403fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 24041db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor// CXSourceLocation and CXSourceRange Operations. 24051db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor//===----------------------------------------------------------------------===// 24061db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 2407b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregorextern "C" { 2408b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceLocation clang_getNullLocation() { 24095352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor CXSourceLocation Result = { { 0, 0 }, 0 }; 2410b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return Result; 2411b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2412b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 2413b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregorunsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) { 241490a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar return (loc1.ptr_data[0] == loc2.ptr_data[0] && 241590a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar loc1.ptr_data[1] == loc2.ptr_data[1] && 241690a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar loc1.int_data == loc2.int_data); 2417b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2418b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 2419b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceLocation clang_getLocation(CXTranslationUnit tu, 2420b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor CXFile file, 2421b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor unsigned line, 2422b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor unsigned column) { 242342748ec5cb2d75fe0dbb3a6db5aee6c11b5dc190Douglas Gregor if (!tu || !file) 2424b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return clang_getNullLocation(); 242542748ec5cb2d75fe0dbb3a6db5aee6c11b5dc190Douglas Gregor 2426b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); 2427b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor SourceLocation SLoc 2428b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor = CXXUnit->getSourceManager().getLocation( 2429f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek static_cast<const FileEntry *>(file), 2430b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor line, column); 243183889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall if (SLoc.isInvalid()) return clang_getNullLocation(); 243283889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 243383889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc); 243483889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall} 243583889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 243683889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid ChisnallCXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu, 243783889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall CXFile file, 243883889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall unsigned offset) { 243983889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall if (!tu || !file) 244083889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall return clang_getNullLocation(); 244183889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 244283889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); 244383889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall SourceLocation Start 244483889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall = CXXUnit->getSourceManager().getLocation( 244583889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall static_cast<const FileEntry *>(file), 244683889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 1, 1); 244783889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall if (Start.isInvalid()) return clang_getNullLocation(); 244883889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 244983889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall SourceLocation SLoc = Start.getFileLocWithOffset(offset); 245083889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 245183889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall if (SLoc.isInvalid()) return clang_getNullLocation(); 2452f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 24531a9a0bc472ee4fec72ee8be8b575fb66ca600d1bTed Kremenek return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc); 2454b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2455b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 24565352ac06d8f6194825bb2a99ffa009b61bafb503Douglas GregorCXSourceRange clang_getNullRange() { 24575352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor CXSourceRange Result = { { 0, 0 }, 0, 0 }; 24585352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return Result; 24595352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor} 2460d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar 2461b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) { 24625352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor if (begin.ptr_data[0] != end.ptr_data[0] || 24635352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor begin.ptr_data[1] != end.ptr_data[1]) 24645352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullRange(); 2465f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2466f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] }, 24675352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor begin.int_data, end.int_data }; 2468b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return Result; 2469b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2470b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 247146766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregorvoid clang_getInstantiationLocation(CXSourceLocation location, 247246766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor CXFile *file, 247346766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor unsigned *line, 247446766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor unsigned *column, 247546766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor unsigned *offset) { 24761db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data); 24771db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 2478bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar if (!location.ptr_data[0] || Loc.isInvalid()) { 247946766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor if (file) 248046766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor *file = 0; 248146766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor if (line) 248246766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor *line = 0; 248346766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor if (column) 248446766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor *column = 0; 248546766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor if (offset) 248646766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor *offset = 0; 248746766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor return; 248846766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor } 248946766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor 2490bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar const SourceManager &SM = 2491bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar *static_cast<const SourceManager*>(location.ptr_data[0]); 24921db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor SourceLocation InstLoc = SM.getInstantiationLoc(Loc); 24931db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 24941db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor if (file) 24951db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc)); 24961db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor if (line) 24971db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor *line = SM.getInstantiationLineNumber(InstLoc); 24981db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor if (column) 24991db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor *column = SM.getInstantiationColumnNumber(InstLoc); 2500e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor if (offset) 250146766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor *offset = SM.getDecomposedLoc(InstLoc).second; 2502e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor} 2503e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor 2504a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregorvoid clang_getSpellingLocation(CXSourceLocation location, 2505a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor CXFile *file, 2506a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor unsigned *line, 2507a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor unsigned *column, 2508a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor unsigned *offset) { 2509a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data); 2510a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor 2511a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (!location.ptr_data[0] || Loc.isInvalid()) { 2512a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (file) 2513a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *file = 0; 2514a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (line) 2515a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *line = 0; 2516a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (column) 2517a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *column = 0; 2518a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (offset) 2519a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *offset = 0; 2520a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor return; 2521a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor } 2522a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor 2523a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor const SourceManager &SM = 2524a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *static_cast<const SourceManager*>(location.ptr_data[0]); 2525a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor SourceLocation SpellLoc = Loc; 2526a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (SpellLoc.isMacroID()) { 2527a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc); 2528a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (SimpleSpellingLoc.isFileID() && 2529a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first)) 2530a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor SpellLoc = SimpleSpellingLoc; 2531a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor else 2532a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor SpellLoc = SM.getInstantiationLoc(SpellLoc); 2533a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor } 2534a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor 2535a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc); 2536a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor FileID FID = LocInfo.first; 2537a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor unsigned FileOffset = LocInfo.second; 2538a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor 2539a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (file) 2540a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *file = (void *)SM.getFileEntryForID(FID); 2541a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (line) 2542a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *line = SM.getLineNumber(FID, FileOffset); 2543a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (column) 2544a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *column = SM.getColumnNumber(FID, FileOffset); 2545a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (offset) 2546a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *offset = FileOffset; 2547a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor} 2548a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor 25491db19dea8d221f27be46332d668d1e2decb7f1abDouglas GregorCXSourceLocation clang_getRangeStart(CXSourceRange range) { 2550f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, 25515352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor range.begin_int_data }; 25521db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor return Result; 25531db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor} 25541db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 25551db19dea8d221f27be46332d668d1e2decb7f1abDouglas GregorCXSourceLocation clang_getRangeEnd(CXSourceRange range) { 2556bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, 25575352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor range.end_int_data }; 25581db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor return Result; 25591db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor} 25601db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 2561b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} // end: extern "C" 2562b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 25631db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor//===----------------------------------------------------------------------===// 2564fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek// CXFile Operations. 2565fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 2566fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 2567fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekextern "C" { 256874844072411bae91d5dbb89955d200cbe1e0a1c8Ted KremenekCXString clang_getFileName(CXFile SFile) { 256998258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor if (!SFile) 257074844072411bae91d5dbb89955d200cbe1e0a1c8Ted Kremenek return createCXString(NULL); 2571f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 257288145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff FileEntry *FEnt = static_cast<FileEntry *>(SFile); 257374844072411bae91d5dbb89955d200cbe1e0a1c8Ted Kremenek return createCXString(FEnt->getName()); 257488145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff} 257588145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff 257688145034694ed5267fa6fa5febc54fadc02bd479Steve Narofftime_t clang_getFileTime(CXFile SFile) { 257798258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor if (!SFile) 257898258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor return 0; 2579f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 258088145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff FileEntry *FEnt = static_cast<FileEntry *>(SFile); 258188145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff return FEnt->getModificationTime(); 2582ee9405e807d7c447c0143c2bd865b759192e97b3Steve Naroff} 2583f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2584b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXFile clang_getFile(CXTranslationUnit tu, const char *file_name) { 2585b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor if (!tu) 2586b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return 0; 2587f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2588b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); 2589f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2590b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor FileManager &FMgr = CXXUnit->getFileManager(); 2591389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis const FileEntry *File = FMgr.getFile(file_name, file_name+strlen(file_name), 2592389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis CXXUnit->getFileSystemOpts()); 2593b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return const_cast<FileEntry *>(File); 2594b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2595f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2596fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C" 2597fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 2598fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 2599fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek// CXCursor Operations. 2600fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 2601fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 2602fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekstatic Decl *getDeclFromExpr(Stmt *E) { 2603db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor if (CastExpr *CE = dyn_cast<CastExpr>(E)) 2604db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor return getDeclFromExpr(CE->getSubExpr()); 2605db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor 2606fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E)) 2607fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return RefExpr->getDecl(); 260838f28c1189142429384996409fffbc57f67b5c60Douglas Gregor if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E)) 260938f28c1189142429384996409fffbc57f67b5c60Douglas Gregor return RefExpr->getDecl(); 2610fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) 2611fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return ME->getMemberDecl(); 2612fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E)) 2613fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return RE->getDecl(); 2614db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) 2615db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor return PRE->getProperty(); 2616db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor 2617fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (CallExpr *CE = dyn_cast<CallExpr>(E)) 2618fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return getDeclFromExpr(CE->getCallee()); 261993798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E)) 262093798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor if (!CE->isElidable()) 262193798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor return CE->getConstructor(); 2622fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E)) 2623fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return OME->getMethodDecl(); 2624f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2625db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E)) 2626db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor return PE->getProtocol(); 2627db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor 2628fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return 0; 2629fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} 2630ee9405e807d7c447c0143c2bd865b759192e97b3Steve Naroff 2631c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbarstatic SourceLocation getLocationFromExpr(Expr *E) { 2632c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) 2633c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return /*FIXME:*/Msg->getLeftLoc(); 2634c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 2635c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return DRE->getLocation(); 263638f28c1189142429384996409fffbc57f67b5c60Douglas Gregor if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E)) 263738f28c1189142429384996409fffbc57f67b5c60Douglas Gregor return RefExpr->getLocation(); 2638c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (MemberExpr *Member = dyn_cast<MemberExpr>(E)) 2639c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return Member->getMemberLoc(); 2640c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E)) 2641c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return Ivar->getLocation(); 2642c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return E->getLocStart(); 2643c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar} 2644c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar 2645fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekextern "C" { 2646f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2647f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekunsigned clang_visitChildren(CXCursor parent, 2648b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXCursorVisitor visitor, 2649b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXClientData client_data) { 2650b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor ASTUnit *CXXUnit = getCursorASTUnit(parent); 2651b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor 2652eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor CursorVisitor CursorVis(CXXUnit, visitor, client_data, 2653eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor CXXUnit->getMaxPCHLevel()); 2654b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return CursorVis.VisitChildren(parent); 2655b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} 2656b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor 26573387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#ifndef __has_feature 26583387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#define __has_feature(x) 0 26593387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#endif 26603387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#if __has_feature(blocks) 26613387c65a094a02b2a94c05111d035a97d3d5c794David Chisnalltypedef enum CXChildVisitResult 26623387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent); 26633387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall 26643387c65a094a02b2a94c05111d035a97d3d5c794David Chisnallstatic enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent, 26653387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall CXClientData client_data) { 26663387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data; 26673387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall return block(cursor, parent); 26683387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall} 26693387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#else 26703387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall// If we are compiled with a compiler that doesn't have native blocks support, 26713387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall// define and call the block manually, so the 26723387c65a094a02b2a94c05111d035a97d3d5c794David Chisnalltypedef struct _CXChildVisitResult 26733387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall{ 26743387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall void *isa; 26753387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall int flags; 26763387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall int reserved; 26779e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor, 26789e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar CXCursor); 26793387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall} *CXCursorVisitorBlock; 26803387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall 26813387c65a094a02b2a94c05111d035a97d3d5c794David Chisnallstatic enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent, 26823387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall CXClientData client_data) { 26833387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data; 26843387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall return block->invoke(block, cursor, parent); 26853387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall} 26863387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#endif 26873387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall 26883387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall 26899e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbarunsigned clang_visitChildrenWithBlock(CXCursor parent, 26909e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar CXCursorVisitorBlock block) { 26913387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall return clang_visitChildren(parent, visitWithBlock, block); 26923387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall} 26933387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall 269478205d4bada39d95097e766af9eb30cdd0159461Douglas Gregorstatic CXString getDeclSpelling(Decl *D) { 269578205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D); 269678205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor if (!ND) 2697ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 2698f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 269978205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) 2700ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(OMD->getSelector().getAsString()); 2701f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 270278205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND)) 270378205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor // No, this isn't the same as the code below. getIdentifier() is non-virtual 270478205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor // and returns different names. NamedDecl returns the class name and 270578205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor // ObjCCategoryImplDecl returns the category name. 2706ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(CIMP->getIdentifier()->getNameStart()); 2707f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 27080a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor if (isa<UsingDirectiveDecl>(D)) 27090a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor return createCXString(""); 27100a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 271150aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek llvm::SmallString<1024> S; 271250aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek llvm::raw_svector_ostream os(S); 271350aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek ND->printName(os); 271450aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek 271550aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek return createCXString(os.str()); 271678205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor} 2717f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 27189ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXString clang_getCursorSpelling(CXCursor C) { 27197eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor if (clang_isTranslationUnit(C.kind)) 2720b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getTranslationUnitSpelling(C.data[2]); 27217eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor 2722f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff if (clang_isReference(C.kind)) { 2723f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff switch (C.kind) { 2724acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar case CXCursor_ObjCSuperClassRef: { 27252e331b938b38057e333fab0ba841130ea8467794Douglas Gregor ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first; 2726ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(Super->getIdentifier()->getNameStart()); 2727acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar } 2728acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar case CXCursor_ObjCClassRef: { 27291adb082a709f7b588f03672999294e061234b2cfDouglas Gregor ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; 2730ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(Class->getIdentifier()->getNameStart()); 2731acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar } 2732acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar case CXCursor_ObjCProtocolRef: { 273378db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first; 2734f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor assert(OID && "getCursorSpelling(): Missing protocol decl"); 2735ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(OID->getIdentifier()->getNameStart()); 2736acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar } 27373064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: { 27383064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); 27393064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return createCXString(B->getType().getAsString()); 27403064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 27417d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor case CXCursor_TypeRef: { 27427d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor TypeDecl *Type = getCursorTypeRef(C).first; 27437d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor assert(Type && "Missing type decl"); 27447d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 2745ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(getCursorContext(C).getTypeDeclType(Type). 2746ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek getAsString()); 27477d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor } 27480b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: { 27490b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor TemplateDecl *Template = getCursorTemplateRef(C).first; 27506931900f43cea558c6974075256c07728dbfecc6Douglas Gregor assert(Template && "Missing template decl"); 27510b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 27520b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return createCXString(Template->getNameAsString()); 27530b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor } 27546931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 27556931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: { 27566931900f43cea558c6974075256c07728dbfecc6Douglas Gregor NamedDecl *NS = getCursorNamespaceRef(C).first; 27576931900f43cea558c6974075256c07728dbfecc6Douglas Gregor assert(NS && "Missing namespace decl"); 27586931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 27596931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return createCXString(NS->getNameAsString()); 27606931900f43cea558c6974075256c07728dbfecc6Douglas Gregor } 27617d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 2762a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: { 2763a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor FieldDecl *Field = getCursorMemberRef(C).first; 2764a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor assert(Field && "Missing member decl"); 2765a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 2766a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return createCXString(Field->getNameAsString()); 2767a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 2768a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 276936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: { 277036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor LabelStmt *Label = getCursorLabelRef(C).first; 277136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor assert(Label && "Missing label"); 277236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 277336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString(Label->getID()->getName()); 277436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 277536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 27761f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: { 27771f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first; 27781f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Decl *D = Storage.dyn_cast<Decl *>()) { 27791f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) 27801f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(ND->getNameAsString()); 27811f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(""); 27821f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 27831f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) 27841f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(E->getName().getAsString()); 27851f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedTemplateStorage *Ovl 27861f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = Storage.get<OverloadedTemplateStorage*>(); 27871f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Ovl->size() == 0) 27881f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(""); 27891f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString((*Ovl->begin())->getNameAsString()); 27901f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 27911f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 2792acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar default: 2793ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString("<not implemented>"); 2794f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff } 2795f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff } 279697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 279797b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) { 279897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor Decl *D = getDeclFromExpr(getCursorExpr(C)); 279997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (D) 280078205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor return getDeclSpelling(D); 2801ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 280297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor } 280397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 280436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (clang_isStatement(C.kind)) { 280536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor Stmt *S = getCursorStmt(C); 280636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) 280736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString(Label->getID()->getName()); 280836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 280936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString(""); 281036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 281136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 28124ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor if (C.kind == CXCursor_MacroInstantiation) 28134ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor return createCXString(getCursorMacroInstantiation(C)->getName() 28144ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor ->getNameStart()); 28154ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor 2816572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor if (C.kind == CXCursor_MacroDefinition) 2817572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor return createCXString(getCursorMacroDefinition(C)->getName() 2818572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor ->getNameStart()); 2819572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor 2820ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (C.kind == CXCursor_InclusionDirective) 2821ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return createCXString(getCursorInclusionDirective(C)->getFileName()); 2822ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 282360cbfacd947590f83257a4191566dda92fbbde69Douglas Gregor if (clang_isDeclaration(C.kind)) 282460cbfacd947590f83257a4191566dda92fbbde69Douglas Gregor return getDeclSpelling(getCursorDecl(C)); 2825e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 2826ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 2827f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff} 2828f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff 2829358559d8d7b458c5f64941842383a16e61f0828dDouglas GregorCXString clang_getCursorDisplayName(CXCursor C) { 2830358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (!clang_isDeclaration(C.kind)) 2831358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return clang_getCursorSpelling(C); 2832358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2833358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor Decl *D = getCursorDecl(C); 2834358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (!D) 2835358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(""); 2836358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2837358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy; 2838358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) 2839358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor D = FunTmpl->getTemplatedDecl(); 2840358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2841358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { 2842358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::SmallString<64> Str; 2843358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::raw_svector_ostream OS(Str); 2844358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << Function->getNameAsString(); 2845358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Function->getPrimaryTemplate()) 2846358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "<>"; 2847358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "("; 2848358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) { 2849358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (I) 2850358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ", "; 2851358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << Function->getParamDecl(I)->getType().getAsString(Policy); 2852358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2853358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2854358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Function->isVariadic()) { 2855358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Function->getNumParams()) 2856358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ", "; 2857358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "..."; 2858358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2859358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ")"; 2860358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(OS.str()); 2861358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2862358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2863358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) { 2864358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::SmallString<64> Str; 2865358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::raw_svector_ostream OS(Str); 2866358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ClassTemplate->getNameAsString(); 2867358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "<"; 2868358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor TemplateParameterList *Params = ClassTemplate->getTemplateParameters(); 2869358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor for (unsigned I = 0, N = Params->size(); I != N; ++I) { 2870358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (I) 2871358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ", "; 2872358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2873358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor NamedDecl *Param = Params->getParam(I); 2874358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Param->getIdentifier()) { 2875358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << Param->getIdentifier()->getName(); 2876358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor continue; 2877358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2878358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2879358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor // There is no parameter name, which makes this tricky. Try to come up 2880358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor // with something useful that isn't too long. 2881358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) 2882358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << (TTP->wasDeclaredWithTypename()? "typename" : "class"); 2883358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor else if (NonTypeTemplateParmDecl *NTTP 2884358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor = dyn_cast<NonTypeTemplateParmDecl>(Param)) 2885358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << NTTP->getType().getAsString(Policy); 2886358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor else 2887358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "template<...> class"; 2888358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2889358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2890358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ">"; 2891358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(OS.str()); 2892358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2893358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2894358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (ClassTemplateSpecializationDecl *ClassSpec 2895358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 2896358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor // If the type was explicitly written, use that. 2897358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten()) 2898358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(TSInfo->getType().getAsString(Policy)); 2899358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2900358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::SmallString<64> Str; 2901358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::raw_svector_ostream OS(Str); 2902358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ClassSpec->getNameAsString(); 2903358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << TemplateSpecializationType::PrintTemplateArgumentList( 2904910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor ClassSpec->getTemplateArgs().data(), 2905910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor ClassSpec->getTemplateArgs().size(), 2906358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor Policy); 2907358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(OS.str()); 2908358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2909358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2910358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return clang_getCursorSpelling(C); 2911358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor} 2912358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2913e68fff6fc083c6270d835216a3de0b82c6ef0310Ted KremenekCXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { 291489922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff switch (Kind) { 2915e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_FunctionDecl: 2916e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("FunctionDecl"); 2917e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_TypedefDecl: 2918e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("TypedefDecl"); 2919e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_EnumDecl: 2920e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("EnumDecl"); 2921e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_EnumConstantDecl: 2922e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("EnumConstantDecl"); 2923e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_StructDecl: 2924e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("StructDecl"); 2925e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnionDecl: 2926e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnionDecl"); 2927e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ClassDecl: 2928e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ClassDecl"); 2929e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_FieldDecl: 2930e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("FieldDecl"); 2931e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_VarDecl: 2932e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("VarDecl"); 2933e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ParmDecl: 2934e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ParmDecl"); 2935e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCInterfaceDecl: 2936e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCInterfaceDecl"); 2937e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCCategoryDecl: 2938e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCCategoryDecl"); 2939e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCProtocolDecl: 2940e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCProtocolDecl"); 2941e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCPropertyDecl: 2942e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCPropertyDecl"); 2943e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCIvarDecl: 2944e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCIvarDecl"); 2945e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCInstanceMethodDecl: 2946e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCInstanceMethodDecl"); 2947e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCClassMethodDecl: 2948e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCClassMethodDecl"); 2949e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCImplementationDecl: 2950e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCImplementationDecl"); 2951e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCCategoryImplDecl: 2952e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCCategoryImplDecl"); 29538bd5a69999cfd06b6b5a58fdd04e4f802b2df5a4Ted Kremenek case CXCursor_CXXMethod: 29548bd5a69999cfd06b6b5a58fdd04e4f802b2df5a4Ted Kremenek return createCXString("CXXMethod"); 2955e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnexposedDecl: 2956e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnexposedDecl"); 2957e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCSuperClassRef: 2958e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCSuperClassRef"); 2959e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCProtocolRef: 2960e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCProtocolRef"); 2961e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCClassRef: 2962e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCClassRef"); 2963e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_TypeRef: 2964e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("TypeRef"); 29650b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: 29660b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return createCXString("TemplateRef"); 29676931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: 29686931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return createCXString("NamespaceRef"); 2969a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: 2970a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return createCXString("MemberRef"); 297136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: 297236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString("LabelRef"); 29731f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 29741f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString("OverloadedDeclRef"); 2975e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnexposedExpr: 2976e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnexposedExpr"); 29771ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek case CXCursor_BlockExpr: 29781ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek return createCXString("BlockExpr"); 2979e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_DeclRefExpr: 2980e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("DeclRefExpr"); 2981e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_MemberRefExpr: 2982e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("MemberRefExpr"); 2983e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_CallExpr: 2984e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("CallExpr"); 2985e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCMessageExpr: 2986e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCMessageExpr"); 2987e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnexposedStmt: 2988e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnexposedStmt"); 298936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelStmt: 299036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString("LabelStmt"); 2991e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_InvalidFile: 2992e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("InvalidFile"); 2993292db6401f040795db3ea4e00fc02622d6c3ba1dTed Kremenek case CXCursor_InvalidCode: 2994292db6401f040795db3ea4e00fc02622d6c3ba1dTed Kremenek return createCXString("InvalidCode"); 2995e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_NoDeclFound: 2996e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("NoDeclFound"); 2997e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_NotImplemented: 2998e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("NotImplemented"); 2999e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_TranslationUnit: 3000e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("TranslationUnit"); 3001e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek case CXCursor_UnexposedAttr: 3002e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek return createCXString("UnexposedAttr"); 3003e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek case CXCursor_IBActionAttr: 3004e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek return createCXString("attribute(ibaction)"); 30059f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor case CXCursor_IBOutletAttr: 30069f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return createCXString("attribute(iboutlet)"); 3007857e918a8a40deb128840308a318bf623d68295fTed Kremenek case CXCursor_IBOutletCollectionAttr: 3008857e918a8a40deb128840308a318bf623d68295fTed Kremenek return createCXString("attribute(iboutletcollection)"); 30099f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor case CXCursor_PreprocessingDirective: 30109f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return createCXString("preprocessing directive"); 3011572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor case CXCursor_MacroDefinition: 3012572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor return createCXString("macro definition"); 30134807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor case CXCursor_MacroInstantiation: 30144807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor return createCXString("macro instantiation"); 3015ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor case CXCursor_InclusionDirective: 3016ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return createCXString("inclusion directive"); 30178f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek case CXCursor_Namespace: 30188f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek return createCXString("Namespace"); 3019a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek case CXCursor_LinkageSpec: 3020a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek return createCXString("LinkageSpec"); 30213064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: 30223064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return createCXString("C++ base class specifier"); 302301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case CXCursor_Constructor: 302401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return createCXString("CXXConstructor"); 302501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case CXCursor_Destructor: 302601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return createCXString("CXXDestructor"); 302701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case CXCursor_ConversionFunction: 302801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return createCXString("CXXConversion"); 3029fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_TemplateTypeParameter: 3030fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("TemplateTypeParameter"); 3031fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_NonTypeTemplateParameter: 3032fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("NonTypeTemplateParameter"); 3033fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_TemplateTemplateParameter: 3034fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("TemplateTemplateParameter"); 3035fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_FunctionTemplate: 3036fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("FunctionTemplate"); 303739d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor case CXCursor_ClassTemplate: 303839d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor return createCXString("ClassTemplate"); 303974dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor case CXCursor_ClassTemplatePartialSpecialization: 304074dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return createCXString("ClassTemplatePartialSpecialization"); 30416931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceAlias: 30426931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return createCXString("NamespaceAlias"); 30430a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor case CXCursor_UsingDirective: 30440a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor return createCXString("UsingDirective"); 30457e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor case CXCursor_UsingDeclaration: 30467e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return createCXString("UsingDeclaration"); 304789922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff } 3048e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 3049deb06bd3566e18f677e76bc435d478b033fe328bTed Kremenek llvm_unreachable("Unhandled CXCursorKind"); 3050e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString(NULL); 3051600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff} 305289922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff 3053e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenekenum CXChildVisitResult GetCursorVisitor(CXCursor cursor, 3054e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek CXCursor parent, 305533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CXClientData client_data) { 305633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CXCursor *BestCursor = static_cast<CXCursor *>(client_data); 305793798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor 305893798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor // If our current best cursor is the construction of a temporary object, 305993798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor // don't replace that cursor with a type reference, because we want 306093798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor // clang_getCursor() to point at the constructor. 306193798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor if (clang_isExpression(BestCursor->kind) && 306293798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) && 306393798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor cursor.kind == CXCursor_TypeRef) 306493798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor return CXChildVisit_Recurse; 306593798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor 306633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor *BestCursor = cursor; 306733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return CXChildVisit_Recurse; 306833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor} 3069e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 3070b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { 3071b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor if (!TU) 3072f462989fe8d6f59ab2d7d0fe2b4b96292ce706eaTed Kremenek return clang_getNullCursor(); 3073e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 3074b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 3075bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor ASTUnit::ConcurrencyCheck Check(*CXXUnit); 3076bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor 3077a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor // Translate the given source location to make it point at the beginning of 3078a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor // the token under the cursor. 3079a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek SourceLocation SLoc = cxloc::translateSourceLocation(Loc); 3080a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek 3081a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek // Guard against an invalid SourceLocation, or we may assert in one 3082a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek // of the following calls. 3083a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek if (SLoc.isInvalid()) 3084a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek return clang_getNullCursor(); 3085a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek 308640749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor bool Logging = getenv("LIBCLANG_LOGGING"); 3087a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(), 3088a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor CXXUnit->getASTContext().getLangOptions()); 3089a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 309033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound); 309133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor if (SLoc.isValid()) { 309233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // FIXME: Would be great to have a "hint" cursor, then walk from that 309333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // hint cursor upward until we find a cursor whose source range encloses 309433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // the region of interest, rather than starting from the translation unit. 309533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit); 3096e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek CursorVisitor CursorVis(CXXUnit, GetCursorVisitor, &Result, 3097a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor Decl::MaxPCHLevel, SourceLocation(SLoc)); 309833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CursorVis.VisitChildren(Parent); 309977128ddd3077fc045751a55bb3226802b15d5510Steve Naroff } 310040749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor 310140749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor if (Logging) { 310240749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor CXFile SearchFile; 310340749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor unsigned SearchLine, SearchColumn; 310440749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor CXFile ResultFile; 310540749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor unsigned ResultLine, ResultColumn; 310640749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor CXString SearchFileName, ResultFileName, KindSpelling; 310740749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor CXSourceLocation ResultLoc = clang_getCursorLocation(Result); 310840749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor 310940749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 311040749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor 0); 311140749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine, 311240749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor &ResultColumn, 0); 311340749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor SearchFileName = clang_getFileName(SearchFile); 311440749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor ResultFileName = clang_getFileName(ResultFile); 311540749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor KindSpelling = clang_getCursorKindSpelling(Result.kind); 311640749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d)\n", 311740749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_getCString(SearchFileName), SearchLine, SearchColumn, 311840749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_getCString(KindSpelling), 311940749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_getCString(ResultFileName), ResultLine, ResultColumn); 312040749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_disposeString(SearchFileName); 312140749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_disposeString(ResultFileName); 312240749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_disposeString(KindSpelling); 312340749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor } 312440749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor 3125e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return Result; 312677128ddd3077fc045751a55bb3226802b15d5510Steve Naroff} 312777128ddd3077fc045751a55bb3226802b15d5510Steve Naroff 3128738855554394a6afcf39cc8345fd22c3756b8dd0Ted KremenekCXCursor clang_getNullCursor(void) { 31295bfb8c128c2ac8eb4032afc180cdc400a0f953caDouglas Gregor return MakeCXCursorInvalid(CXCursor_InvalidFile); 3130738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek} 3131738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek 3132738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenekunsigned clang_equalCursors(CXCursor X, CXCursor Y) { 3133283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor return X == Y; 3134738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek} 31350d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 31369ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isInvalid(enum CXCursorKind K) { 313777128ddd3077fc045751a55bb3226802b15d5510Steve Naroff return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid; 313877128ddd3077fc045751a55bb3226802b15d5510Steve Naroff} 313977128ddd3077fc045751a55bb3226802b15d5510Steve Naroff 31409ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isDeclaration(enum CXCursorKind K) { 314189922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl; 314289922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff} 31432d4d629d8a0de5112c7ae9d05c03ddbf6dcd956aSteve Naroff 31449ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isReference(enum CXCursorKind K) { 3145f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff return K >= CXCursor_FirstRef && K <= CXCursor_LastRef; 3146f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff} 3147f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff 314897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregorunsigned clang_isExpression(enum CXCursorKind K) { 314997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr; 315097b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor} 315197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 315297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregorunsigned clang_isStatement(enum CXCursorKind K) { 315397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt; 315497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor} 315597b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 31567eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregorunsigned clang_isTranslationUnit(enum CXCursorKind K) { 31577eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor return K == CXCursor_TranslationUnit; 31587eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor} 31597eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor 31609f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregorunsigned clang_isPreprocessing(enum CXCursorKind K) { 31619f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing; 31629f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor} 31639f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor 3164ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenekunsigned clang_isUnexposed(enum CXCursorKind K) { 3165ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek switch (K) { 3166ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedDecl: 3167ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedExpr: 3168ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedStmt: 3169ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedAttr: 3170ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek return true; 3171ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek default: 3172ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek return false; 3173ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek } 3174ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek} 3175ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek 31769ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXCursorKind clang_getCursorKind(CXCursor C) { 31779efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff return C.kind; 31789efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff} 31799efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff 318098258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas GregorCXSourceLocation clang_getCursorLocation(CXCursor C) { 318198258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor if (clang_isReference(C.kind)) { 3182f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor switch (C.kind) { 3183f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCSuperClassRef: { 3184f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor std::pair<ObjCInterfaceDecl *, SourceLocation> P 3185f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor = getCursorObjCSuperClassRef(C); 3186a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 3187f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 3188f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor 3189f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCProtocolRef: { 3190f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor std::pair<ObjCProtocolDecl *, SourceLocation> P 3191f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor = getCursorObjCProtocolRef(C); 3192a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 3193f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 3194f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor 3195f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCClassRef: { 3196f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor std::pair<ObjCInterfaceDecl *, SourceLocation> P 3197f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor = getCursorObjCClassRef(C); 3198a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 3199f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 32007d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 3201f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_TypeRef: { 32027d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C); 3203a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 32047d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor } 32050b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 32060b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: { 32070b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C); 32080b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 32090b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor } 32100b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 32116931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: { 32126931900f43cea558c6974075256c07728dbfecc6Douglas Gregor std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C); 32136931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 32146931900f43cea558c6974075256c07728dbfecc6Douglas Gregor } 32156931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 3216a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: { 3217a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C); 3218a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 3219a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 3220a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 32213064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: { 32221b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C); 32231b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor if (!BaseSpec) 32241b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return clang_getNullLocation(); 32251b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor 32261b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo()) 32271b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 32281b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor TSInfo->getTypeLoc().getBeginLoc()); 32291b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor 32301b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 32311b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor BaseSpec->getSourceRange().getBegin()); 32323064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 3233f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 323436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: { 323536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C); 323636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), P.second); 323736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 323836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 32391f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 32401f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 32411f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor getCursorOverloadedDeclRef(C).second); 32421f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 3243f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor default: 3244f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor // FIXME: Need a way to enumerate all non-reference cases. 3245f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor llvm_unreachable("Missed a reference kind"); 3246f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 324798258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor } 324897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 324997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) 3250f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return cxloc::translateSourceLocation(getCursorContext(C), 325197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor getLocationFromExpr(getCursorExpr(C))); 325297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 325336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (clang_isStatement(C.kind)) 325436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 325536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor getCursorStmt(C)->getLocStart()); 325636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 32579f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor if (C.kind == CXCursor_PreprocessingDirective) { 32589f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin(); 32599f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 32609f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 32614807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor 32624807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor if (C.kind == CXCursor_MacroInstantiation) { 32634ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor SourceLocation L 32644ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin(); 32654807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 32664807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor } 3267572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor 3268572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor if (C.kind == CXCursor_MacroDefinition) { 3269572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation(); 3270572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 3271572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor } 3272ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 3273ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (C.kind == CXCursor_InclusionDirective) { 3274ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor SourceLocation L 3275ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin(); 3276ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 3277ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor } 3278ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 32799a700d277c38d9afaa7cb3fe93a714bfe9b62eecTed Kremenek if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl) 32805352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullLocation(); 328198258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor 3282f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor Decl *D = getCursorDecl(C); 3283f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor SourceLocation Loc = D->getLocation(); 3284f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D)) 3285f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor Loc = Class->getClassLoc(); 3286007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // FIXME: Multiple variables declared in a single declaration 3287007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // currently lack the information needed to correctly determine their 3288007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // ranges when accounting for the type-specifier. We use context 3289007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, 3290007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // and if so, whether it is the first decl. 3291007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 3292007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (!cxcursor::isFirstInDeclGroup(C)) 3293007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek Loc = VD->getLocation(); 3294007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek } 3295007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek 32962ca54feee89d7277fb967e3247a64f40ef155a82Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), Loc); 329788145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff} 3298a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor 3299a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor} // end extern "C" 3300a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 3301a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorstatic SourceRange getRawCursorExtent(CXCursor C) { 3302a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor if (clang_isReference(C.kind)) { 3303a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor switch (C.kind) { 3304a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_ObjCSuperClassRef: 3305a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorObjCSuperClassRef(C).second; 3306f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3307a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_ObjCProtocolRef: 3308a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorObjCProtocolRef(C).second; 3309f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3310a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_ObjCClassRef: 3311a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorObjCClassRef(C).second; 33127d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 3313a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_TypeRef: 3314a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorTypeRef(C).second; 33150b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 33160b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: 33170b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return getCursorTemplateRef(C).second; 33180b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 33196931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: 33206931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return getCursorNamespaceRef(C).second; 3321a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 3322a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: 3323a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return getCursorMemberRef(C).second; 3324a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 33253064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: 33261b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return getCursorCXXBaseSpecifier(C)->getSourceRange(); 3327f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 332836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: 332936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return getCursorLabelRef(C).second; 333036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 33311f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 33321f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return getCursorOverloadedDeclRef(C).second; 33331f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 3334a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor default: 3335a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor // FIXME: Need a way to enumerate all non-reference cases. 3336a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor llvm_unreachable("Missed a reference kind"); 3337a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor } 3338a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor } 333997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 334097b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) 3341a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorExpr(C)->getSourceRange(); 334233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 334333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor if (clang_isStatement(C.kind)) 3344a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorStmt(C)->getSourceRange(); 3345f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3346a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (C.kind == CXCursor_PreprocessingDirective) 3347a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return cxcursor::getCursorPreprocessingDirective(C); 33484807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor 3349a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (C.kind == CXCursor_MacroInstantiation) 3350a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return cxcursor::getCursorMacroInstantiation(C)->getSourceRange(); 3351572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor 3352a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (C.kind == CXCursor_MacroDefinition) 3353a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return cxcursor::getCursorMacroDefinition(C)->getSourceRange(); 3354ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 3355ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (C.kind == CXCursor_InclusionDirective) 3356ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return cxcursor::getCursorInclusionDirective(C)->getSourceRange(); 3357ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 3358007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) { 3359007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek Decl *D = cxcursor::getCursorDecl(C); 3360007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek SourceRange R = D->getSourceRange(); 3361007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // FIXME: Multiple variables declared in a single declaration 3362007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // currently lack the information needed to correctly determine their 3363007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // ranges when accounting for the type-specifier. We use context 3364007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, 3365007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // and if so, whether it is the first decl. 3366007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 3367007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (!cxcursor::isFirstInDeclGroup(C)) 3368007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek R.setBegin(VD->getLocation()); 3369007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek } 3370007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek return R; 3371007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek } 3372ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return SourceRange();} 3373a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 3374a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorextern "C" { 3375a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 3376a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas GregorCXSourceRange clang_getCursorExtent(CXCursor C) { 3377a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor SourceRange R = getRawCursorExtent(C); 3378a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (R.isInvalid()) 33795352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullRange(); 3380f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3381a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return cxloc::translateSourceRange(getCursorContext(C), R); 3382a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor} 3383c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor 3384c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas GregorCXCursor clang_getCursorReferenced(CXCursor C) { 3385b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (clang_isInvalid(C.kind)) 3386b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getNullCursor(); 3387f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3388b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor ASTUnit *CXXUnit = getCursorASTUnit(C); 33891f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (clang_isDeclaration(C.kind)) { 33901f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = getCursorDecl(C); 33911f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) 33921f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(Using, D->getLocation(), CXXUnit); 33931f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D)) 33941f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), CXXUnit); 33951f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCForwardProtocolDecl *Protocols 33961f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = dyn_cast<ObjCForwardProtocolDecl>(D)) 33971f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), CXXUnit); 33981f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 3399c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor return C; 34001f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 34011f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 340297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) { 34031f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Expr *E = getCursorExpr(C); 34041f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = getDeclFromExpr(E); 340597b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (D) 3406b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(D, CXXUnit); 34071f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34081f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E)) 34091f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(Ovl, CXXUnit); 34101f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 341197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor return clang_getNullCursor(); 341297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor } 341397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 341436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (clang_isStatement(C.kind)) { 341536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor Stmt *S = getCursorStmt(C); 341636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S)) 341736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return MakeCXCursor(Goto->getLabel(), getCursorDecl(C), 341836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor getCursorASTUnit(C)); 341936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 342036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return clang_getNullCursor(); 342136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 342236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 3423bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor if (C.kind == CXCursor_MacroInstantiation) { 3424bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition()) 3425bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor return MakeMacroDefinitionCursor(Def, CXXUnit); 3426bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor } 3427bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor 3428c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor if (!clang_isReference(C.kind)) 3429c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor return clang_getNullCursor(); 3430f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3431c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor switch (C.kind) { 3432c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor case CXCursor_ObjCSuperClassRef: 3433b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(getCursorObjCSuperClassRef(C).first, CXXUnit); 3434f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3435f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCProtocolRef: { 3436b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(getCursorObjCProtocolRef(C).first, CXXUnit); 3437f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3438f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCClassRef: 3439b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(getCursorObjCClassRef(C).first, CXXUnit); 34407d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 3441f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_TypeRef: 34427d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit); 34430b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 34440b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: 34450b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return MakeCXCursor(getCursorTemplateRef(C).first, CXXUnit); 34460b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 34476931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: 34486931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return MakeCXCursor(getCursorNamespaceRef(C).first, CXXUnit); 34496931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 3450a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: 3451a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return MakeCXCursor(getCursorMemberRef(C).first, CXXUnit); 3452a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 34533064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: { 34543064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); 34553064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), 34563064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek CXXUnit)); 34573064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 3458f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 345936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: 346036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor // FIXME: We end up faking the "parent" declaration here because we 346136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor // don't want to make CXCursor larger. 346236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return MakeCXCursor(getCursorLabelRef(C).first, 346336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor CXXUnit->getASTContext().getTranslationUnitDecl(), 346436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor CXXUnit); 346536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 34661f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 34671f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return C; 34681f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 3469c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor default: 3470c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor // We would prefer to enumerate all non-reference cursor kinds here. 3471c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor llvm_unreachable("Unhandled reference cursor kind"); 3472c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor break; 3473c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor } 3474c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor } 3475f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3476c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor return clang_getNullCursor(); 3477c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor} 3478c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor 3479b699866820102a69d83d6ac6941985c5ef4e8c40Douglas GregorCXCursor clang_getCursorDefinition(CXCursor C) { 3480b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (clang_isInvalid(C.kind)) 3481b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getNullCursor(); 3482f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3483b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor ASTUnit *CXXUnit = getCursorASTUnit(C); 3484f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3485b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor bool WasReference = false; 348697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isReference(C.kind) || clang_isExpression(C.kind)) { 3487b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor C = clang_getCursorReferenced(C); 3488b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor WasReference = true; 3489b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3490b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3491bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor if (C.kind == CXCursor_MacroInstantiation) 3492bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor return clang_getCursorReferenced(C); 3493bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor 3494b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!clang_isDeclaration(C.kind)) 3495b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3496b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3497b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor Decl *D = getCursorDecl(C); 3498b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!D) 3499b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3500f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3501b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor switch (D->getKind()) { 3502b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Declaration kinds that don't really separate the notions of 3503b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // declaration and definition. 3504b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Namespace: 3505b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Typedef: 3506b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::TemplateTypeParm: 3507b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::EnumConstant: 3508b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Field: 3509b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCIvar: 3510b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCAtDefsField: 3511b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ImplicitParam: 3512b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ParmVar: 3513b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::NonTypeTemplateParm: 3514b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::TemplateTemplateParm: 3515b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCCategoryImpl: 3516b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCImplementation: 35176206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara case Decl::AccessSpec: 3518b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::LinkageSpec: 3519b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCPropertyImpl: 3520b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::FileScopeAsm: 3521b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::StaticAssert: 3522b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Block: 3523b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 3524b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3525b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Declaration kinds that don't make any sense here, but are 3526b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // nonetheless harmless. 3527b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::TranslationUnit: 3528b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor break; 3529b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3530b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Declaration kinds for which the definition is not resolvable. 3531b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UnresolvedUsingTypename: 3532b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UnresolvedUsingValue: 3533b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor break; 3534b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3535b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UsingDirective: 3536b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(), 3537b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor CXXUnit); 3538b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3539b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::NamespaceAlias: 3540b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), CXXUnit); 3541b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3542b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Enum: 3543b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Record: 3544b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXRecord: 3545b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ClassTemplateSpecialization: 3546b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ClassTemplatePartialSpecialization: 3547952b017601f9c82b51119c3a1600f1312a833db9Douglas Gregor if (TagDecl *Def = cast<TagDecl>(D)->getDefinition()) 3548b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Def, CXXUnit); 3549b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3550b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3551b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Function: 3552b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXMethod: 3553b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXConstructor: 3554b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXDestructor: 3555b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXConversion: { 3556b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor const FunctionDecl *Def = 0; 3557b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (cast<FunctionDecl>(D)->getBody(Def)) 3558b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(const_cast<FunctionDecl *>(Def), CXXUnit); 3559b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3560b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3561b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3562b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Var: { 356331310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl // Ask the variable if it has a definition. 356431310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl if (VarDecl *Def = cast<VarDecl>(D)->getDefinition()) 356531310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl return MakeCXCursor(Def, CXXUnit); 356631310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl return clang_getNullCursor(); 3567b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3568f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3569b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::FunctionTemplate: { 3570b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor const FunctionDecl *Def = 0; 3571b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def)) 3572b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Def->getDescribedFunctionTemplate(), CXXUnit); 3573b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3574b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3575f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3576b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ClassTemplate: { 3577b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl() 3578952b017601f9c82b51119c3a1600f1312a833db9Douglas Gregor ->getDefinition()) 35790b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(), 3580b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor CXXUnit); 3581b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3582b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3583b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 35841f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case Decl::Using: 35851f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), 35861f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor D->getLocation(), CXXUnit); 3587b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3588b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UsingShadow: 3589b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getCursorDefinition( 3590f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), 3591b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor CXXUnit)); 3592b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3593b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCMethod: { 3594b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D); 3595b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (Method->isThisDeclarationADefinition()) 3596b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 3597b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3598b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Dig out the method definition in the associated 3599b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // @implementation, if we have it. 3600b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // FIXME: The ASTs should make finding the definition easier. 3601b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCInterfaceDecl *Class 3602b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) 3603b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCImplementationDecl *ClassImpl = Class->getImplementation()) 3604b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(), 3605b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor Method->isInstanceMethod())) 3606b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (Def->isThisDeclarationADefinition()) 3607b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Def, CXXUnit); 3608b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3609b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3610b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3611b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3612b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCCategory: 3613b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCCategoryImplDecl *Impl 3614b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = cast<ObjCCategoryDecl>(D)->getImplementation()) 3615b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Impl, CXXUnit); 3616b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3617b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3618b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCProtocol: 3619b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!cast<ObjCProtocolDecl>(D)->isForwardDecl()) 3620b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 3621b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3622b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3623b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCInterface: 3624b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // There are two notions of a "definition" for an Objective-C 3625b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // class: the interface and its implementation. When we resolved a 3626b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // reference to an Objective-C class, produce the @interface as 3627b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // the definition; when we were provided with the interface, 3628b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // produce the @implementation as the definition. 3629b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (WasReference) { 3630b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl()) 3631b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 3632b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } else if (ObjCImplementationDecl *Impl 3633b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = cast<ObjCInterfaceDecl>(D)->getImplementation()) 3634b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Impl, CXXUnit); 3635b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3636f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3637b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCProperty: 3638b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // FIXME: We don't really know where to find the 3639b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // ObjCPropertyImplDecls that implement this property. 3640b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3641b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3642b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCCompatibleAlias: 3643b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCInterfaceDecl *Class 3644b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface()) 3645b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!Class->isForwardDecl()) 3646b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Class, CXXUnit); 3647f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3648b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3649b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 36501f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case Decl::ObjCForwardProtocol: 36511f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D), 36521f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor D->getLocation(), CXXUnit); 3653b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 36541f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case Decl::ObjCClass: 36559e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(), 36561f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor CXXUnit); 3657b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3658b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Friend: 3659b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl()) 3660b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit)); 3661b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3662b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3663b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::FriendTemplate: 3664b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl()) 3665b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit)); 3666b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3667b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3668b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3669b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3670b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor} 3671b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3672b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregorunsigned clang_isCursorDefinition(CXCursor C) { 3673b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!clang_isDeclaration(C.kind)) 3674b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return 0; 3675b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3676b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getCursorDefinition(C) == C; 3677b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor} 3678b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 36791f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregorunsigned clang_getNumOverloadedDecls(CXCursor C) { 36807c432dd959609a3689c2e4406450c092e6d76d6dDouglas Gregor if (C.kind != CXCursor_OverloadedDeclRef) 36811f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return 0; 36821f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 36831f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first; 36841f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) 36851f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return E->getNumDecls(); 36861f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 36871f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadedTemplateStorage *S 36881f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = Storage.dyn_cast<OverloadedTemplateStorage*>()) 36891f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return S->size(); 36901f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 36911f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = Storage.get<Decl*>(); 36921f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) 3693826faa22bae112e01293a58534a40711043cce65Argyrios Kyrtzidis return Using->shadow_size(); 36941f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D)) 36951f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return Classes->size(); 36961f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D)) 36971f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return Protocols->protocol_size(); 36981f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 36991f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return 0; 37001f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 37011f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 37021f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas GregorCXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) { 37037c432dd959609a3689c2e4406450c092e6d76d6dDouglas Gregor if (cursor.kind != CXCursor_OverloadedDeclRef) 37041f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return clang_getNullCursor(); 37051f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 37061f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (index >= clang_getNumOverloadedDecls(cursor)) 37071f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return clang_getNullCursor(); 37081f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 37091f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor ASTUnit *Unit = getCursorASTUnit(cursor); 37101f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first; 37111f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) 37121f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCXCursor(E->decls_begin()[index], Unit); 37131f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 37141f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadedTemplateStorage *S 37151f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = Storage.dyn_cast<OverloadedTemplateStorage*>()) 37161f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCXCursor(S->begin()[index], Unit); 37171f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 37181f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = Storage.get<Decl*>(); 37191f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) { 37201f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor // FIXME: This is, unfortunately, linear time. 37211f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor UsingDecl::shadow_iterator Pos = Using->shadow_begin(); 37221f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor std::advance(Pos, index); 37231f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), Unit); 37241f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 37251f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 37261f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D)) 37271f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCXCursor(Classes->begin()[index].getInterface(), Unit); 37281f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 37291f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D)) 37301f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCXCursor(Protocols->protocol_begin()[index], Unit); 37311f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 37321f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return clang_getNullCursor(); 37331f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 37341f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 37350d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbarvoid clang_getDefinitionSpellingAndExtent(CXCursor C, 37364ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff const char **startBuf, 37374ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff const char **endBuf, 37384ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff unsigned *startLine, 37394ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff unsigned *startColumn, 37404ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff unsigned *endLine, 37419ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar unsigned *endColumn) { 3742283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor assert(getCursorDecl(C) && "CXCursor has null decl"); 3743283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C)); 37444ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff FunctionDecl *FD = dyn_cast<FunctionDecl>(ND); 37454ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody()); 3746f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 37474ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff SourceManager &SM = FD->getASTContext().getSourceManager(); 37484ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *startBuf = SM.getCharacterData(Body->getLBracLoc()); 37494ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *endBuf = SM.getCharacterData(Body->getRBracLoc()); 37504ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *startLine = SM.getSpellingLineNumber(Body->getLBracLoc()); 37514ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc()); 37524ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *endLine = SM.getSpellingLineNumber(Body->getRBracLoc()); 37534ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc()); 37544ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff} 3755f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 37560a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregorvoid clang_enableStackTraces(void) { 37570a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor llvm::sys::PrintStackTraceOnErrorSignal(); 37580a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor} 37590a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor 3760995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbarvoid clang_executeOnThread(void (*fn)(void*), void *user_data, 3761995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar unsigned stack_size) { 3762995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar llvm::llvm_execute_on_thread(fn, user_data, stack_size); 3763995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar} 3764995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar 3765fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C" 3766fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 3767fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 3768fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor// Token-based Operations. 3769fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor//===----------------------------------------------------------------------===// 3770fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3771fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor/* CXToken layout: 3772fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[0]: a CXTokenKind 3773fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[1]: starting token location 3774fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[2]: token length 3775fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[3]: reserved 3776f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek * ptr_data: for identifiers and keywords, an IdentifierInfo*. 3777fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * otherwise unused. 3778fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor */ 3779fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregorextern "C" { 3780fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3781fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXTokenKind clang_getTokenKind(CXToken CXTok) { 3782fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return static_cast<CXTokenKind>(CXTok.int_data[0]); 3783fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 3784fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3785fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) { 3786fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor switch (clang_getTokenKind(CXTok)) { 3787fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Identifier: 3788fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Keyword: 3789fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // We know we have an IdentifierInfo*, so use that. 3790ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data) 3791ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek ->getNameStart()); 3792fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3793fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Literal: { 3794fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // We have stashed the starting pointer in the ptr_data field. Use it. 3795fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor const char *Text = static_cast<const char *>(CXTok.ptr_data); 3796ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(llvm::StringRef(Text, CXTok.int_data[2])); 3797fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } 3798f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3799fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Punctuation: 3800fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Comment: 3801fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor break; 3802fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } 3803f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3804f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek // We have to find the starting buffer pointer the hard way, by 3805fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // deconstructing the source location. 3806fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 3807fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (!CXXUnit) 3808ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 3809f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3810fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]); 3811fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor std::pair<FileID, unsigned> LocInfo 3812fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = CXXUnit->getSourceManager().getDecomposedLoc(Loc); 3813f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor bool Invalid = false; 3814f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer llvm::StringRef Buffer 3815f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); 3816f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor if (Invalid) 3817aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor return createCXString(""); 3818fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3819f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2])); 3820fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 3821f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3822fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) { 3823fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 3824fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (!CXXUnit) 3825fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return clang_getNullLocation(); 3826f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3827fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return cxloc::translateSourceLocation(CXXUnit->getASTContext(), 3828fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceLocation::getFromRawEncoding(CXTok.int_data[1])); 3829fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 3830fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3831fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) { 3832fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 38335352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor if (!CXXUnit) 38345352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullRange(); 3835f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3836f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return cxloc::translateSourceRange(CXXUnit->getASTContext(), 3837fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceLocation::getFromRawEncoding(CXTok.int_data[1])); 3838fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 3839f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3840fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregorvoid clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, 3841fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXToken **Tokens, unsigned *NumTokens) { 3842fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (Tokens) 3843fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *Tokens = 0; 3844fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (NumTokens) 3845fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *NumTokens = 0; 3846f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3847fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 3848fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (!CXXUnit || !Tokens || !NumTokens) 3849fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 3850f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3851bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor ASTUnit::ConcurrencyCheck Check(*CXXUnit); 3852bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor 385385b988fdfa6adab6d43e16efd19ad4f3f7e2b49bDaniel Dunbar SourceRange R = cxloc::translateCXSourceRange(Range); 3854fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (R.isInvalid()) 3855fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 3856f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3857fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceManager &SourceMgr = CXXUnit->getSourceManager(); 3858fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor std::pair<FileID, unsigned> BeginLocInfo 3859fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = SourceMgr.getDecomposedLoc(R.getBegin()); 3860fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor std::pair<FileID, unsigned> EndLocInfo 3861fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = SourceMgr.getDecomposedLoc(R.getEnd()); 3862f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3863fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Cannot tokenize across files. 3864fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (BeginLocInfo.first != EndLocInfo.first) 3865fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 3866f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3867f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek // Create a lexer 3868f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor bool Invalid = false; 3869f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer llvm::StringRef Buffer 3870f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid); 387147a3fcd4afe122b23f9e7b6148f147bfa460cfe8Douglas Gregor if (Invalid) 387247a3fcd4afe122b23f9e7b6148f147bfa460cfe8Douglas Gregor return; 3873aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor 3874fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), 3875fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXXUnit->getASTContext().getLangOptions(), 3876f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end()); 3877fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Lex.SetCommentRetentionState(true); 3878f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3879fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Lex tokens until we hit the end of the range. 3880f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second; 3881fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor llvm::SmallVector<CXToken, 32> CXTokens; 3882fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Token Tok; 3883096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall bool previousWasAt = false; 3884fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor do { 3885fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Lex the next token 3886fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Lex.LexFromRawLexer(Tok); 3887fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (Tok.is(tok::eof)) 3888fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor break; 3889f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3890fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Initialize the CXToken. 3891fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXToken CXTok; 3892f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3893fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // - Common fields 3894fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[1] = Tok.getLocation().getRawEncoding(); 3895fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[2] = Tok.getLength(); 3896fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[3] = 0; 3897f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3898fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // - Kind-specific fields 3899fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (Tok.isLiteral()) { 3900fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[0] = CXToken_Literal; 3901fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = (void *)Tok.getLiteralData(); 3902fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } else if (Tok.is(tok::identifier)) { 3903aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor // Lookup the identifier to determine whether we have a keyword. 3904fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor std::pair<FileID, unsigned> LocInfo 3905fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = SourceMgr.getDecomposedLoc(Tok.getLocation()); 3906f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor bool Invalid = false; 3907f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer llvm::StringRef Buf 3908f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); 3909f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor if (Invalid) 3910aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor return; 3911aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor 3912f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer const char *StartPos = Buf.data() + LocInfo.second; 3913fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor IdentifierInfo *II 3914fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok, StartPos); 3915aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek 3916096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) { 3917aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek CXTok.int_data[0] = CXToken_Keyword; 3918aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek } 3919aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek else { 3920aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek CXTok.int_data[0] = II->getTokenID() == tok::identifier? 3921aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek CXToken_Identifier 3922aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek : CXToken_Keyword; 3923aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek } 3924fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = II; 3925fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } else if (Tok.is(tok::comment)) { 3926fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[0] = CXToken_Comment; 3927fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = 0; 3928fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } else { 3929fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[0] = CXToken_Punctuation; 3930fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = 0; 3931fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } 3932fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTokens.push_back(CXTok); 3933096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall previousWasAt = Tok.is(tok::at); 3934fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } while (Lex.getBufferLocation() <= EffectiveBufferEnd); 3935f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3936fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (CXTokens.empty()) 3937fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 3938f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3939fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size()); 3940fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); 3941fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *NumTokens = CXTokens.size(); 3942fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 39430045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor 39446db610934bedc6896393c1e1099525b35380acd6Ted Kremenekvoid clang_disposeTokens(CXTranslationUnit TU, 39456db610934bedc6896393c1e1099525b35380acd6Ted Kremenek CXToken *Tokens, unsigned NumTokens) { 39466db610934bedc6896393c1e1099525b35380acd6Ted Kremenek free(Tokens); 39476db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} 39486db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 39496db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} // end: extern "C" 39506db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 39516db610934bedc6896393c1e1099525b35380acd6Ted Kremenek//===----------------------------------------------------------------------===// 39526db610934bedc6896393c1e1099525b35380acd6Ted Kremenek// Token annotation APIs. 39536db610934bedc6896393c1e1099525b35380acd6Ted Kremenek//===----------------------------------------------------------------------===// 39546db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 39550045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregortypedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData; 3956fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekstatic enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, 3957fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXCursor parent, 3958fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXClientData client_data); 39596db610934bedc6896393c1e1099525b35380acd6Ted Kremeneknamespace { 39606db610934bedc6896393c1e1099525b35380acd6Ted Kremenekclass AnnotateTokensWorker { 39616db610934bedc6896393c1e1099525b35380acd6Ted Kremenek AnnotateTokensData &Annotated; 396211949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek CXToken *Tokens; 396311949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek CXCursor *Cursors; 396411949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek unsigned NumTokens; 3965fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek unsigned TokIdx; 39664419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor unsigned PreprocessingTokIdx; 3967fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CursorVisitor AnnotateVis; 3968fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceManager &SrcMgr; 3969fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3970fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek bool MoreTokens() const { return TokIdx < NumTokens; } 3971fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek unsigned NextToken() const { return TokIdx; } 3972fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek void AdvanceToken() { ++TokIdx; } 3973fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation GetTokenLoc(unsigned tokI) { 3974fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]); 3975fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 3976fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 39776db610934bedc6896393c1e1099525b35380acd6Ted Kremenekpublic: 397811949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek AnnotateTokensWorker(AnnotateTokensData &annotated, 3979fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXToken *tokens, CXCursor *cursors, unsigned numTokens, 3980fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek ASTUnit *CXXUnit, SourceRange RegionOfInterest) 398111949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek : Annotated(annotated), Tokens(tokens), Cursors(cursors), 39824419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0), 3983fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AnnotateVis(CXXUnit, AnnotateTokensVisitor, this, 3984fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Decl::MaxPCHLevel, RegionOfInterest), 3985fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SrcMgr(CXXUnit->getSourceManager()) {} 398611949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek 3987fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); } 39886db610934bedc6896393c1e1099525b35380acd6Ted Kremenek enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent); 3989fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek void AnnotateTokens(CXCursor parent); 3990ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek void AnnotateTokens() { 3991ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getASTUnit())); 3992ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek } 39936db610934bedc6896393c1e1099525b35380acd6Ted Kremenek}; 39946db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} 39950045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor 3996fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekvoid AnnotateTokensWorker::AnnotateTokens(CXCursor parent) { 3997fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Walk the AST within the region of interest, annotating tokens 3998fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // along the way. 3999fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek VisitChildren(parent); 4000fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4001fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek for (unsigned I = 0 ; I < TokIdx ; ++I) { 400211949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); 40034419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor if (Pos != Annotated.end() && 40044419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor (clang_isInvalid(Cursors[I].kind) || 40054419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor Pos->second.kind != CXCursor_PreprocessingDirective)) 4006fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = Pos->second; 4007fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 4008fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4009fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Finish up annotating any tokens left. 4010fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (!MoreTokens()) 4011fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return; 401211949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek 4013fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const CXCursor &C = clang_getNullCursor(); 4014fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek for (unsigned I = TokIdx ; I < NumTokens ; ++I) { 4015fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); 4016fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second; 401711949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek } 401811949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek} 401911949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek 40206db610934bedc6896393c1e1099525b35380acd6Ted Kremenekenum CXChildVisitResult 40214419b675577d7c281a659fab1fec10e1bfbe04c5Douglas GregorAnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { 4022fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXSourceLocation Loc = clang_getCursorLocation(cursor); 40234419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor SourceRange cursorRange = getRawCursorExtent(cursor); 402481d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor if (cursorRange.isInvalid()) 402581d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor return CXChildVisit_Recurse; 402681d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor 40274419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor if (clang_isPreprocessing(cursor.kind)) { 40284419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // For macro instantiations, just note where the beginning of the macro 40294419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // instantiation occurs. 40304419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor if (cursor.kind == CXCursor_MacroInstantiation) { 40314419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor Annotated[Loc.int_data] = cursor; 40324419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor return CXChildVisit_Recurse; 40334419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 40344419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 40354419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Items in the preprocessing record are kept separate from items in 40364419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // declarations, so we keep a separate token index. 40374419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor unsigned SavedTokIdx = TokIdx; 40384419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor TokIdx = PreprocessingTokIdx; 40394419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 40404419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Skip tokens up until we catch up to the beginning of the preprocessing 40414419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // entry. 40424419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor while (MoreTokens()) { 40434419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor const unsigned I = NextToken(); 40444419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor SourceLocation TokLoc = GetTokenLoc(I); 40454419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 40464419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeBefore: 40474419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor AdvanceToken(); 40484419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor continue; 40494419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeAfter: 40504419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeOverlap: 40514419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 40524419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 40534419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 40544419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 40554419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 40564419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Look at all of the tokens within this range. 40574419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor while (MoreTokens()) { 40584419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor const unsigned I = NextToken(); 40594419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor SourceLocation TokLoc = GetTokenLoc(I); 40604419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 40614419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeBefore: 40624419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor assert(0 && "Infeasible"); 40634419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeAfter: 40644419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 40654419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeOverlap: 40664419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor Cursors[I] = cursor; 40674419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor AdvanceToken(); 40684419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor continue; 40694419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 40704419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 40714419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 40724419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 40734419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Save the preprocessing token index; restore the non-preprocessing 40744419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // token index. 40754419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor PreprocessingTokIdx = TokIdx; 40764419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor TokIdx = SavedTokIdx; 40770045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor return CXChildVisit_Recurse; 40780045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor } 4079fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4080fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (cursorRange.isInvalid()) 4081fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return CXChildVisit_Continue; 4082a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek 4083fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data); 4084fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4085a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek // Adjust the annotated range based specific declarations. 4086a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek const enum CXCursorKind cursorK = clang_getCursorKind(cursor); 4087a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) { 408823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek Decl *D = cxcursor::getCursorDecl(cursor); 408923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // Don't visit synthesized ObjC methods, since they have no syntatic 409023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // representation in the source. 409123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 409223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (MD->isSynthesized()) 409323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return CXChildVisit_Continue; 409423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek } 409523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { 4096a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) { 4097a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek TypeLoc TL = TI->getTypeLoc(); 4098bd054dba8a3023821f2a0951b0fae05e3522a7c9Abramo Bagnara SourceLocation TLoc = TL.getSourceRange().getBegin(); 409981d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor if (TLoc.isValid() && L.isValid() && 41006bfd53360072409715fe4e4d4f41d9ebdf948479Ted Kremenek SrcMgr.isBeforeInTranslationUnit(TLoc, L)) 4101a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek cursorRange.setBegin(TLoc); 4102a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek } 4103a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek } 4104a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek } 410581d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor 41063f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // If the location of the cursor occurs within a macro instantiation, record 41073f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // the spelling location of the cursor in our annotation map. We can then 41083f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // paper over the token labelings during a post-processing step to try and 41093f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // get cursor mappings for tokens that are the *arguments* of a macro 41103f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // instantiation. 41113f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek if (L.isMacroID()) { 41123f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding(); 41133f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // Only invalidate the old annotation if it isn't part of a preprocessing 41143f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // directive. Here we assume that the default construction of CXCursor 41153f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // results in CXCursor.kind being an initialized value (i.e., 0). If 41163f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // this isn't the case, we can fix by doing lookup + insertion. 41174419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 41183f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek CXCursor &oldC = Annotated[rawEncoding]; 41193f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek if (!clang_isPreprocessing(oldC.kind)) 41203f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek oldC = cursor; 41213f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek } 41223f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek 4123fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const enum CXCursorKind K = clang_getCursorKind(parent); 4124fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const CXCursor updateC = 4125d8b0a84d586bc0a08695968acf2f169c9d01da69Ted Kremenek (clang_isInvalid(K) || K == CXCursor_TranslationUnit) 4126d8b0a84d586bc0a08695968acf2f169c9d01da69Ted Kremenek ? clang_getNullCursor() : parent; 4127fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4128fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek while (MoreTokens()) { 4129fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned I = NextToken(); 4130fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation TokLoc = GetTokenLoc(I); 4131fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 4132fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeBefore: 4133fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = updateC; 4134fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AdvanceToken(); 4135fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek continue; 4136fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeAfter: 4137fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeOverlap: 4138fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek break; 4139fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 4140fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek break; 4141fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 4142fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4143fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Visit children to get their cursor information. 4144fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned BeforeChildren = NextToken(); 4145fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek VisitChildren(cursor); 4146fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned AfterChildren = NextToken(); 4147fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4148fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Adjust 'Last' to the last token within the extent of the cursor. 4149fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek while (MoreTokens()) { 4150fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned I = NextToken(); 4151fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation TokLoc = GetTokenLoc(I); 4152fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 4153fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeBefore: 4154fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek assert(0 && "Infeasible"); 4155fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeAfter: 4156fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek break; 4157fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeOverlap: 4158fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = updateC; 4159fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AdvanceToken(); 4160fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek continue; 4161fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 4162fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek break; 4163fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 4164fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned Last = NextToken(); 41656db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 4166fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Scan the tokens that are at the beginning of the cursor, but are not 4167fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // capture by the child cursors. 4168fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4169fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // For AST elements within macros, rely on a post-annotate pass to 4170fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // to correctly annotate the tokens with cursors. Otherwise we can 4171fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // get confusing results of having tokens that map to cursors that really 4172fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // are expanded by an instantiation. 4173fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (L.isMacroID()) 4174fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek cursor = clang_getNullCursor(); 4175fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4176fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek for (unsigned I = BeforeChildren; I != AfterChildren; ++I) { 4177fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (!clang_isInvalid(clang_getCursorKind(Cursors[I]))) 4178fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek break; 41794419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 4180fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = cursor; 4181fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 4182fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Scan the tokens that are at the end of the cursor, but are not captured 4183fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // but the child cursors. 4184fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek for (unsigned I = AfterChildren; I != Last; ++I) 4185fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = cursor; 4186fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4187fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek TokIdx = Last; 4188fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return CXChildVisit_Continue; 41890045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor} 41900045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor 41916db610934bedc6896393c1e1099525b35380acd6Ted Kremenekstatic enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, 41926db610934bedc6896393c1e1099525b35380acd6Ted Kremenek CXCursor parent, 41936db610934bedc6896393c1e1099525b35380acd6Ted Kremenek CXClientData client_data) { 41946db610934bedc6896393c1e1099525b35380acd6Ted Kremenek return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent); 41956db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} 41966db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 4197ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek// This gets run a separate thread to avoid stack blowout. 4198ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenekstatic void runAnnotateTokensWorker(void *UserData) { 4199ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek ((AnnotateTokensWorker*)UserData)->AnnotateTokens(); 4200ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek} 4201ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek 42026db610934bedc6896393c1e1099525b35380acd6Ted Kremenekextern "C" { 42036db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 4204fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregorvoid clang_annotateTokens(CXTranslationUnit TU, 4205fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXToken *Tokens, unsigned NumTokens, 4206fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXCursor *Cursors) { 4207fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4208fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (NumTokens == 0 || !Tokens || !Cursors) 42090045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor return; 4210fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 42114419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Any token we don't specifically annotate will have a NULL cursor. 42124419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor CXCursor C = clang_getNullCursor(); 42134419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor for (unsigned I = 0; I != NumTokens; ++I) 42144419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor Cursors[I] = C; 42154419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 42160045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 42174419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor if (!CXXUnit) 42180045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor return; 4219fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4220bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor ASTUnit::ConcurrencyCheck Check(*CXXUnit); 4221fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 42220396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // Determine the region of interest, which contains all of the tokens. 42230045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor SourceRange RegionOfInterest; 4224fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek RegionOfInterest.setBegin(cxloc::translateSourceLocation( 4225fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek clang_getTokenLocation(TU, Tokens[0]))); 4226a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor RegionOfInterest.setEnd(cxloc::translateSourceLocation( 4227a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor clang_getTokenLocation(TU, 4228a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor Tokens[NumTokens - 1]))); 4229fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 42300396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // A mapping from the source locations found when re-lexing or traversing the 42310396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // region of interest to the corresponding cursors. 42320045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor AnnotateTokensData Annotated; 4233fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4234fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Relex the tokens within the source range to look for preprocessing 42350396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // directives. 42369f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor SourceManager &SourceMgr = CXXUnit->getSourceManager(); 42379f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor std::pair<FileID, unsigned> BeginLocInfo 42389f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin()); 42399f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor std::pair<FileID, unsigned> EndLocInfo 42409f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd()); 4241fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 42429f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor llvm::StringRef Buffer; 42430396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor bool Invalid = false; 42440396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (BeginLocInfo.first == EndLocInfo.first && 42450396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) && 42460396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor !Invalid) { 42479f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), 42489f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor CXXUnit->getASTContext().getLangOptions(), 4249fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Buffer.begin(), Buffer.data() + BeginLocInfo.second, 42504ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor Buffer.end()); 42519f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Lex.SetCommentRetentionState(true); 4252fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4253fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Lex tokens in raw mode until we hit the end of the range, to avoid 42549f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // entering #includes or expanding macros. 42554807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor while (true) { 42569f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Token Tok; 42579f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Lex.LexFromRawLexer(Tok); 4258fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 42599f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor reprocess: 42609f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) { 42619f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // We have found a preprocessing directive. Gobble it up so that we 42629e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar // don't see it while preprocessing these tokens later, but keep track 42639e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar // of all of the token locations inside this preprocessing directive so 42649e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar // that we can annotate them appropriately. 42659f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // 42669f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // FIXME: Some simple tests here could identify macro definitions and 42679f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // #undefs, to provide specific cursor kinds for those. 42689f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor std::vector<SourceLocation> Locations; 42699f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor do { 42709f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Locations.push_back(Tok.getLocation()); 4271fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Lex.LexFromRawLexer(Tok); 42729f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof)); 4273fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 42749f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor using namespace cxcursor; 42759f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor CXCursor Cursor 4276fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(), 4277fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Locations.back()), 42786db610934bedc6896393c1e1099525b35380acd6Ted Kremenek CXXUnit); 42799f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor for (unsigned I = 0, N = Locations.size(); I != N; ++I) { 42809f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Annotated[Locations[I].getRawEncoding()] = Cursor; 42819f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 4282fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 42839f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor if (Tok.isAtStartOfLine()) 42849f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor goto reprocess; 4285fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 42869f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor continue; 42879f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 4288fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 42894807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor if (Tok.is(tok::eof)) 42909f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor break; 42919f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 42924ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor } 4293fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 42940396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // Annotate all of the source locations in the region of interest that map to 4295fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // a specific cursor. 4296fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens, 4297fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXXUnit, RegionOfInterest); 4298ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek 4299ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek // Run the worker within a CrashRecoveryContext. 4300ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek llvm::CrashRecoveryContext CRC; 4301ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek if (!RunSafely(CRC, runAnnotateTokensWorker, &W)) { 4302ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek fprintf(stderr, "libclang: crash detected while annotating tokens\n"); 4303ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek } 4304fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 4305fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} // end: extern "C" 4306fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 4307fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor//===----------------------------------------------------------------------===// 430816b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek// Operations for querying linkage of a cursor. 430916b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek//===----------------------------------------------------------------------===// 431016b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek 431116b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenekextern "C" { 431216b4259aecaa22b642d35d36fd89965ed700c1e0Ted KremenekCXLinkageKind clang_getCursorLinkage(CXCursor cursor) { 43130396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (!clang_isDeclaration(cursor.kind)) 43140396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor return CXLinkage_Invalid; 43150396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor 431616b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek Decl *D = cxcursor::getCursorDecl(cursor); 431716b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D)) 431816b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek switch (ND->getLinkage()) { 431916b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case NoLinkage: return CXLinkage_NoLinkage; 432016b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case InternalLinkage: return CXLinkage_Internal; 432116b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case UniqueExternalLinkage: return CXLinkage_UniqueExternal; 432216b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case ExternalLinkage: return CXLinkage_External; 432316b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek }; 432416b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek 432516b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek return CXLinkage_Invalid; 432616b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek} 432716b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek} // end: extern "C" 432816b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek 432916b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek//===----------------------------------------------------------------------===// 433045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek// Operations for querying language of a cursor. 433145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek//===----------------------------------------------------------------------===// 433245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 433345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenekstatic CXLanguageKind getDeclLanguage(const Decl *D) { 433445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek switch (D->getKind()) { 433545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek default: 433645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek break; 433745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ImplicitParam: 433845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCAtDefsField: 433945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCCategory: 434045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCCategoryImpl: 434145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCClass: 434245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCCompatibleAlias: 434345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCForwardProtocol: 434445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCImplementation: 434545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCInterface: 434645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCIvar: 434745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCMethod: 434845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCProperty: 434945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCPropertyImpl: 435045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCProtocol: 435145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_ObjC; 435245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXConstructor: 435345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXConversion: 435445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXDestructor: 435545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXMethod: 435645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXRecord: 435745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ClassTemplate: 435845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ClassTemplatePartialSpecialization: 435945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ClassTemplateSpecialization: 436045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::Friend: 436145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::FriendTemplate: 436245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::FunctionTemplate: 436345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::LinkageSpec: 436445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::Namespace: 436545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::NamespaceAlias: 436645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::NonTypeTemplateParm: 436745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::StaticAssert: 436845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::TemplateTemplateParm: 436945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::TemplateTypeParm: 437045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UnresolvedUsingTypename: 437145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UnresolvedUsingValue: 437245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::Using: 437345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UsingDirective: 437445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UsingShadow: 437545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_CPlusPlus; 437645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek } 437745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 437845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_C; 437945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek} 438045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 438145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenekextern "C" { 438258ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 438358ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregorenum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) { 438458ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor if (clang_isDeclaration(cursor.kind)) 438558ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor if (Decl *D = cxcursor::getCursorDecl(cursor)) { 438658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor if (D->hasAttr<UnavailableAttr>() || 438758ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())) 438858ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor return CXAvailability_Available; 438958ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 439058ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor if (D->hasAttr<DeprecatedAttr>()) 439158ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor return CXAvailability_Deprecated; 439258ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor } 439358ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 439458ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor return CXAvailability_Available; 439558ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor} 439658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 439745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted KremenekCXLanguageKind clang_getCursorLanguage(CXCursor cursor) { 439845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek if (clang_isDeclaration(cursor.kind)) 439945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return getDeclLanguage(cxcursor::getCursorDecl(cursor)); 440045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 440145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_Invalid; 440245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek} 44032be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 44042be5bc9ad3981347a000742f81b91ab3080f1214Douglas GregorCXCursor clang_getCursorSemanticParent(CXCursor cursor) { 44052be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (clang_isDeclaration(cursor.kind)) { 44062be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (Decl *D = getCursorDecl(cursor)) { 44072be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor DeclContext *DC = D->getDeclContext(); 44082be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return MakeCXCursor(cast<Decl>(DC), getCursorASTUnit(cursor)); 44092be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 44102be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 44112be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 44122be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) { 44132be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (Decl *D = getCursorDecl(cursor)) 44142be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return MakeCXCursor(D, getCursorASTUnit(cursor)); 44152be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 44162be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 44172be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return clang_getNullCursor(); 44182be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor} 44192be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 44202be5bc9ad3981347a000742f81b91ab3080f1214Douglas GregorCXCursor clang_getCursorLexicalParent(CXCursor cursor) { 44212be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (clang_isDeclaration(cursor.kind)) { 44222be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (Decl *D = getCursorDecl(cursor)) { 44232be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor DeclContext *DC = D->getLexicalDeclContext(); 44242be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return MakeCXCursor(cast<Decl>(DC), getCursorASTUnit(cursor)); 44252be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 44262be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 44272be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 44282be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor // FIXME: Note that we can't easily compute the lexical context of a 44292be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor // statement or expression, so we return nothing. 44302be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return clang_getNullCursor(); 44312be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor} 44322be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 44339f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorstatic void CollectOverriddenMethods(DeclContext *Ctx, 44349f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor ObjCMethodDecl *Method, 44359f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) { 44369f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!Ctx) 44379f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 44389f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 44399f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // If we have a class or category implementation, jump straight to the 44409f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // interface. 44419f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx)) 44429f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods); 44439f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 44449f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx); 44459f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!Container) 44469f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 44479f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 44489f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // Check whether we have a matching method at this level. 44499f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(), 44509f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Method->isInstanceMethod())) 44519f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (Method != Overridden) { 44529f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // We found an override at this level; there is no need to look 44539f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // into other protocols or categories. 44549f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Methods.push_back(Overridden); 44559f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 44569f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 44579f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 44589f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { 44599f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(), 44609f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor PEnd = Protocol->protocol_end(); 44619f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor P != PEnd; ++P) 44629f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(*P, Method, Methods); 44639f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 44649f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 44659f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) { 44669f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(), 44679f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor PEnd = Category->protocol_end(); 44689f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor P != PEnd; ++P) 44699f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(*P, Method, Methods); 44709f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 44719f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 44729f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) { 44739f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(), 44749f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor PEnd = Interface->protocol_end(); 44759f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor P != PEnd; ++P) 44769f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(*P, Method, Methods); 44779f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 44789f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCCategoryDecl *Category = Interface->getCategoryList(); 44799f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Category; Category = Category->getNextClassCategory()) 44809f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(Category, Method, Methods); 44819f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 44829f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // We only look into the superclass if we haven't found anything yet. 44839f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (Methods.empty()) 44849f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) 44859f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return CollectOverriddenMethods(Super, Method, Methods); 44869f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 44879f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor} 44889f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 44899f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorvoid clang_getOverriddenCursors(CXCursor cursor, 44909f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CXCursor **overridden, 44919f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor unsigned *num_overridden) { 44929f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (overridden) 44939f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *overridden = 0; 44949f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (num_overridden) 44959f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *num_overridden = 0; 44969f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!overridden || !num_overridden) 44979f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 44989f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 44999f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!clang_isDeclaration(cursor.kind)) 45009f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 45019f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 45029f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Decl *D = getCursorDecl(cursor); 45039f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!D) 45049f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 45059f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 45069f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // Handle C++ member functions. 45079f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor ASTUnit *CXXUnit = getCursorASTUnit(cursor); 45089f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) { 45099f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *num_overridden = CXXMethod->size_overridden_methods(); 45109f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!*num_overridden) 45119f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 45129f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 45139f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *overridden = new CXCursor [*num_overridden]; 45149f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor unsigned I = 0; 45159f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (CXXMethodDecl::method_iterator 45169f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor M = CXXMethod->begin_overridden_methods(), 45179f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor MEnd = CXXMethod->end_overridden_methods(); 45189f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor M != MEnd; (void)++M, ++I) 45199f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), CXXUnit); 45209f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 45219f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 45229f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 45239f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D); 45249f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!Method) 45259f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 45269f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 45279f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // Handle Objective-C methods. 45289f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor llvm::SmallVector<ObjCMethodDecl *, 4> Methods; 45299f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(Method->getDeclContext(), Method, Methods); 45309f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 45319f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (Methods.empty()) 45329f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 45339f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 45349f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *num_overridden = Methods.size(); 45359f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *overridden = new CXCursor [Methods.size()]; 45369f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (unsigned I = 0, N = Methods.size(); I != N; ++I) 45379f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor (*overridden)[I] = MakeCXCursor(Methods[I], CXXUnit); 45389f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor} 45399f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 45409f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorvoid clang_disposeOverriddenCursors(CXCursor *overridden) { 45419f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor delete [] overridden; 45429f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor} 45439f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 4544ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas GregorCXFile clang_getIncludedFile(CXCursor cursor) { 4545ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (cursor.kind != CXCursor_InclusionDirective) 4546ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return 0; 4547ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 4548ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor InclusionDirective *ID = getCursorInclusionDirective(cursor); 4549ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return (void *)ID->getFile(); 4550ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor} 4551ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 455245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek} // end: extern "C" 455345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 45549ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek 45559ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek//===----------------------------------------------------------------------===// 45569ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek// C++ AST instrospection. 45579ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek//===----------------------------------------------------------------------===// 45589ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek 45599ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenekextern "C" { 45609ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenekunsigned clang_CXXMethod_isStatic(CXCursor C) { 45619ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek if (!clang_isDeclaration(C.kind)) 45629ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek return 0; 456349f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor 456449f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor CXXMethodDecl *Method = 0; 456549f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor Decl *D = cxcursor::getCursorDecl(C); 456649f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D)) 456749f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); 456849f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor else 456949f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor Method = dyn_cast_or_null<CXXMethodDecl>(D); 457049f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor return (Method && Method->isStatic()) ? 1 : 0; 457140b492a43bac3ed0c465772aa6921d011cfc273fTed Kremenek} 4572b12903e1a4b8d1b611b8c7e4f910665d628e68cdTed Kremenek 45739ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek} // end: extern "C" 45749ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek 457545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek//===----------------------------------------------------------------------===// 457695f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek// Attribute introspection. 457795f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek//===----------------------------------------------------------------------===// 457895f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 457995f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenekextern "C" { 458095f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted KremenekCXType clang_getIBOutletCollectionType(CXCursor C) { 458195f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek if (C.kind != CXCursor_IBOutletCollectionAttr) 458295f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek return cxtype::MakeCXType(QualType(), cxcursor::getCursorASTUnit(C)); 458395f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 458495f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek IBOutletCollectionAttr *A = 458595f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C)); 458695f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 458795f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorASTUnit(C)); 458895f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek} 458995f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek} // end: extern "C" 459095f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 459195f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek//===----------------------------------------------------------------------===// 4592fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek// CXString Operations. 4593fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 4594fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 4595fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekextern "C" { 4596fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekconst char *clang_getCString(CXString string) { 4597fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return string.Spelling; 4598fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} 45994ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff 4600fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekvoid clang_disposeString(CXString string) { 4601fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (string.MustFreeString && string.Spelling) 4602fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek free((void*)string.Spelling); 4603fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} 460404bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek 4605fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C" 460604bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek 4607ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremeneknamespace clang { namespace cxstring { 4608ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted KremenekCXString createCXString(const char *String, bool DupString){ 4609ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek CXString Str; 4610ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek if (DupString) { 4611ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Str.Spelling = strdup(String); 4612ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Str.MustFreeString = 1; 4613ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek } else { 4614ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Str.Spelling = String; 4615ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Str.MustFreeString = 0; 4616ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek } 4617ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return Str; 4618ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek} 4619ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek 4620ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted KremenekCXString createCXString(llvm::StringRef String, bool DupString) { 4621ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek CXString Result; 4622ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek if (DupString || (!String.empty() && String.data()[String.size()] != 0)) { 4623ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek char *Spelling = (char *)malloc(String.size() + 1); 4624ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek memmove(Spelling, String.data(), String.size()); 4625ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Spelling[String.size()] = 0; 4626ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Result.Spelling = Spelling; 4627ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Result.MustFreeString = 1; 4628ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek } else { 4629ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Result.Spelling = String.data(); 4630ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Result.MustFreeString = 0; 4631ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek } 4632ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return Result; 4633ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek} 4634ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek}} 4635ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek 463604bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek//===----------------------------------------------------------------------===// 463704bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek// Misc. utility functions. 463804bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek//===----------------------------------------------------------------------===// 4639f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4640abdce7abc8a22dd2fe79a05c0b71864039bd8296Daniel Dunbar/// Default to using an 8 MB stack size on "safety" threads. 4641abdce7abc8a22dd2fe79a05c0b71864039bd8296Daniel Dunbarstatic unsigned SafetyStackThreadSize = 8 << 20; 4642bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 4643bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarnamespace clang { 4644bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 4645bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarbool RunSafely(llvm::CrashRecoveryContext &CRC, 4646bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar void (*Fn)(void*), void *UserData) { 4647bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar if (unsigned Size = GetSafetyThreadStackSize()) 4648bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar return CRC.RunSafelyOnThread(Fn, UserData, Size); 4649bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar return CRC.RunSafely(Fn, UserData); 4650bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar} 4651bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 4652bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarunsigned GetSafetyThreadStackSize() { 4653bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar return SafetyStackThreadSize; 4654bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar} 4655bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 4656bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarvoid SetSafetyThreadStackSize(unsigned Value) { 4657bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar SafetyStackThreadSize = Value; 4658bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar} 4659bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 4660bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar} 4661bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 466204bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenekextern "C" { 466304bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek 4664a2a9d6e4e5b6001b86b7dfc5db1ea296ce29a3d3Ted KremenekCXString clang_getClangVersion() { 4665ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(getClangFullVersion()); 466604bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek} 466704bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek 466804bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek} // end: extern "C" 4669