CIndex.cpp revision 18aa2ff4641847d7f8866e8c5912d4d0ddb858ce
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" 170a90d32523bfe5fa63e11b648686c9699f786d15Ted Kremenek#include "CXTranslationUnit.h" 18ed122735639d83c10f18c28c7fd117bfcd0f62cbTed Kremenek#include "CXString.h" 1995f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek#include "CXType.h" 20a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek#include "CXSourceLocation.h" 215352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor#include "CIndexDiagnostic.h" 22ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek 2304bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek#include "clang/Basic/Version.h" 24936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor 2550398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff#include "clang/AST/DeclVisitor.h" 26fb5704295c6137685a7b90b92cd6b958028740c8Steve Naroff#include "clang/AST/StmtVisitor.h" 277d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor#include "clang/AST/TypeLocVisitor.h" 28b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Basic/Diagnostic.h" 29b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Frontend/ASTUnit.h" 30b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Frontend/CompilerInstance.h" 31936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor#include "clang/Frontend/FrontendDiagnostic.h" 32d8210650ed948de65a08a8daf16d291b747717c4Ted Kremenek#include "clang/Lex/Lexer.h" 33dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor#include "clang/Lex/HeaderSearch.h" 34b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Lex/PreprocessingRecord.h" 3533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor#include "clang/Lex/Preprocessor.h" 36a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor#include "llvm/ADT/STLExtras.h" 37d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek#include "llvm/ADT/Optional.h" 38f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor#include "llvm/ADT/StringSwitch.h" 39d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek#include "clang/Analysis/Support/SaveAndRestore.h" 40c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar#include "llvm/Support/CrashRecoveryContext.h" 4148615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar#include "llvm/Support/PrettyStackTrace.h" 4202465750c8c3fa96b1e7e596b02297e24361dc4fDouglas Gregor#include "llvm/Support/MemoryBuffer.h" 43358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor#include "llvm/Support/raw_ostream.h" 447a07fcb8f10fe45ea65a0a41798eb1c40777bde4Douglas Gregor#include "llvm/Support/Timer.h" 4503013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Mutex.h" 4603013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Program.h" 4703013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Signals.h" 4803013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Threading.h" 4937f1ea0eb08a00fa90edbecb427cfbb50ca0f4d0Ted Kremenek#include "llvm/Support/Compiler.h" 50fc0622155fa61349698a8fd0053773c37d9f7ac4Ted Kremenek 5150398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroffusing namespace clang; 5216c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenekusing namespace clang::cxcursor; 53ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenekusing namespace clang::cxstring; 5450398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff 55a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenekstatic CXTranslationUnit MakeCXTranslationUnit(ASTUnit *TU) { 56a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek if (!TU) 57a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return 0; 58a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXTranslationUnit D = new CXTranslationUnitImpl(); 59a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek D->TUData = TU; 60a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek D->StringPool = createCXStringPool(); 61a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return D; 62a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek} 63a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 6433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \brief The result of comparing two source ranges. 6533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregorenum RangeComparisonResult { 6633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief Either the ranges overlap or one of the ranges is invalid. 6733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor RangeOverlap, 68f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 6933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The first range ends before the second range starts. 7033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor RangeBefore, 71f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 7233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The first range starts after the second range ends. 7333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor RangeAfter 7433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor}; 7533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 76f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek/// \brief Compare two source ranges to determine their relative position in 7733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// the translation unit. 78f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekstatic RangeComparisonResult RangeCompare(SourceManager &SM, 79f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek SourceRange R1, 8033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor SourceRange R2) { 8133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor assert(R1.isValid() && "First range is invalid?"); 8233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor assert(R2.isValid() && "Second range is invalid?"); 83a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (R1.getEnd() != R2.getBegin() && 84d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin())) 8533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return RangeBefore; 86a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (R2.getEnd() != R1.getBegin() && 87d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin())) 8833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return RangeAfter; 8933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return RangeOverlap; 9033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor} 9133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 92fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek/// \brief Determine if a source location falls within, before, or after a 93fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek/// a given source range. 94fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekstatic RangeComparisonResult LocationCompare(SourceManager &SM, 95fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation L, SourceRange R) { 96fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek assert(R.isValid() && "First range is invalid?"); 97fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek assert(L.isValid() && "Second range is invalid?"); 98a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (L == R.getBegin() || L == R.getEnd()) 99fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeOverlap; 100fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (SM.isBeforeInTranslationUnit(L, R.getBegin())) 101fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeBefore; 102fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (SM.isBeforeInTranslationUnit(R.getEnd(), L)) 103fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeAfter; 104fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeOverlap; 105fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek} 106fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 10776dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// \brief Translate a Clang source range into a CIndex source range. 10876dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// 10976dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// Clang internally represents ranges where the end location points to the 11076dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// start of the token at the end. However, for external clients it is more 11176dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// useful to have a CXSourceRange be a proper half-open interval. This routine 11276dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// does the appropriate translation. 113f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed KremenekCXSourceRange cxloc::translateSourceRange(const SourceManager &SM, 11476dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar const LangOptions &LangOpts, 1150a76aae8c03cb7dd7bdbe683485560afaf695959Chris Lattner const CharSourceRange &R) { 11676dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar // We want the last character in this location, so we will adjust the 1176a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor // location accordingly. 11876dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar SourceLocation EndLoc = R.getEnd(); 119a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (EndLoc.isValid() && EndLoc.isMacroID()) 120edc3dccece244a584f8ebdb81da6c962c08e79beChandler Carruth EndLoc = SM.getExpansionRange(EndLoc).second; 1210a76aae8c03cb7dd7bdbe683485560afaf695959Chris Lattner if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) { 1226a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts); 12376dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar EndLoc = EndLoc.getFileLocWithOffset(Length); 12476dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar } 12576dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar 12676dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts }, 12776dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar R.getBegin().getRawEncoding(), 12876dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar EndLoc.getRawEncoding() }; 12976dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar return Result; 13076dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar} 1311db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 1328a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek//===----------------------------------------------------------------------===// 13333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor// Cursor visitor. 1348a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek//===----------------------------------------------------------------------===// 1358a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek 13689922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroffnamespace { 137c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 138c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekclass VisitorJob { 139c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekpublic: 140cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind, 141e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek TypeLocVisitKind, OverloadExprPartsKind, 14260608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek DeclRefExprPartsKind, LabelRefVisitKind, 143f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek ExplicitTemplateArgsVisitKind, 144f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor NestedNameSpecifierLocVisitKind, 145cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek DeclarationNameInfoVisitKind, 14694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor MemberRefVisitKind, SizeOfPackExprPartsKind }; 147c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekprotected: 148f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek void *data[3]; 149c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek CXCursor parent; 150c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek Kind K; 151f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0) 152f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek : parent(C), K(k) { 153f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek data[0] = d1; 154f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek data[1] = d2; 155f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek data[2] = d3; 156f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek } 157c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekpublic: 158c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek Kind getKind() const { return K; } 159c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek const CXCursor &getParent() const { return parent; } 160c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek static bool classof(VisitorJob *VJ) { return true; } 161c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek}; 162c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 1635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnertypedef SmallVector<VisitorJob, 10> VisitorWorkList; 164c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 165b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor// Cursor visitor. 1667d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorclass CursorVisitor : public DeclVisitor<CursorVisitor, bool>, 167cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek public TypeLocVisitor<CursorVisitor, bool> 1687d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor{ 16933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The translation unit we are traversing. 170a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXTranslationUnit TU; 171a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *AU; 172f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 17333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The parent cursor whose children we are traversing. 174b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXCursor Parent; 175f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 17633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The declaration that serves at the parent of any statement or 17733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// expression nodes. 178f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor Decl *StmtParent; 179f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 18033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The visitor function. 181b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXCursorVisitor Visitor; 182f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 18333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The opaque client data, to be passed along to the visitor. 184b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXClientData ClientData; 185f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 18604a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor /// \brief Whether we should visit the preprocessing record entries last, 18704a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor /// after visiting other declarations. 18804a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor bool VisitPreprocessorLast; 18904a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor 19033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief When valid, a source range to which the cursor should restrict 19133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// its search. 19233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor SourceRange RegionOfInterest; 193f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 194d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // FIXME: Eventually remove. This part of a hack to support proper 195d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // iteration over all Decls contained lexically within an ObjC container. 196d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator *DI_current; 197d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator DE_current; 198d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 199d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek // Cache of pre-allocated worklists for data-recursion walk of Stmts. 2005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<VisitorWorkList*, 5> WorkListFreeList; 2015f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<VisitorWorkList*, 5> WorkListCache; 202d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek 203b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor using DeclVisitor<CursorVisitor, bool>::Visit; 2047d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor using TypeLocVisitor<CursorVisitor, bool>::Visit; 205f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 206f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek /// \brief Determine whether this particular source range comes before, comes 207f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek /// after, or overlaps the region of interest. 20833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// 209d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar /// \param R a half-open source range retrieved from the abstract syntax tree. 210f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek RangeComparisonResult CompareRegionOfInterest(SourceRange R); 211f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2120f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek class SetParentRAII { 2130f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek CXCursor &Parent; 2140f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek Decl *&StmtParent; 2150f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek CXCursor OldParent; 2160f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 2170f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek public: 2180f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent) 2190f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) 2200f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek { 2210f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek Parent = NewParent; 2220f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (clang_isDeclaration(Parent.kind)) 2230f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek StmtParent = getCursorDecl(Parent); 2240f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek } 2250f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 2260f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek ~SetParentRAII() { 2270f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek Parent = OldParent; 2280f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (clang_isDeclaration(Parent.kind)) 2290f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek StmtParent = getCursorDecl(Parent); 2300f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek } 2310f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek }; 2320f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 233b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorpublic: 234a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor, 235a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXClientData ClientData, 23604a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor bool VisitPreprocessorLast, 23733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor SourceRange RegionOfInterest = SourceRange()) 238a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)), 239a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek Visitor(Visitor), ClientData(ClientData), 24008e0bc16b3312c27e87d33be7dcf3d4fe5bdd2e2Douglas Gregor VisitPreprocessorLast(VisitPreprocessorLast), 24104a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor RegionOfInterest(RegionOfInterest), DI_current(0) 242b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor { 243b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.kind = CXCursor_NoDeclFound; 244b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.data[0] = 0; 245b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.data[1] = 0; 246b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.data[2] = 0; 247f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor StmtParent = 0; 248b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 249f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 250d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek ~CursorVisitor() { 251d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek // Free the pre-allocated worklists for data-recursion. 2525f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (SmallVectorImpl<VisitorWorkList*>::iterator 253d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) { 254d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek delete *I; 255d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek } 256d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek } 257d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek 258a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); } 259a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXTranslationUnit getTU() const { return TU; } 260ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek 26133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false); 262788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 2634c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor bool visitPreprocessedEntitiesInRegion(); 2644c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 2654c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor template<typename InputIterator> 2664c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor bool visitPreprocessedEntitiesInRegion(InputIterator First, 2674c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor InputIterator Last); 2684c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 2694c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor template<typename InputIterator> 2704c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor bool visitPreprocessedEntities(InputIterator First, InputIterator Last); 271788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 272b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor bool VisitChildren(CXCursor Parent); 273f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2747d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor // Declaration visitors 275162e1c1b487352434552147967c3dd296ebee2f7Richard Smith bool VisitTypeAliasDecl(TypeAliasDecl *D); 27609dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek bool VisitAttributes(Decl *D); 2771ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek bool VisitBlockDecl(BlockDecl *B); 2783064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek bool VisitCXXRecordDecl(CXXRecordDecl *D); 279d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek llvm::Optional<bool> shouldVisitCursor(CXCursor C); 280b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor bool VisitDeclContext(DeclContext *DC); 28179758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitTranslationUnitDecl(TranslationUnitDecl *D); 28279758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitTypedefDecl(TypedefDecl *D); 28379758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitTagDecl(TagDecl *D); 2840ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D); 28574dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor bool VisitClassTemplatePartialSpecializationDecl( 28674dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor ClassTemplatePartialSpecializationDecl *D); 287fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); 2884540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitEnumConstantDecl(EnumConstantDecl *D); 28979758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitDeclaratorDecl(DeclaratorDecl *DD); 2904540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitFunctionDecl(FunctionDecl *ND); 29179758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitFieldDecl(FieldDecl *D); 29279758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitVarDecl(VarDecl *); 29384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); 294fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D); 29539d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor bool VisitClassTemplateDecl(ClassTemplateDecl *D); 29684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); 29779758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCMethodDecl(ObjCMethodDecl *ND); 2984540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitObjCContainerDecl(ObjCContainerDecl *D); 29979758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND); 30079758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID); 30123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD); 30279758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); 3034540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitObjCImplDecl(ObjCImplDecl *D); 30479758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); 3051ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor bool VisitObjCImplementationDecl(ObjCImplementationDecl *D); 30679758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations. 30779758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); 30879758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCClassDecl(ObjCClassDecl *D); 309a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD); 310a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek bool VisitLinkageSpecDecl(LinkageSpecDecl *D); 3118f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek bool VisitNamespaceDecl(NamespaceDecl *D); 3126931900f43cea558c6974075256c07728dbfecc6Douglas Gregor bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D); 3130a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D); 3147e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor bool VisitUsingDecl(UsingDecl *D); 3157e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); 3167e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); 3170a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 31801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Name visitor 31901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor bool VisitDeclarationNameInfo(DeclarationNameInfo Name); 320c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range); 321dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); 32201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 323fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // Template visitors 324fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateParameters(const TemplateParameterList *Params); 3250b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor bool VisitTemplateName(TemplateName Name, SourceLocation Loc); 326fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL); 327fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 3287d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor // Type visitors 329427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis#define ABSTRACT_TYPELOC(CLASS, PARENT) 330427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis#define TYPELOC(CLASS, PARENT) \ 331427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); 332427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis#include "clang/AST/TypeLocNodes.def" 333427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis 334f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitTagTypeLoc(TagTypeLoc TL); 335f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitArrayTypeLoc(ArrayTypeLoc TL); 336427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false); 337427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis 338c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Data-recursive visitor functions. 339c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek bool IsInRegionOfInterest(CXCursor C); 340c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek bool RunVisitorWorkList(VisitorWorkList &WL); 341c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek void EnqueueWorkList(VisitorWorkList &WL, Stmt *S); 342cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S); 343b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor}; 344f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 345b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} // end anonymous namespace 3460d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 347a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorstatic SourceRange getRawCursorExtent(CXCursor C); 3486653798ff5ce6deb58112777e21307ccc453133dDouglas Gregorstatic SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr); 3496653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor 350a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 35133e9abd21083a0191a7676a04b497006d2da184dDouglas GregorRangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) { 352a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return RangeCompare(AU->getSourceManager(), R, RegionOfInterest); 35333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor} 35433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 355b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \brief Visit the given cursor and, if requested by the visitor, 356b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// its children. 357b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// 35833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \param Cursor the cursor to visit. 35933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// 36033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \param CheckRegionOfInterest if true, then the caller already checked that 36133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// this cursor is within the region of interest. 36233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// 363b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \returns true if the visitation should be aborted, false if it 364b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// should continue. 36533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregorbool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) { 366b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isInvalid(Cursor.kind)) 367b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 368f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 369b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isDeclaration(Cursor.kind)) { 370b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Decl *D = getCursorDecl(Cursor); 371b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor assert(D && "Invalid declaration cursor"); 372b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (D->isImplicit()) 373b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 374b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 3750d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 37633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // If we have a range of interest, and this cursor doesn't intersect with it, 37733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // we're done. 37833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) { 379a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor SourceRange Range = getRawCursorExtent(Cursor); 380f408f32aa9ae3d97bc656267dc5d78fa7d03499bDaniel Dunbar if (Range.isInvalid() || CompareRegionOfInterest(Range)) 38133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return false; 38233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor } 383f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 384b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor switch (Visitor(Cursor, Parent, ClientData)) { 385b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor case CXChildVisit_Break: 386b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 3870d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 388b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor case CXChildVisit_Continue: 389b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 3902e331b938b38057e333fab0ba841130ea8467794Douglas Gregor 391b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor case CXChildVisit_Recurse: 392b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return VisitChildren(Cursor); 393b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 3940d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 395fd64377225a6a140bddb3f997d52a036486f9360Douglas Gregor return false; 396b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} 3970d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 3984c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregorbool CursorVisitor::visitPreprocessedEntitiesInRegion() { 399788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor PreprocessingRecord &PPRec 400a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek = *AU->getPreprocessor().getPreprocessingRecord(); 401788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 402788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor bool OnlyLocalDecls 40332038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor = !AU->isMainFileAST() && AU->getOnlyLocalDecls(); 40432038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor 40532038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor if (OnlyLocalDecls && RegionOfInterest.isValid()) { 40632038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor // If we would only look at local declarations but we have a region of 40732038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor // interest, check whether that region of interest is in the main file. 40832038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor // If not, we should traverse all declarations. 40932038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor // FIXME: My kingdom for a proper binary search approach to finding 41032038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor // cursors! 41132038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor std::pair<FileID, unsigned> Location 412e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth = AU->getSourceManager().getDecomposedExpansionLoc( 41332038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor RegionOfInterest.getBegin()); 41432038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor if (Location.first != AU->getSourceManager().getMainFileID()) 41532038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor OnlyLocalDecls = false; 41632038bb8486a1f31e8bd8e19ef388049669e9ed2Douglas Gregor } 417788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 41889d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor PreprocessingRecord::iterator StartEntity, EndEntity; 4194c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor if (OnlyLocalDecls && AU->pp_entity_begin() != AU->pp_entity_end()) 4204c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor return visitPreprocessedEntitiesInRegion(AU->pp_entity_begin(), 4214c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor AU->pp_entity_end()); 4224c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor else 4234c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor return visitPreprocessedEntitiesInRegion(PPRec.begin(), PPRec.end()); 4244c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor} 4254c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 4264c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregortemplate<typename InputIterator> 4274c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregorbool CursorVisitor::visitPreprocessedEntitiesInRegion(InputIterator First, 4284c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor InputIterator Last) { 429788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // There is no region of interest; we have to walk everything. 430788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (RegionOfInterest.isInvalid()) 4314c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor return visitPreprocessedEntities(First, Last); 4324c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 433788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // Find the file in which the region of interest lands. 434a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek SourceManager &SM = AU->getSourceManager(); 435788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor std::pair<FileID, unsigned> Begin 436e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth = SM.getDecomposedExpansionLoc(RegionOfInterest.getBegin()); 437788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor std::pair<FileID, unsigned> End 438e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth = SM.getDecomposedExpansionLoc(RegionOfInterest.getEnd()); 439788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 440788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // The region of interest spans files; we have to walk everything. 441788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (Begin.first != End.first) 4424c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor return visitPreprocessedEntities(First, Last); 4434c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 444788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap 4454c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor = AU->getPreprocessedEntitiesByFile(); 446788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (ByFileMap.empty()) { 447788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // Build the mapping from files to sets of preprocessed entities. 4484c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor for (; First != Last; ++First) { 449788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor std::pair<FileID, unsigned> P 450e7b2b6e87dbe5b1207f77b6ff9c210a02f95bb39Chandler Carruth = SM.getDecomposedExpansionLoc((*First)->getSourceRange().getBegin()); 4514c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 4524c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor ByFileMap[P.first].push_back(*First); 4534c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor } 4544c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor } 4554c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 4564c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor return visitPreprocessedEntities(ByFileMap[Begin.first].begin(), 4574c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor ByFileMap[Begin.first].end()); 4584c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor} 4594c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 4604c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregortemplate<typename InputIterator> 4614c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregorbool CursorVisitor::visitPreprocessedEntities(InputIterator First, 4624c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor InputIterator Last) { 4634c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor for (; First != Last; ++First) { 4644c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor if (MacroExpansion *ME = dyn_cast<MacroExpansion>(*First)) { 4654c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor if (Visit(MakeMacroExpansionCursor(ME, TU))) 4664c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor return true; 4674c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 4684c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor continue; 4694c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor } 4704c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 4714c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*First)) { 4724c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor if (Visit(MakeMacroDefinitionCursor(MD, TU))) 4734c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor return true; 47489d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor 4754c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor continue; 4764c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor } 4774c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 4784c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*First)) { 4794c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor if (Visit(MakeInclusionDirectiveCursor(ID, TU))) 4804c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor return true; 4814c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor 4824c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor continue; 483788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor } 484788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor } 485788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 4864c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor return false; 487788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor} 488788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 489b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \brief Visit the children of the given cursor. 490a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek/// 491b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \returns true if the visitation should be aborted, false if it 492b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// should continue. 493f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekbool CursorVisitor::VisitChildren(CXCursor Cursor) { 494c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor if (clang_isReference(Cursor.kind) && 495c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor Cursor.kind != CXCursor_CXXBaseSpecifier) { 496a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor // By definition, references have no children. 497a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return false; 498a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor } 499f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 500f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek // Set the Parent field to Cursor, then back to its old value once we're 501b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor // done. 5020f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek SetParentRAII SetParent(Parent, StmtParent, Cursor); 503f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 504b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isDeclaration(Cursor.kind)) { 505b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Decl *D = getCursorDecl(Cursor); 50606d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor if (!D) 50706d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor return false; 50806d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor 509539311e0221df256c70c1c3080c8af847cd29dffTed Kremenek return VisitAttributes(D) || Visit(D); 510b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 511f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 51206d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor if (clang_isStatement(Cursor.kind)) { 51306d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor if (Stmt *S = getCursorStmt(Cursor)) 51406d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor return Visit(S); 51506d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor 51606d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor return false; 51706d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor } 51806d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor 51906d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor if (clang_isExpression(Cursor.kind)) { 52006d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor if (Expr *E = getCursorExpr(Cursor)) 52106d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor return Visit(E); 52206d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor 52306d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor return false; 52406d9b1ad0bca7230cbae57e3e3207dda77a9eac0Douglas Gregor } 525f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 526b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isTranslationUnit(Cursor.kind)) { 527a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXTranslationUnit tu = getCursorTU(Cursor); 528a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData); 52904a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor 53004a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast }; 53104a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor for (unsigned I = 0; I != 2; ++I) { 53204a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor if (VisitOrder[I]) { 53304a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() && 53404a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor RegionOfInterest.isInvalid()) { 53504a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(), 53604a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor TLEnd = CXXUnit->top_level_end(); 53704a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor TL != TLEnd; ++TL) { 53804a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor if (Visit(MakeCXCursor(*TL, tu), true)) 53904a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor return true; 54004a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor } 54104a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor } else if (VisitDeclContext( 54204a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor CXXUnit->getASTContext().getTranslationUnitDecl())) 5437b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor return true; 54404a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor continue; 5457b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor } 5463178cb674ac8c3b59e1791e14d38d48619a1b621Bob Wilson 54704a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor // Walk the preprocessing record. 5484c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor if (CXXUnit->getPreprocessor().getPreprocessingRecord()) 5494c30bb148b53c8063e940ca3e049ba4d270dc9d5Douglas Gregor visitPreprocessedEntitiesInRegion(); 5500396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor } 55104a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor 5527b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor return false; 553b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 554f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 555c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor if (Cursor.kind == CXCursor_CXXBaseSpecifier) { 556c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) { 557c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) { 558c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor return Visit(BaseTSInfo->getTypeLoc()); 559c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor } 560c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor } 561c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor } 562c314aa484524c6a310a51e7b83bc194774e95e90Douglas Gregor 563b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor // Nothing to visit at the moment. 564b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 565dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 566dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 5671ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenekbool CursorVisitor::VisitBlockDecl(BlockDecl *B) { 56813c8ccb59b38e9e7133f1c80a00f210b6514a0b1Douglas Gregor if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten()) 56913c8ccb59b38e9e7133f1c80a00f210b6514a0b1Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 57013c8ccb59b38e9e7133f1c80a00f210b6514a0b1Douglas Gregor return true; 5711ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek 572664cffd330611d78fc0286f539589920a37ca328Ted Kremenek if (Stmt *Body = B->getBody()) 573664cffd330611d78fc0286f539589920a37ca328Ted Kremenek return Visit(MakeCXCursor(Body, StmtParent, TU)); 574664cffd330611d78fc0286f539589920a37ca328Ted Kremenek 575664cffd330611d78fc0286f539589920a37ca328Ted Kremenek return false; 5761ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek} 5771ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek 578d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenekllvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) { 579d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (RegionOfInterest.isValid()) { 5806653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager()); 581d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (Range.isInvalid()) 582d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return llvm::Optional<bool>(); 5836653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor 584d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek switch (CompareRegionOfInterest(Range)) { 585d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek case RangeBefore: 586d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // This declaration comes before the region of interest; skip it. 587d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return llvm::Optional<bool>(); 58823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 589d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek case RangeAfter: 590d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // This declaration comes after the region of interest; we're done. 591d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 592d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar 593d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek case RangeOverlap: 594d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // This declaration overlaps the region of interest; visit it. 595d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 596d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 597d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 598d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return true; 599d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek} 600f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 601d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenekbool CursorVisitor::VisitDeclContext(DeclContext *DC) { 602d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); 603f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 604d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // FIXME: Eventually remove. This part of a hack to support proper 605d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // iteration over all Decls contained lexically within an ObjC container. 606d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I); 607d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E); 608f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 609d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek for ( ; I != E; ++I) { 610d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek Decl *D = *I; 611d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (D->getLexicalDeclContext() != DC) 612d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 613d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek CXCursor Cursor = MakeCXCursor(D, TU); 614d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek const llvm::Optional<bool> &V = shouldVisitCursor(Cursor); 615d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.hasValue()) 616d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 617d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.getValue()) 618d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 619d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar if (Visit(Cursor, true)) 620b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 621b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 622b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 623dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 624dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 6251ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) { 6261ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor llvm_unreachable("Translation units are visited directly by Visit()"); 6271ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 6281ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 6291ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 630162e1c1b487352434552147967c3dd296ebee2f7Richard Smithbool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) { 631162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo()) 632162e1c1b487352434552147967c3dd296ebee2f7Richard Smith return Visit(TSInfo->getTypeLoc()); 633162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 634162e1c1b487352434552147967c3dd296ebee2f7Richard Smith return false; 635162e1c1b487352434552147967c3dd296ebee2f7Richard Smith} 636162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 6371ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) { 6381ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo()) 6391ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(TSInfo->getTypeLoc()); 640f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 6411ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 6421ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 6431ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 6441ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTagDecl(TagDecl *D) { 6451ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitDeclContext(D); 6461ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 6471ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 6480ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregorbool CursorVisitor::VisitClassTemplateSpecializationDecl( 6490ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor ClassTemplateSpecializationDecl *D) { 6500ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor bool ShouldVisitBody = false; 6510ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor switch (D->getSpecializationKind()) { 6520ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_Undeclared: 6530ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ImplicitInstantiation: 6540ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor // Nothing to visit 6550ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return false; 6560ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6570ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ExplicitInstantiationDeclaration: 6580ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ExplicitInstantiationDefinition: 6590ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor break; 6600ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6610ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ExplicitSpecialization: 6620ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor ShouldVisitBody = true; 6630ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor break; 6640ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor } 6650ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6660ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor // Visit the template arguments used in the specialization. 6670ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) { 6680ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor TypeLoc TL = SpecType->getTypeLoc(); 6690ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (TemplateSpecializationTypeLoc *TSTLoc 6700ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) { 6710ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I) 6720ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I))) 6730ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return true; 6740ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor } 6750ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor } 6760ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6770ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (ShouldVisitBody && VisitCXXRecordDecl(D)) 6780ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return true; 6790ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6800ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return false; 6810ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor} 6820ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 68374dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregorbool CursorVisitor::VisitClassTemplatePartialSpecializationDecl( 68474dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor ClassTemplatePartialSpecializationDecl *D) { 68574dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor // FIXME: Visit the "outer" template parameter lists on the TagDecl 68674dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor // before visiting these template parameters. 68774dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 68874dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return true; 68974dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor 69074dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor // Visit the partial specialization arguments. 69174dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten(); 69274dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I) 69374dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor if (VisitTemplateArgumentLoc(TemplateArgs[I])) 69474dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return true; 69574dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor 69674dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return VisitCXXRecordDecl(D); 69774dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor} 69874dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor 699fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { 70084b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor // Visit the default argument. 70184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) 70284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo()) 70384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (Visit(DefArg->getTypeLoc())) 70484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 70584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 706fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 707fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 708fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 7091ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) { 7101ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Expr *Init = D->getInitExpr()) 7111ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(MakeCXCursor(Init, StmtParent, TU)); 7121ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 7131ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 7141ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 7157d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorbool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { 7167d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo()) 7177d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor if (Visit(TSInfo->getTypeLoc())) 7187d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor return true; 7197d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 720c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor // Visit the nested-name-specifier, if present. 721c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc()) 722c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor if (VisitNestedNameSpecifierLoc(QualifierLoc)) 723c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor return true; 724c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor 7257d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor return false; 7267d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor} 7277d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 728a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor/// \brief Compare two base or member initializers based on their source order. 729cbb67480094b3bcb5b715acd827cbad55e2a204cSean Huntstatic int CompareCXXCtorInitializers(const void* Xp, const void *Yp) { 730cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer const * const *X 731cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt = static_cast<CXXCtorInitializer const * const *>(Xp); 732cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer const * const *Y 733cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt = static_cast<CXXCtorInitializer const * const *>(Yp); 734a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 735a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if ((*X)->getSourceOrder() < (*Y)->getSourceOrder()) 736a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return -1; 737a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder()) 738a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return 1; 739a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor else 740a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return 0; 741a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor} 742a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 743b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { 74401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) { 74501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Visit the function declaration's syntactic components in the order 74601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // written. This requires a bit of work. 747723df245307a530da5433dfb43accf187dc3e243Abramo Bagnara TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); 74801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL); 74901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 75001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // If we have a function declared directly (without the use of a typedef), 75101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // visit just the return type. Otherwise, just visit the function's type 75201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // now. 75301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) || 75401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor (!FTL && Visit(TL))) 75501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return true; 75601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 757c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit the nested-name-specifier, if present. 758c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc()) 759c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor if (VisitNestedNameSpecifierLoc(QualifierLoc)) 760c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 76101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 76201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Visit the declaration name. 76301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (VisitDeclarationNameInfo(ND->getNameInfo())) 76401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return true; 76501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 76601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // FIXME: Visit explicitly-specified template arguments! 76701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 76801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Visit the function parameters, if we have a function type. 76901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (FTL && VisitFunctionTypeLoc(*FTL, true)) 77001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return true; 77101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 77201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // FIXME: Attributes? 77301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor } 77401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 77510620eb5164e31208fcbf0437cd79ae535ed0559Sean Hunt if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) { 776a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) { 777a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Find the initializers that were written in the source. 7785f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXCtorInitializer *, 4> WrittenInits; 779a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(), 780a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor IEnd = Constructor->init_end(); 781a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor I != IEnd; ++I) { 782a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (!(*I)->isWritten()) 783a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor continue; 784a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 785a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor WrittenInits.push_back(*I); 786a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 787a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 788a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Sort the initializers in source order 789a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(), 790cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt &CompareCXXCtorInitializers); 791a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 792a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Visit the initializers in source order 793a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) { 794cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CXXCtorInitializer *Init = WrittenInits[I]; 79500eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (Init->isAnyMemberInitializer()) { 79600eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (Visit(MakeCursorMemberRef(Init->getAnyMember(), 797a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor Init->getMemberLocation(), TU))) 798a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 799a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) { 800a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Visit(BaseInfo->getTypeLoc())) 801a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 802a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 803a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 804a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Visit the initializer value. 805a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Expr *Initializer = Init->getInit()) 806a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Visit(MakeCXCursor(Initializer, ND, TU))) 807a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 808a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 809a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 810a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 811a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) 812a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 813a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 814f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 815b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 816b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} 817dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 8181ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitFieldDecl(FieldDecl *D) { 8191ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (VisitDeclaratorDecl(D)) 8201ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 821f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8221ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Expr *BitWidth = D->getBitWidth()) 8231ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(MakeCXCursor(BitWidth, StmtParent, TU)); 824f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8251ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 8261ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 8271ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 8281ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitVarDecl(VarDecl *D) { 8291ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (VisitDeclaratorDecl(D)) 8301ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 831f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8321ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Expr *Init = D->getInit()) 8331ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(MakeCXCursor(Init, StmtParent, TU)); 834f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8351ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 8361ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 8371ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 83884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregorbool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { 83984b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (VisitDeclaratorDecl(D)) 84084b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 84184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 84284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) 84384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (Expr *DefArg = D->getDefaultArgument()) 84484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return Visit(MakeCXCursor(DefArg, StmtParent, TU)); 84584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 84684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return false; 84784b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor} 84884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 849fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { 850fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // FIXME: Visit the "outer" template parameter lists on the FunctionDecl 851fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // before visiting these template parameters. 852fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 853fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return true; 854fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 855fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return VisitFunctionDecl(D->getTemplatedDecl()); 856fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 857fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 85839d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregorbool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) { 85939d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor // FIXME: Visit the "outer" template parameter lists on the TagDecl 86039d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor // before visiting these template parameters. 86139d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 86239d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor return true; 86339d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor 86439d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor return VisitCXXRecordDecl(D->getTemplatedDecl()); 86539d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor} 86639d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor 86784b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregorbool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { 86884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 86984b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 87084b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 87184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() && 87284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor VisitTemplateArgumentLoc(D->getDefaultArgument())) 87384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 87484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 87584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return false; 87684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor} 87784b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 8781ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) { 8794bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo()) 8804bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor if (Visit(TSInfo->getTypeLoc())) 8814bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor return true; 8824bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor 883f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek for (ObjCMethodDecl::param_iterator P = ND->param_begin(), 8841ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor PEnd = ND->param_end(); 8851ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor P != PEnd; ++P) { 8861ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Visit(MakeCXCursor(*P, TU))) 8871ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 8881ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor } 889f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8901ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (ND->isThisDeclarationADefinition() && 8911ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) 8921ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 893f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8941ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 8951ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 8961ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 897d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremeneknamespace { 898d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek struct ContainerDeclsSort { 899d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceManager &SM; 900d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek ContainerDeclsSort(SourceManager &sm) : SM(sm) {} 901d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek bool operator()(Decl *A, Decl *B) { 902d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation L_A = A->getLocStart(); 903d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation L_B = B->getLocStart(); 904d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek assert(L_A.isValid() && L_B.isValid()); 905d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return SM.isBeforeInTranslationUnit(L_A, L_B); 906d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 907d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek }; 908d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek} 909d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 910a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregorbool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) { 911d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially 912d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // an @implementation can lexically contain Decls that are not properly 913d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // nested in the AST. When we identify such cases, we need to retrofit 914d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // this nesting here. 915d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!DI_current) 916d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return VisitDeclContext(D); 917d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 918d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Scan the Decls that immediately come after the container 919d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // in the current DeclContext. If any fall within the 920d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // container's lexical region, stash them into a vector 921d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // for later processing. 9225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Decl *, 24> DeclsInContainer; 923d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation EndLoc = D->getSourceRange().getEnd(); 924a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek SourceManager &SM = AU->getSourceManager(); 925d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (EndLoc.isValid()) { 926d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator next = *DI_current; 927d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek while (++next != DE_current) { 928d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek Decl *D_next = *next; 929d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!D_next) 930d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 931d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation L = D_next->getLocStart(); 932d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!L.isValid()) 933d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 934d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (SM.isBeforeInTranslationUnit(L, EndLoc)) { 935d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek *DI_current = next; 936d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclsInContainer.push_back(D_next); 937d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 938d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 939d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 940d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 941d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 942d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 943d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // The common case. 944d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (DeclsInContainer.empty()) 945d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return VisitDeclContext(D); 946d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 947d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Get all the Decls in the DeclContext, and sort them with the 948d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // additional ones we've collected. Then visit them. 949d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end(); 950d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek I!=E; ++I) { 951d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek Decl *subDecl = *I; 9520582c897ec7261b4c6af0fe26dc2a0b6b54d266cTed Kremenek if (!subDecl || subDecl->getLexicalDeclContext() != D || 9530582c897ec7261b4c6af0fe26dc2a0b6b54d266cTed Kremenek subDecl->getLocStart().isInvalid()) 954d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 955d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclsInContainer.push_back(subDecl); 956d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 957d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 958d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Now sort the Decls so that they appear in lexical order. 959d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek std::sort(DeclsInContainer.begin(), DeclsInContainer.end(), 960d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek ContainerDeclsSort(SM)); 961d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 962d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Now visit the decls. 9635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(), 964d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek E = DeclsInContainer.end(); I != E; ++I) { 965d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek CXCursor Cursor = MakeCXCursor(*I, TU); 966d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek const llvm::Optional<bool> &V = shouldVisitCursor(Cursor); 967d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.hasValue()) 968d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 969d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.getValue()) 970d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 971d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (Visit(Cursor, true)) 972d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return true; 973d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 974d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 975a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor} 976a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor 977b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { 978b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(), 979b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor TU))) 980b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 981f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 98278db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin(); 98378db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(), 98478db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor E = ND->protocol_end(); I != E; ++I, ++PL) 985b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 986b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 987f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 988a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return VisitObjCContainerDecl(ND); 989dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 990dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 9911ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { 9921ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin(); 9931ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), 9941ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor E = PID->protocol_end(); I != E; ++I, ++PL) 9951ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 9961ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 997f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 9981ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCContainerDecl(PID); 9991ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 10001ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 100123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenekbool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) { 100283cb94269015bf2770ade71e616c5322ea7e76e1Douglas Gregor if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc())) 1003fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall return true; 1004fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall 100523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // FIXME: This implements a workaround with @property declarations also being 100623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // installed in the DeclContext for the @interface. Eventually this code 100723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // should be removed. 100823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext()); 100923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (!CDecl || !CDecl->IsClassExtension()) 101023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 101123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 101223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCInterfaceDecl *ID = CDecl->getClassInterface(); 101323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (!ID) 101423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 101523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 101623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek IdentifierInfo *PropertyId = PD->getIdentifier(); 101723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCPropertyDecl *prevDecl = 101823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId); 101923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 102023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (!prevDecl) 102123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 102223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 102323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // Visit synthesized methods since they will be skipped when visiting 102423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // the @interface. 102523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl()) 1026a054fb46b1fb596d1719b89d2d9a5be3c32a4b0dTed Kremenek if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl) 102723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (Visit(MakeCXCursor(MD, TU))) 102823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return true; 102923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 103023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl()) 1031a054fb46b1fb596d1719b89d2d9a5be3c32a4b0dTed Kremenek if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl) 103223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (Visit(MakeCXCursor(MD, TU))) 103323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return true; 103423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 103523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 103623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek} 103723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 1038b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { 1039dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek // Issue callbacks for super class. 1040b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (D->getSuperClass() && 1041b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), 1042f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek D->getSuperClassLoc(), 1043b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor TU))) 1044b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 1045f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 104678db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); 104778db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), 104878db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor E = D->protocol_end(); I != E; ++I, ++PL) 1049b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 1050b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 1051f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1052a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return VisitObjCContainerDecl(D); 1053dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 1054dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 10551ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) { 10561ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCContainerDecl(D); 10571ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 10581ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 10591ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { 1060ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek // 'ID' could be null when dealing with invalid code. 1061ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek if (ObjCInterfaceDecl *ID = D->getClassInterface()) 1062ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU))) 1063ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek return true; 1064f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 10651ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCImplDecl(D); 10661ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 10671ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 10681ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { 10691ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor#if 0 10701ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor // Issue callbacks for super class. 10711ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor // FIXME: No source location information! 10721ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (D->getSuperClass() && 10731ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), 1074f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek D->getSuperClassLoc(), 10751ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor TU))) 1076a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return true; 10771ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor#endif 1078f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 10791ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCImplDecl(D); 1080dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 1081dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 10821ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { 10831ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); 10841ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(), 10851ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor E = D->protocol_end(); 10861ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor I != E; ++I, ++PL) 1087b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 1088b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 1089f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1090f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return false; 1091dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 1092dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 10931ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) { 109495ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian if (Visit(MakeCursorObjCClassRef(D->getForwardInterfaceDecl(), 109595ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian D->getForwardDecl()->getLocation(), TU))) 10961ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 10971ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 1098dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 10995e4bc590b0ea010e38372d0b4a0aab578a746fe6Benjamin Kramer 1100a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregorbool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) { 1101a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl()) 1102a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU)); 1103a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor 1104a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor return false; 1105a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor} 1106a4ffd85a6684e42f900aad5459e58ad91bb88755Douglas Gregor 11078f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenekbool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) { 11088f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek return VisitDeclContext(D); 11098f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek} 11108f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek 11116931900f43cea558c6974075256c07728dbfecc6Douglas Gregorbool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { 1112c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 11130cfaf6a270ecd0f5c7e541a8047c87948317548bDouglas Gregor if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) 11140cfaf6a270ecd0f5c7e541a8047c87948317548bDouglas Gregor if (VisitNestedNameSpecifierLoc(QualifierLoc)) 1115c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 11166931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 11176931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(), 11186931900f43cea558c6974075256c07728dbfecc6Douglas Gregor D->getTargetNameLoc(), TU)); 11196931900f43cea558c6974075256c07728dbfecc6Douglas Gregor} 11206931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 11217e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUsingDecl(UsingDecl *D) { 1122c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1123dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) { 1124dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor if (VisitNestedNameSpecifierLoc(QualifierLoc)) 1125c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 1126dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor } 11277e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 11281f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU))) 11291f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return true; 11301f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 11317e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return VisitDeclarationNameInfo(D->getNameInfo()); 11327e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor} 11337e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 11340a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregorbool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { 1135c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1136db9924191092b4d426cc066637d81698211846aaDouglas Gregor if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) 1137db9924191092b4d426cc066637d81698211846aaDouglas Gregor if (VisitNestedNameSpecifierLoc(QualifierLoc)) 1138c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 11390a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 11400a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(), 11410a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor D->getIdentLocation(), TU)); 11420a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor} 11430a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 11447e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { 1145c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1146dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) { 1147dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor if (VisitNestedNameSpecifierLoc(QualifierLoc)) 1148c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 1149dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor } 1150c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 11517e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return VisitDeclarationNameInfo(D->getNameInfo()); 11527e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor} 11537e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 11547e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUnresolvedUsingTypenameDecl( 11557e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor UnresolvedUsingTypenameDecl *D) { 1156c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1157dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) 1158dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor if (VisitNestedNameSpecifierLoc(QualifierLoc)) 1159c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 1160c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 11617e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return false; 11627e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor} 11637e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 116401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) { 116501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor switch (Name.getName().getNameKind()) { 116601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::Identifier: 116701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXLiteralOperatorName: 116801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXOperatorName: 116901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXUsingDirective: 117001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 117101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 117201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXConstructorName: 117301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXDestructorName: 117401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXConversionFunctionName: 117501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo()) 117601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return Visit(TSInfo->getTypeLoc()); 117701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 117801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 117901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::ObjCZeroArgSelector: 118001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::ObjCOneArgSelector: 118101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::ObjCMultiArgSelector: 118201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // FIXME: Per-identifier location info? 118301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 118401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor } 118501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 118601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 118701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor} 118801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 1189c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregorbool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS, 1190c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor SourceRange Range) { 1191c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // FIXME: This whole routine is a hack to work around the lack of proper 1192c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // source information in nested-name-specifiers (PR5791). Since we do have 1193c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // a beginning source location, we can visit the first component of the 1194c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // nested-name-specifier, if it's a single-token component. 1195c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (!NNS) 1196c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return false; 1197c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1198c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Get the first component in the nested-name-specifier. 1199c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor while (NestedNameSpecifier *Prefix = NNS->getPrefix()) 1200c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor NNS = Prefix; 1201c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1202c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor switch (NNS->getKind()) { 1203c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::Namespace: 1204c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), 1205c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor TU)); 1206c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 120714aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor case NestedNameSpecifier::NamespaceAlias: 120814aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(), 120914aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor Range.getBegin(), TU)); 121014aba76042e041b2c5e439bf4ae353a0a3c7fd73Douglas Gregor 1211c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::TypeSpec: { 1212c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // If the type has a form where we know that the beginning of the source 1213c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // range matches up with a reference cursor. Visit the appropriate reference 1214c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // cursor. 1215f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall const Type *T = NNS->getAsType(); 1216c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (const TypedefType *Typedef = dyn_cast<TypedefType>(T)) 1217c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU)); 1218c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (const TagType *Tag = dyn_cast<TagType>(T)) 1219c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU)); 1220c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (const TemplateSpecializationType *TST 1221c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor = dyn_cast<TemplateSpecializationType>(T)) 1222c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return VisitTemplateName(TST->getTemplateName(), Range.getBegin()); 1223c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor break; 1224c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor } 1225c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1226c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::TypeSpecWithTemplate: 1227c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::Global: 1228c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::Identifier: 1229c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor break; 1230c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor } 1231c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1232c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return false; 1233c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor} 1234c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1235dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregorbool 1236dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas GregorCursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) { 12375f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<NestedNameSpecifierLoc, 4> Qualifiers; 1238dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor for (; Qualifier; Qualifier = Qualifier.getPrefix()) 1239dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor Qualifiers.push_back(Qualifier); 1240dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor 1241dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor while (!Qualifiers.empty()) { 1242dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor NestedNameSpecifierLoc Q = Qualifiers.pop_back_val(); 1243dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor NestedNameSpecifier *NNS = Q.getNestedNameSpecifier(); 1244dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor switch (NNS->getKind()) { 1245dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor case NestedNameSpecifier::Namespace: 1246dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), 1247c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor Q.getLocalBeginLoc(), 1248dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor TU))) 1249dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor return true; 1250dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor 1251dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor break; 1252dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor 1253dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor case NestedNameSpecifier::NamespaceAlias: 1254dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(), 1255c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor Q.getLocalBeginLoc(), 1256dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor TU))) 1257dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor return true; 1258dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor 1259dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor break; 1260dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor 1261dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor case NestedNameSpecifier::TypeSpec: 1262dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor case NestedNameSpecifier::TypeSpecWithTemplate: 1263dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor if (Visit(Q.getTypeLoc())) 1264dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor return true; 1265dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor 1266dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor break; 1267dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor 1268dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor case NestedNameSpecifier::Global: 1269dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor case NestedNameSpecifier::Identifier: 1270dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor break; 1271dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor } 1272dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor } 1273dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor 1274dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor return false; 1275dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor} 1276dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor 1277fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateParameters( 1278fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor const TemplateParameterList *Params) { 1279fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (!Params) 1280fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1281fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1282fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor for (TemplateParameterList::const_iterator P = Params->begin(), 1283fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor PEnd = Params->end(); 1284fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor P != PEnd; ++P) { 1285fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (Visit(MakeCXCursor(*P, TU))) 1286fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return true; 1287fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor } 1288fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1289fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1290fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1291fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 12920b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregorbool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) { 12930b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor switch (Name.getKind()) { 12940b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::Template: 12950b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU)); 12960b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 12970b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::OverloadedTemplate: 12981f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor // Visit the overloaded template set. 12991f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU))) 13001f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return true; 13011f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 13020b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return false; 13030b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 13040b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::DependentTemplate: 13050b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // FIXME: Visit nested-name-specifier. 13060b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return false; 13070b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 13080b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::QualifiedTemplate: 13090b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // FIXME: Visit nested-name-specifier. 13100b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return Visit(MakeCursorTemplateRef( 13110b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor Name.getAsQualifiedTemplateName()->getDecl(), 13120b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor Loc, TU)); 1313146060435c3efce95c95a092c7a1eb651cfb9ae0John McCall 1314146060435c3efce95c95a092c7a1eb651cfb9ae0John McCall case TemplateName::SubstTemplateTemplateParm: 1315146060435c3efce95c95a092c7a1eb651cfb9ae0John McCall return Visit(MakeCursorTemplateRef( 1316146060435c3efce95c95a092c7a1eb651cfb9ae0John McCall Name.getAsSubstTemplateTemplateParm()->getParameter(), 1317146060435c3efce95c95a092c7a1eb651cfb9ae0John McCall Loc, TU)); 13181aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor 13191aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor case TemplateName::SubstTemplateTemplateParmPack: 13201aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor return Visit(MakeCursorTemplateRef( 13211aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), 13221aee05d08b2184acadeb36de300e216390780d6cDouglas Gregor Loc, TU)); 13230b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor } 13240b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 13250b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return false; 13260b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor} 13270b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 1328fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) { 1329fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor switch (TAL.getArgument().getKind()) { 1330fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Null: 1331fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Integral: 1332fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Pack: 1333fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 133487dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor 1335fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Type: 1336fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo()) 1337fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return Visit(TSInfo->getTypeLoc()); 1338fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1339fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1340fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Declaration: 1341fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (Expr *E = TAL.getSourceDeclExpression()) 1342fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return Visit(MakeCXCursor(E, StmtParent, TU)); 1343fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1344fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1345fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Expression: 1346fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (Expr *E = TAL.getSourceExpression()) 1347fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return Visit(MakeCXCursor(E, StmtParent, TU)); 1348fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1349fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1350fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Template: 1351a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor case TemplateArgument::TemplateExpansion: 1352b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc())) 1353b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor return true; 1354b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor 1355a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(), 13560b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor TAL.getTemplateNameLoc()); 1357fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor } 1358fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1359fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1360fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1361fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1362a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenekbool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) { 1363a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek return VisitDeclContext(D); 1364a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek} 1365a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek 136601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { 136701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return Visit(TL.getUnqualifiedLoc()); 136801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor} 136901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 1370f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { 1371a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTContext &Context = AU->getASTContext(); 1372f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1373f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor // Some builtin types (such as Objective-C's "id", "sel", and 1374f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor // "Class") have associated declarations. Create cursors for those. 1375f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor QualType VisitType; 1376f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor switch (TL.getType()->getAs<BuiltinType>()->getKind()) { 13776b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Void: 1378f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Bool: 13796b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Char_U: 13806b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UChar: 1381f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Char16: 1382f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Char32: 13836b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UShort: 13846b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UInt: 13856b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::ULong: 13866b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::ULongLong: 13876b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UInt128: 1388f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Char_S: 13896b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::SChar: 13903f59c975aa5d047f7edd1b900b5e885c38af0ef7Chris Lattner case BuiltinType::WChar_U: 13913f59c975aa5d047f7edd1b900b5e885c38af0ef7Chris Lattner case BuiltinType::WChar_S: 13926b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Short: 1393f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Int: 1394f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Long: 1395c4174cc4b9b657abb77d0825de473ea29cf48297Ted Kremenek case BuiltinType::LongLong: 13966b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Int128: 13976b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Float: 13986b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Double: 13996b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::LongDouble: 1400f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::NullPtr: 1401f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Overload: 1402864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall case BuiltinType::BoundMember: 14036b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Dependent: 14041de4d4e8cb2e9c88809fea8092bc6e835a5473d2John McCall case BuiltinType::UnknownAny: 1405f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor break; 14066b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek 1407f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::ObjCId: 1408f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor VisitType = Context.getObjCIdType(); 1409f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor break; 14106b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek 14116b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::ObjCClass: 14126b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek VisitType = Context.getObjCClassType(); 14136b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek break; 14146b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek 1415f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::ObjCSel: 1416f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor VisitType = Context.getObjCSelType(); 1417f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor break; 1418f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor } 1419f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1420f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (!VisitType.isNull()) { 1421f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (const TypedefType *Typedef = VisitType->getAs<TypedefType>()) 1422f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), 1423f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor TU)); 1424f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor } 1425f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1426f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1427f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1428f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 14297d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorbool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) { 1430162e1c1b487352434552147967c3dd296ebee2f7Richard Smith return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU)); 14317d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor} 14327d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 1433f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { 1434f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 1435f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1436f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1437f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) { 14386f155de99c59af890817146ec8526bafb6560f1fArgyrios Kyrtzidis if (TL.isDefinition()) 14396f155de99c59af890817146ec8526bafb6560f1fArgyrios Kyrtzidis return Visit(MakeCXCursor(TL.getDecl(), TU)); 14406f155de99c59af890817146ec8526bafb6560f1fArgyrios Kyrtzidis 1441f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 1442f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1443f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1444fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { 1445960d13dde337a59dacc9dc3936c26d4aa8478986Chandler Carruth return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 1446fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1447fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1448f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { 1449f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU))) 1450f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1451f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1452c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall return false; 1453c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall} 1454c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall 1455c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCallbool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { 1456c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc())) 1457c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall return true; 1458c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall 1459f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { 1460f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I), 1461f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor TU))) 1462f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1463f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor } 1464f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1465f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1466f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1467f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1468f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { 1469c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall return Visit(TL.getPointeeLoc()); 1470f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1471f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1472075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnarabool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) { 1473075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara return Visit(TL.getInnerLoc()); 1474075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara} 1475075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara 1476f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) { 1477f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(TL.getPointeeLoc()); 1478f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1479f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1480f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { 1481f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(TL.getPointeeLoc()); 1482f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1483f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1484f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { 1485f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(TL.getPointeeLoc()); 1486f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1487f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1488f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { 1489f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return Visit(TL.getPointeeLoc()); 1490f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1491f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1492f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { 1493f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return Visit(TL.getPointeeLoc()); 1494f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1495f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 14963422fbc38f35d9e486879850c5bf0175bd2eee16Argyrios Kyrtzidisbool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) { 14973422fbc38f35d9e486879850c5bf0175bd2eee16Argyrios Kyrtzidis return Visit(TL.getModifiedLoc()); 14983422fbc38f35d9e486879850c5bf0175bd2eee16Argyrios Kyrtzidis} 14993422fbc38f35d9e486879850c5bf0175bd2eee16Argyrios Kyrtzidis 150001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL, 150101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor bool SkipResultType) { 150201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (!SkipResultType && Visit(TL.getResultLoc())) 1503f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1504f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1505f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 15065dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek if (Decl *D = TL.getArg(I)) 15075dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek if (Visit(MakeCXCursor(D, TU))) 15085dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek return true; 1509f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1510f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1511f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1512f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1513f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) { 1514f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Visit(TL.getElementLoc())) 1515f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1516f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1517f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Expr *Size = TL.getSizeExpr()) 1518f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(MakeCXCursor(Size, StmtParent, TU)); 1519f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1520f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1521f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1522f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1523fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateSpecializationTypeLoc( 1524fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor TemplateSpecializationTypeLoc TL) { 15250b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // Visit the template name. 15260b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor if (VisitTemplateName(TL.getTypePtr()->getTemplateName(), 15270b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor TL.getTemplateNameLoc())) 15280b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return true; 1529fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1530fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // Visit the template arguments. 1531fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 1532fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (VisitTemplateArgumentLoc(TL.getArgLoc(I))) 1533fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return true; 1534fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1535fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1536fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1537fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 15382332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregorbool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { 15392332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU)); 15402332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor} 15412332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor 15422332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregorbool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { 15432332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo()) 1544ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt return Visit(TSInfo->getTypeLoc()); 1545ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt 1546ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt return false; 1547ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt} 1548ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt 1549ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Huntbool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { 1550ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo()) 15512332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor return Visit(TSInfo->getTypeLoc()); 15522332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor 15532332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor return false; 15542332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor} 15552332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor 15562494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregorbool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { 15572494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc())) 15582494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor return true; 15592494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor 15602494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor return false; 15612494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor} 15622494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor 156394fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregorbool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc( 156494fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor DependentTemplateSpecializationTypeLoc TL) { 156594fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor // Visit the nested-name-specifier, if there is one. 156694fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor if (TL.getQualifierLoc() && 156794fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor VisitNestedNameSpecifierLoc(TL.getQualifierLoc())) 156894fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor return true; 156994fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor 157094fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor // Visit the template arguments. 157194fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 157294fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor if (VisitTemplateArgumentLoc(TL.getArgLoc(I))) 157394fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor return true; 157494fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor 157594fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor return false; 157694fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor} 157794fdffa4a572fc14ac296f5f1aae9db3734c72f1Douglas Gregor 15789e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregorbool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { 15799e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc())) 15809e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor return true; 15819e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor 15829e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor return Visit(TL.getNamedTypeLoc()); 15839e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor} 15849e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor 15857536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregorbool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) { 15867536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor return Visit(TL.getPatternLoc()); 15877536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor} 15887536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor 1589427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidisbool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { 1590427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis if (Expr *E = TL.getUnderlyingExpr()) 1591427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis return Visit(MakeCXCursor(E, StmtParent, TU)); 1592427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis 1593427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis return false; 1594427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis} 1595427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis 1596427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidisbool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { 1597427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 1598427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis} 1599427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis 1600427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \ 1601427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidisbool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \ 1602427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis return Visit##PARENT##Loc(TL); \ 1603427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis} 1604427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis 1605427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(Complex, Type) 1606427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType) 1607427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType) 1608427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(VariableArray, ArrayType) 1609427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType) 1610427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type) 1611427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(Vector, Type) 1612427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(ExtVector, VectorType) 1613427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType) 1614427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType) 1615427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(Record, TagType) 1616427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(Enum, TagType) 1617427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type) 1618427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type) 1619427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios KyrtzidisDEFAULT_TYPELOC_IMPL(Auto, Type) 1620427964e15f1b9595659cea3fcb4dd808a00f37b5Argyrios Kyrtzidis 16213064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenekbool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) { 1622c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor // Visit the nested-name-specifier, if present. 1623c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) 1624c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor if (VisitNestedNameSpecifierLoc(QualifierLoc)) 1625c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor return true; 1626c22b5fff39a7520207f165fb16a27a34b944bd9cDouglas Gregor 16273064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek if (D->isDefinition()) { 16283064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), 16293064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek E = D->bases_end(); I != E; ++I) { 16303064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU))) 16313064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return true; 16323064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 16333064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 16343064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek 16353064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return VisitTagDecl(D); 16363064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek} 16373064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek 163809dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenekbool CursorVisitor::VisitAttributes(Decl *D) { 1639cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end(); 1640cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) 1641cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (Visit(MakeCXCursor(*i, D, TU))) 164209dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek return true; 164309dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek 164409dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek return false; 164509dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek} 164609dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek 1647c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===// 1648c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek// Data-recursive visitor methods. 1649c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===// 1650c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 165128a719433411ef782b582946823bc648ddcc4533Ted Kremeneknamespace { 1652035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek#define DEF_JOB(NAME, DATA, KIND)\ 1653035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekclass NAME : public VisitorJob {\ 1654035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekpublic:\ 1655035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \ 1656035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\ 1657f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek DATA *get() const { return static_cast<DATA*>(data[0]); }\ 1658035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek}; 1659035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek 1660035dc41b509fcc470ceb6764aa64837505a2ece3Ted KremenekDEF_JOB(StmtVisit, Stmt, StmtVisitKind) 1661035dc41b509fcc470ceb6764aa64837505a2ece3Ted KremenekDEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind) 1662e4979ccb5960608edce73f3b274eb7c2de15dac5Ted KremenekDEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind) 1663035dc41b509fcc470ceb6764aa64837505a2ece3Ted KremenekDEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind) 166460608ec12d17168a3d1f415409a6a6eaf6d94508Ted KremenekDEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList, 166560608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek ExplicitTemplateArgsVisitKind) 166694d96291cd041adc5731a2294828a9c20e450b74Douglas GregorDEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind) 1667035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek#undef DEF_JOB 1668035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek 1669035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekclass DeclVisit : public VisitorJob { 1670035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekpublic: 1671035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek DeclVisit(Decl *d, CXCursor parent, bool isFirst) : 1672035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek VisitorJob(parent, VisitorJob::DeclVisitKind, 1673035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek d, isFirst ? (void*) 1 : (void*) 0) {} 1674035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek static bool classof(const VisitorJob *VJ) { 167582f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek return VJ->getKind() == DeclVisitKind; 1676035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek } 1677f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek Decl *get() const { return static_cast<Decl*>(data[0]); } 1678f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek bool isFirst() const { return data[1] ? true : false; } 1679035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek}; 1680035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekclass TypeLocVisit : public VisitorJob { 1681035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekpublic: 1682035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek TypeLocVisit(TypeLoc tl, CXCursor parent) : 1683035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek VisitorJob(parent, VisitorJob::TypeLocVisitKind, 1684035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {} 1685035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek 1686035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek static bool classof(const VisitorJob *VJ) { 1687035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek return VJ->getKind() == TypeLocVisitKind; 1688035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek } 1689035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek 169082f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek TypeLoc get() const { 1691f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek QualType T = QualType::getFromOpaquePtr(data[0]); 1692f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek return TypeLoc(T, data[1]); 1693035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek } 1694035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek}; 1695035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek 1696ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenekclass LabelRefVisit : public VisitorJob { 1697ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenekpublic: 1698ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent) 1699ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD, 1700dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin labelLoc.getPtrEncoding()) {} 1701ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek 1702ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek static bool classof(const VisitorJob *VJ) { 1703ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek return VJ->getKind() == VisitorJob::LabelRefVisitKind; 1704ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek } 1705ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); } 1706ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek SourceLocation getLoc() const { 1707dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin return SourceLocation::getFromPtrEncoding(data[1]); } 1708f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek}; 1709f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor 1710f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregorclass NestedNameSpecifierLocVisit : public VisitorJob { 1711f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregorpublic: 1712f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent) 1713f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind, 1714f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor Qualifier.getNestedNameSpecifier(), 1715f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor Qualifier.getOpaqueData()) { } 1716f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor 1717f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor static bool classof(const VisitorJob *VJ) { 1718f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind; 1719f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor } 1720f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor 1721f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor NestedNameSpecifierLoc get() const { 1722f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]), 1723f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor data[1]); 1724f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor } 1725f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor}; 1726f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor 1727f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenekclass DeclarationNameInfoVisit : public VisitorJob { 1728f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenekpublic: 1729f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek DeclarationNameInfoVisit(Stmt *S, CXCursor parent) 1730f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {} 1731f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek static bool classof(const VisitorJob *VJ) { 1732f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind; 1733f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek } 1734f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek DeclarationNameInfo get() const { 1735f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek Stmt *S = static_cast<Stmt*>(data[0]); 1736f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek switch (S->getStmtClass()) { 1737f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek default: 1738f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek llvm_unreachable("Unhandled Stmt"); 1739f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek case Stmt::CXXDependentScopeMemberExprClass: 1740f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo(); 1741f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek case Stmt::DependentScopeDeclRefExprClass: 1742f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek return cast<DependentScopeDeclRefExpr>(S)->getNameInfo(); 1743f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek } 1744f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek } 1745ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek}; 1746cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekclass MemberRefVisit : public VisitorJob { 1747cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekpublic: 1748cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent) 1749cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D, 1750dec0984fce504a39a7f085774fb67cfd9957be58Jeffrey Yasskin L.getPtrEncoding()) {} 1751cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek static bool classof(const VisitorJob *VJ) { 1752cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek return VJ->getKind() == VisitorJob::MemberRefVisitKind; 1753cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek } 1754cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek FieldDecl *get() const { 1755cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek return static_cast<FieldDecl*>(data[0]); 1756cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek } 1757cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek SourceLocation getLoc() const { 1758cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]); 1759cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek } 1760cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek}; 176128a719433411ef782b582946823bc648ddcc4533Ted Kremenekclass EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> { 176228a719433411ef782b582946823bc648ddcc4533Ted Kremenek VisitorWorkList &WL; 176328a719433411ef782b582946823bc648ddcc4533Ted Kremenek CXCursor Parent; 176428a719433411ef782b582946823bc648ddcc4533Ted Kremenekpublic: 176528a719433411ef782b582946823bc648ddcc4533Ted Kremenek EnqueueVisitor(VisitorWorkList &wl, CXCursor parent) 176628a719433411ef782b582946823bc648ddcc4533Ted Kremenek : WL(wl), Parent(parent) {} 176728a719433411ef782b582946823bc648ddcc4533Ted Kremenek 1768ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek void VisitAddrLabelExpr(AddrLabelExpr *E); 176973d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek void VisitBlockExpr(BlockExpr *B); 177028a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitCompoundLiteralExpr(CompoundLiteralExpr *E); 1771083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenek void VisitCompoundStmt(CompoundStmt *S); 177211b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ } 1773f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); 177411b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek void VisitCXXNewExpr(CXXNewExpr *E); 17756d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); 177628a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E); 1777cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); 177873d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E); 1779b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenek void VisitCXXTypeidExpr(CXXTypeidExpr *E); 178055b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E); 17811e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenek void VisitCXXUuidofExpr(CXXUuidofExpr *E); 1782e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek void VisitDeclRefExpr(DeclRefExpr *D); 1783035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek void VisitDeclStmt(DeclStmt *S); 1784f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); 1785cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek void VisitDesignatedInitExpr(DesignatedInitExpr *E); 178628a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitExplicitCastExpr(ExplicitCastExpr *E); 178728a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitForStmt(ForStmt *FS); 1788ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek void VisitGotoStmt(GotoStmt *GS); 178928a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitIfStmt(IfStmt *If); 179028a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitInitListExpr(InitListExpr *IE); 179128a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitMemberExpr(MemberExpr *M); 1792cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek void VisitOffsetOfExpr(OffsetOfExpr *E); 179373d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek void VisitObjCEncodeExpr(ObjCEncodeExpr *E); 179428a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitObjCMessageExpr(ObjCMessageExpr *M); 179528a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitOverloadExpr(OverloadExpr *E); 1796f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E); 179728a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitStmt(Stmt *S); 179828a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitSwitchStmt(SwitchStmt *S); 179928a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitWhileStmt(WhileStmt *W); 18002939b6f356161f572712d4d6310b65f9599e3675Ted Kremenek void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E); 18016ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E); 180221ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E); 1803552622067dc45013d240f73952fece703f5e63bdJohn Wiegley void VisitExpressionTraitExpr(ExpressionTraitExpr *E); 180428a719433411ef782b582946823bc648ddcc4533Ted Kremenek void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U); 18059d3bf79d94c961af95144ef63bbd6f9f3f32c59aTed Kremenek void VisitVAArgExpr(VAArgExpr *E); 180694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor void VisitSizeOfPackExpr(SizeOfPackExpr *E); 1807ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor 180828a719433411ef782b582946823bc648ddcc4533Ted Kremenekprivate: 1809f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek void AddDeclarationNameInfo(Stmt *S); 1810f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier); 181160608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A); 1812cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek void AddMemberRef(FieldDecl *D, SourceLocation L); 181328a719433411ef782b582946823bc648ddcc4533Ted Kremenek void AddStmt(Stmt *S); 1814035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek void AddDecl(Decl *D, bool isFirst = true); 181528a719433411ef782b582946823bc648ddcc4533Ted Kremenek void AddTypeLoc(TypeSourceInfo *TI); 181628a719433411ef782b582946823bc648ddcc4533Ted Kremenek void EnqueueChildren(Stmt *S); 181728a719433411ef782b582946823bc648ddcc4533Ted Kremenek}; 181828a719433411ef782b582946823bc648ddcc4533Ted Kremenek} // end anonyous namespace 181928a719433411ef782b582946823bc648ddcc4533Ted Kremenek 1820f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenekvoid EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) { 1821f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek // 'S' should always be non-null, since it comes from the 1822f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek // statement we are visiting. 1823f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek WL.push_back(DeclarationNameInfoVisit(S, Parent)); 1824f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek} 1825f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor 1826f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregorvoid 1827f3db29fff6a583ecda823cf909ab7737d8d30129Douglas GregorEnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) { 1828f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor if (Qualifier) 1829f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent)); 1830f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor} 1831f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor 183228a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::AddStmt(Stmt *S) { 183328a719433411ef782b582946823bc648ddcc4533Ted Kremenek if (S) 183428a719433411ef782b582946823bc648ddcc4533Ted Kremenek WL.push_back(StmtVisit(S, Parent)); 183528a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 1836035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekvoid EnqueueVisitor::AddDecl(Decl *D, bool isFirst) { 183728a719433411ef782b582946823bc648ddcc4533Ted Kremenek if (D) 1838035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek WL.push_back(DeclVisit(D, Parent, isFirst)); 183928a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 184060608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenekvoid EnqueueVisitor:: 184160608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) { 184260608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek if (A) 184360608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek WL.push_back(ExplicitTemplateArgsVisit( 184460608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek const_cast<ExplicitTemplateArgumentList*>(A), Parent)); 184560608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek} 1846cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekvoid EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) { 1847cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek if (D) 1848cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek WL.push_back(MemberRefVisit(D, L, Parent)); 1849cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek} 185028a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) { 185128a719433411ef782b582946823bc648ddcc4533Ted Kremenek if (TI) 185228a719433411ef782b582946823bc648ddcc4533Ted Kremenek WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent)); 185328a719433411ef782b582946823bc648ddcc4533Ted Kremenek } 185428a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::EnqueueChildren(Stmt *S) { 1855a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek unsigned size = WL.size(); 18567502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall for (Stmt::child_range Child = S->children(); Child; ++Child) { 185728a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(*Child); 1858a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek } 1859a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek if (size == WL.size()) 1860a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek return; 1861a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek // Now reverse the entries we just added. This will match the DFS 1862a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek // ordering performed by the worklist. 1863a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek VisitorWorkList::iterator I = WL.begin() + size, E = WL.end(); 1864a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek std::reverse(I, E); 1865a6b70435ae49f2c7da1ad2b200c1aeb9f8761fddTed Kremenek} 1866ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenekvoid EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) { 1867ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent)); 1868ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek} 186973d15c452e675b684b7eee4f2096e386e59397aaTed Kremenekvoid EnqueueVisitor::VisitBlockExpr(BlockExpr *B) { 187073d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek AddDecl(B->getBlockDecl()); 187173d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek} 187228a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 187328a719433411ef782b582946823bc648ddcc4533Ted Kremenek EnqueueChildren(E); 187428a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddTypeLoc(E->getTypeSourceInfo()); 187528a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 1876083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenekvoid EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) { 1877083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenek for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(), 1878083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenek E = S->body_rend(); I != E; ++I) { 1879083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenek AddStmt(*I); 1880083c7e2d564033af87e507fbbd02f1c77ff462b1Ted Kremenek } 188111b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek} 1882f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenekvoid EnqueueVisitor:: 1883f64d80306144f978148ba92f36f7cea7b671dd34Ted KremenekVisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) { 1884f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs()); 1885f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek AddDeclarationNameInfo(E); 18867c3179cf463c3b3b8c21dbb955f933ba50b74f28Douglas Gregor if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc()) 18877c3179cf463c3b3b8c21dbb955f933ba50b74f28Douglas Gregor AddNestedNameSpecifierLoc(QualifierLoc); 1888f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek if (!E->isImplicitAccess()) 1889f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek AddStmt(E->getBase()); 1890f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek} 189111b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenekvoid EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) { 189211b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek // Enqueue the initializer or constructor arguments. 189311b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek for (unsigned I = E->getNumConstructorArgs(); I > 0; --I) 189411b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek AddStmt(E->getConstructorArg(I-1)); 189511b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek // Enqueue the array size, if any. 189611b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek AddStmt(E->getArraySize()); 189711b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek // Enqueue the allocated type. 189811b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek AddTypeLoc(E->getAllocatedTypeSourceInfo()); 189911b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek // Enqueue the placement arguments. 190011b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek for (unsigned I = E->getNumPlacementArgs(); I > 0; --I) 190111b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek AddStmt(E->getPlacementArg(I-1)); 190211b8e3e7fa67795acc968a9d5ebfd687feaf2b2cTed Kremenek} 190328a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) { 19048b8d8c90f2d8ac651d14b57f116d20b3c911ac7fTed Kremenek for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I) 19058b8d8c90f2d8ac651d14b57f116d20b3c911ac7fTed Kremenek AddStmt(CE->getArg(I-1)); 190628a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(CE->getCallee()); 190728a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(CE->getArg(0)); 190828a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 1909cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekvoid EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 1910cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek // Visit the name of the type being destroyed. 1911cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek AddTypeLoc(E->getDestroyedTypeInfo()); 1912cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek // Visit the scope type that looks disturbingly like the nested-name-specifier 1913cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek // but isn't. 1914cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek AddTypeLoc(E->getScopeTypeInfo()); 1915cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek // Visit the nested-name-specifier. 1916f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc()) 1917f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor AddNestedNameSpecifierLoc(QualifierLoc); 1918cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek // Visit base expression. 1919cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek AddStmt(E->getBase()); 1920cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek} 19216d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenekvoid EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { 19226d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek AddTypeLoc(E->getTypeSourceInfo()); 19236d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek} 192473d15c452e675b684b7eee4f2096e386e59397aaTed Kremenekvoid EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { 192573d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek EnqueueChildren(E); 192673d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek AddTypeLoc(E->getTypeSourceInfo()); 192773d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek} 1928b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenekvoid EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) { 1929b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenek EnqueueChildren(E); 1930b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenek if (E->isTypeOperand()) 1931b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenek AddTypeLoc(E->getTypeOperandSourceInfo()); 1932b8dd1cad52be63b18092bd9d9335cbeee3f5de9fTed Kremenek} 193355b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek 193455b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenekvoid EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr 193555b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek *E) { 193655b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek EnqueueChildren(E); 193755b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek AddTypeLoc(E->getTypeSourceInfo()); 193855b933ae3b3efc29987b8bd92714257f00c4b53aTed Kremenek} 19391e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenekvoid EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) { 19401e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenek EnqueueChildren(E); 19411e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenek if (E->isTypeOperand()) 19421e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenek AddTypeLoc(E->getTypeOperandSourceInfo()); 19431e7e877091187556bb6d644ab2b7c00a628121ebTed Kremenek} 1944e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenekvoid EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) { 194560608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek if (DR->hasExplicitTemplateArgs()) { 194660608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs()); 194760608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek } 1948e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek WL.push_back(DeclRefExprParts(DR, Parent)); 1949e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek} 1950f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenekvoid EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { 1951f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs()); 1952f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek AddDeclarationNameInfo(E); 195300cf3cc2718671aa48e8da264a523b0058a8591eDouglas Gregor AddNestedNameSpecifierLoc(E->getQualifierLoc()); 1954f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek} 1955035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenekvoid EnqueueVisitor::VisitDeclStmt(DeclStmt *S) { 1956035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek unsigned size = WL.size(); 1957035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek bool isFirst = true; 1958035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); 1959035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek D != DEnd; ++D) { 1960035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek AddDecl(*D, isFirst); 1961035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek isFirst = false; 1962035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek } 1963035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek if (size == WL.size()) 1964035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek return; 1965035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek // Now reverse the entries we just added. This will match the DFS 1966035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek // ordering performed by the worklist. 1967035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek VisitorWorkList::iterator I = WL.begin() + size, E = WL.end(); 1968035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek std::reverse(I, E); 1969035dc41b509fcc470ceb6764aa64837505a2ece3Ted Kremenek} 1970cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekvoid EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) { 1971cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek AddStmt(E->getInit()); 1972cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek typedef DesignatedInitExpr::Designator Designator; 1973cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek for (DesignatedInitExpr::reverse_designators_iterator 1974cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek D = E->designators_rbegin(), DEnd = E->designators_rend(); 1975cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek D != DEnd; ++D) { 1976cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek if (D->isFieldDesignator()) { 1977cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek if (FieldDecl *Field = D->getField()) 1978cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek AddMemberRef(Field, D->getFieldLoc()); 1979cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek continue; 1980cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek } 1981cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek if (D->isArrayDesignator()) { 1982cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek AddStmt(E->getArrayIndex(*D)); 1983cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek continue; 1984cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek } 1985cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek assert(D->isArrayRangeDesignator() && "Unknown designator kind"); 1986cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek AddStmt(E->getArrayRangeEnd(*D)); 1987cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek AddStmt(E->getArrayRangeStart(*D)); 1988cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek } 1989cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek} 199028a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) { 199128a719433411ef782b582946823bc648ddcc4533Ted Kremenek EnqueueChildren(E); 199228a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddTypeLoc(E->getTypeInfoAsWritten()); 199328a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 199428a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitForStmt(ForStmt *FS) { 199528a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(FS->getBody()); 199628a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(FS->getInc()); 199728a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(FS->getCond()); 199828a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddDecl(FS->getConditionVariable()); 199928a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(FS->getInit()); 200028a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 2001ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenekvoid EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) { 2002ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent)); 2003ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek} 200428a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitIfStmt(IfStmt *If) { 200528a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(If->getElse()); 200628a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(If->getThen()); 200728a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(If->getCond()); 200828a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddDecl(If->getConditionVariable()); 200928a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 201028a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) { 201128a719433411ef782b582946823bc648ddcc4533Ted Kremenek // We care about the syntactic form of the initializer list, only. 201228a719433411ef782b582946823bc648ddcc4533Ted Kremenek if (InitListExpr *Syntactic = IE->getSyntacticForm()) 201328a719433411ef782b582946823bc648ddcc4533Ted Kremenek IE = Syntactic; 201428a719433411ef782b582946823bc648ddcc4533Ted Kremenek EnqueueChildren(IE); 201528a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 201628a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitMemberExpr(MemberExpr *M) { 201789629a746019a42797495b091711a1d68467e88aDouglas Gregor WL.push_back(MemberExprParts(M, Parent)); 201889629a746019a42797495b091711a1d68467e88aDouglas Gregor 201989629a746019a42797495b091711a1d68467e88aDouglas Gregor // If the base of the member access expression is an implicit 'this', don't 202089629a746019a42797495b091711a1d68467e88aDouglas Gregor // visit it. 202189629a746019a42797495b091711a1d68467e88aDouglas Gregor // FIXME: If we ever want to show these implicit accesses, this will be 202289629a746019a42797495b091711a1d68467e88aDouglas Gregor // unfortunate. However, clang_getCursor() relies on this behavior. 202375e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor if (!M->isImplicitAccess()) 202475e85048e73fcde2ce9d8a48dfdb1220e132eb59Douglas Gregor AddStmt(M->getBase()); 202528a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 202673d15c452e675b684b7eee4f2096e386e59397aaTed Kremenekvoid EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { 202773d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek AddTypeLoc(E->getEncodedTypeSourceInfo()); 202873d15c452e675b684b7eee4f2096e386e59397aaTed Kremenek} 202928a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) { 203028a719433411ef782b582946823bc648ddcc4533Ted Kremenek EnqueueChildren(M); 203128a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddTypeLoc(M->getClassReceiverTypeInfo()); 203228a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 2033cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekvoid EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) { 2034cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek // Visit the components of the offsetof expression. 2035cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) { 2036cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek typedef OffsetOfExpr::OffsetOfNode OffsetOfNode; 2037cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek const OffsetOfNode &Node = E->getComponent(I-1); 2038cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek switch (Node.getKind()) { 2039cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek case OffsetOfNode::Array: 2040cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek AddStmt(E->getIndexExpr(Node.getArrayExprIndex())); 2041cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek break; 2042cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek case OffsetOfNode::Field: 204306dec892b5300b43263d25c5476b506c9d6cfbadAbramo Bagnara AddMemberRef(Node.getField(), Node.getSourceRange().getEnd()); 2044cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek break; 2045cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek case OffsetOfNode::Identifier: 2046cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek case OffsetOfNode::Base: 2047cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek continue; 2048cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek } 2049cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek } 2050cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek // Visit the type into which we're computing the offset. 2051cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek AddTypeLoc(E->getTypeSourceInfo()); 2052cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek} 205328a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) { 205460608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs()); 20556045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek WL.push_back(OverloadExprParts(E, Parent)); 20566045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek} 2057f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbournevoid EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr( 2058f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne UnaryExprOrTypeTraitExpr *E) { 20596d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek EnqueueChildren(E); 20606d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek if (E->isArgumentType()) 20616d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek AddTypeLoc(E->getArgumentTypeInfo()); 20626d0a00d9b02499d6c1253ea03d4dc7c32f8f289eTed Kremenek} 206328a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitStmt(Stmt *S) { 206428a719433411ef782b582946823bc648ddcc4533Ted Kremenek EnqueueChildren(S); 206528a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 206628a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) { 206728a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(S->getBody()); 206828a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(S->getCond()); 206928a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddDecl(S->getConditionVariable()); 207028a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 2071fafa75aebadef8d6b44a920e3f40529f150a5574Ted Kremenek 207228a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitWhileStmt(WhileStmt *W) { 207328a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(W->getBody()); 207428a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(W->getCond()); 207528a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddDecl(W->getConditionVariable()); 207628a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 207721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 20782939b6f356161f572712d4d6310b65f9599e3675Ted Kremenekvoid EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { 20792939b6f356161f572712d4d6310b65f9599e3675Ted Kremenek AddTypeLoc(E->getQueriedTypeSourceInfo()); 20802939b6f356161f572712d4d6310b65f9599e3675Ted Kremenek} 20816ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 20826ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichetvoid EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { 20836ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet AddTypeLoc(E->getRhsTypeSourceInfo()); 20840a03a3f98b14006a54bcac9e8908a7c9f50e519fFrancois Pichet AddTypeLoc(E->getLhsTypeSourceInfo()); 20856ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet} 20866ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 208721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegleyvoid EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { 208821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley AddTypeLoc(E->getQueriedTypeSourceInfo()); 208921ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley} 209021ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 2091552622067dc45013d240f73952fece703f5e63bdJohn Wiegleyvoid EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { 2092552622067dc45013d240f73952fece703f5e63bdJohn Wiegley EnqueueChildren(E); 2093552622067dc45013d240f73952fece703f5e63bdJohn Wiegley} 2094552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 209528a719433411ef782b582946823bc648ddcc4533Ted Kremenekvoid EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) { 209628a719433411ef782b582946823bc648ddcc4533Ted Kremenek VisitOverloadExpr(U); 209728a719433411ef782b582946823bc648ddcc4533Ted Kremenek if (!U->isImplicitAccess()) 209828a719433411ef782b582946823bc648ddcc4533Ted Kremenek AddStmt(U->getBase()); 209928a719433411ef782b582946823bc648ddcc4533Ted Kremenek} 21009d3bf79d94c961af95144ef63bbd6f9f3f32c59aTed Kremenekvoid EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) { 21019d3bf79d94c961af95144ef63bbd6f9f3f32c59aTed Kremenek AddStmt(E->getSubExpr()); 21029d3bf79d94c961af95144ef63bbd6f9f3f32c59aTed Kremenek AddTypeLoc(E->getWrittenTypeInfo()); 21039d3bf79d94c961af95144ef63bbd6f9f3f32c59aTed Kremenek} 210494d96291cd041adc5731a2294828a9c20e450b74Douglas Gregorvoid EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) { 210594d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor WL.push_back(SizeOfPackExprParts(E, Parent)); 210694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor} 21076045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek 2108c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekvoid CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) { 210928a719433411ef782b582946823bc648ddcc4533Ted Kremenek EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S); 2110c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek} 2111c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2112c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekbool CursorVisitor::IsInRegionOfInterest(CXCursor C) { 2113c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (RegionOfInterest.isValid()) { 2114c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek SourceRange Range = getRawCursorExtent(C); 2115c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (Range.isInvalid() || CompareRegionOfInterest(Range)) 2116c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return false; 2117c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2118c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return true; 2119c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek} 2120c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2121c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenekbool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { 2122c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek while (!WL.empty()) { 2123c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Dequeue the worklist item. 212482f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek VisitorJob LI = WL.back(); 212582f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek WL.pop_back(); 212682f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek 2127c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Set the Parent field, then back to its old value once we're done. 2128c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek SetParentRAII SetParent(Parent, StmtParent, LI.getParent()); 2129c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2130c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek switch (LI.getKind()) { 2131f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek case VisitorJob::DeclVisitKind: { 213282f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek Decl *D = cast<DeclVisit>(&LI)->get(); 2133f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek if (!D) 2134f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek continue; 2135f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek 2136f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek // For now, perform default visitation for Decls. 213782f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst()))) 2138f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek return true; 2139f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek 2140f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek continue; 2141f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek } 214260608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek case VisitorJob::ExplicitTemplateArgsVisitKind: { 214360608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek const ExplicitTemplateArgumentList *ArgList = 214460608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek cast<ExplicitTemplateArgsVisit>(&LI)->get(); 214560608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(), 214660608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek *ArgEnd = Arg + ArgList->NumTemplateArgs; 214760608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek Arg != ArgEnd; ++Arg) { 214860608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek if (VisitTemplateArgumentLoc(*Arg)) 214960608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek return true; 215060608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek } 215160608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek continue; 215260608ec12d17168a3d1f415409a6a6eaf6d94508Ted Kremenek } 2153cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek case VisitorJob::TypeLocVisitKind: { 2154cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek // Perform default visitation for TypeLocs. 215582f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek if (Visit(cast<TypeLocVisit>(&LI)->get())) 2156cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek return true; 2157cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek continue; 2158cdb4caf6bd8beb562e169b4d3f6c604c4e4528f8Ted Kremenek } 2159ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek case VisitorJob::LabelRefVisitKind: { 2160ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner LabelDecl *LS = cast<LabelRefVisit>(&LI)->get(); 2161e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek if (LabelStmt *stmt = LS->getStmt()) { 2162e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(), 2163e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek TU))) { 2164e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek return true; 2165e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek } 2166e7455016e5fae3db7e2d88a61633f76ab05fc9d3Ted Kremenek } 2167ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek continue; 2168ae1fd6fd47ce3fbb878155af6f517adaeae15a51Ted Kremenek } 216947695c8ad8424851f62e0d4a983b45b15daee1c5Ted Kremenek 2170f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor case VisitorJob::NestedNameSpecifierLocVisitKind: { 2171f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI); 2172f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor if (VisitNestedNameSpecifierLoc(V->get())) 2173f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor return true; 2174f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor continue; 2175f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor } 2176f3db29fff6a583ecda823cf909ab7737d8d30129Douglas Gregor 2177f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek case VisitorJob::DeclarationNameInfoVisitKind: { 2178f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI) 2179f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek ->get())) 2180f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek return true; 2181f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek continue; 2182f64d80306144f978148ba92f36f7cea7b671dd34Ted Kremenek } 2183cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek case VisitorJob::MemberRefVisitKind: { 2184cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek MemberRefVisit *V = cast<MemberRefVisit>(&LI); 2185cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU))) 2186cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek return true; 2187cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek continue; 2188cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek } 2189c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case VisitorJob::StmtVisitKind: { 219082f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek Stmt *S = cast<StmtVisit>(&LI)->get(); 21918c269ac75569454a049385b1246140db5f2b6faaTed Kremenek if (!S) 21928c269ac75569454a049385b1246140db5f2b6faaTed Kremenek continue; 21938c269ac75569454a049385b1246140db5f2b6faaTed Kremenek 2194f1107457c7d5cb57718725c51dfed4bf2ba6ee9eTed Kremenek // Update the current cursor. 2195c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek CXCursor Cursor = MakeCXCursor(S, StmtParent, TU); 2196cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek if (!IsInRegionOfInterest(Cursor)) 2197cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek continue; 2198cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek switch (Visitor(Cursor, Parent, ClientData)) { 2199cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek case CXChildVisit_Break: return true; 2200cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek case CXChildVisit_Continue: break; 2201cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek case CXChildVisit_Recurse: 2202cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenek EnqueueWorkList(WL, S); 220382f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek break; 2204c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 220582f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek continue; 2206c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2207c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek case VisitorJob::MemberExprPartsKind: { 2208c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Handle the other pieces in the MemberExpr besides the base. 220982f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek MemberExpr *M = cast<MemberExprParts>(&LI)->get(); 2210c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2211c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Visit the nested-name-specifier 221240d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc()) 221340d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor if (VisitNestedNameSpecifierLoc(QualifierLoc)) 2214c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return true; 2215c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2216c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Visit the declaration name. 2217c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (VisitDeclarationNameInfo(M->getMemberNameInfo())) 2218c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return true; 2219c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2220c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek // Visit the explicitly-specified template arguments, if any. 2221c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (M->hasExplicitTemplateArgs()) { 2222c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(), 2223c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek *ArgEnd = Arg + M->getNumTemplateArgs(); 2224c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek Arg != ArgEnd; ++Arg) { 2225c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek if (VisitTemplateArgumentLoc(*Arg)) 2226c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return true; 2227c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2228c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2229c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek continue; 2230c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2231e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek case VisitorJob::DeclRefExprPartsKind: { 223282f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get(); 2233e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek // Visit nested-name-specifier, if present. 223440d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc()) 223540d96a69c0e1e8c10f92d450c305a7aae696ca9cDouglas Gregor if (VisitNestedNameSpecifierLoc(QualifierLoc)) 2236e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek return true; 2237e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek // Visit declaration name. 2238e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek if (VisitDeclarationNameInfo(DR->getNameInfo())) 2239e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek return true; 2240e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek continue; 2241e4979ccb5960608edce73f3b274eb7c2de15dac5Ted Kremenek } 22426045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek case VisitorJob::OverloadExprPartsKind: { 224382f3c50fa163f99d1407849e556d3859a09afd78Ted Kremenek OverloadExpr *O = cast<OverloadExprParts>(&LI)->get(); 22446045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek // Visit the nested-name-specifier. 22454c9be89bb615ec07eb3ed507c8fa9d0baa8a5ad7Douglas Gregor if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc()) 22464c9be89bb615ec07eb3ed507c8fa9d0baa8a5ad7Douglas Gregor if (VisitNestedNameSpecifierLoc(QualifierLoc)) 22476045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek return true; 22486045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek // Visit the declaration name. 22496045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek if (VisitDeclarationNameInfo(O->getNameInfo())) 22506045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek return true; 22516045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek // Visit the overloaded declaration reference. 22526045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek if (Visit(MakeCursorOverloadedDeclRef(O, TU))) 22536045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek return true; 22546045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek continue; 22556045878f1fa7fad19d826634617991db99d3bd22Ted Kremenek } 225694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor case VisitorJob::SizeOfPackExprPartsKind: { 225794d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get(); 225894d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor NamedDecl *Pack = E->getPack(); 225994d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor if (isa<TemplateTypeParmDecl>(Pack)) { 226094d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack), 226194d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor E->getPackLoc(), TU))) 226294d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor return true; 226394d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor 226494d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor continue; 226594d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor } 226694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor 226794d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor if (isa<TemplateTemplateParmDecl>(Pack)) { 226894d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack), 226994d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor E->getPackLoc(), TU))) 227094d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor return true; 227194d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor 227294d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor continue; 227394d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor } 227494d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor 227594d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor // Non-type template parameter packs and function parameter packs are 227694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor // treated like DeclRefExpr cursors. 227794d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor continue; 227894d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor } 2279c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2280c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek } 2281c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek return false; 2282c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek} 2283c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 2284cdba6595a61a7bd31f504260abf63c900a759d0fTed Kremenekbool CursorVisitor::Visit(Stmt *S) { 2285d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek VisitorWorkList *WL = 0; 2286d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek if (!WorkListFreeList.empty()) { 2287d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek WL = WorkListFreeList.back(); 2288d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek WL->clear(); 2289d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek WorkListFreeList.pop_back(); 2290d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek } 2291d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek else { 2292d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek WL = new VisitorWorkList(); 2293d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek WorkListCache.push_back(WL); 2294d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek } 2295d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek EnqueueWorkList(*WL, S); 2296d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek bool result = RunVisitorWorkList(*WL); 2297d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek WorkListFreeList.push_back(WL); 2298d1ded66c4eda8d170222071dec7ebba78bd86ea4Ted Kremenek return result; 2299c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek} 2300c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 230148a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichetnamespace { 230248a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichettypedef llvm::SmallVector<SourceRange, 4> RefNamePieces; 230348a8d14fc6f064a5297024c2b34733a4080b2efeFrancois PichetRefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr, 230448a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet const DeclarationNameInfo &NI, 230548a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet const SourceRange &QLoc, 230648a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet const ExplicitTemplateArgumentList *TemplateArgs = 0){ 230748a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet const bool WantQualifier = NameFlags & CXNameRange_WantQualifier; 230848a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs; 230948a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece; 231048a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet 231148a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet const DeclarationName::NameKind Kind = NI.getName().getNameKind(); 231248a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet 231348a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet RefNamePieces Pieces; 231448a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet 231548a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet if (WantQualifier && QLoc.isValid()) 231648a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet Pieces.push_back(QLoc); 231748a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet 231848a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr) 231948a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet Pieces.push_back(NI.getLoc()); 232048a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet 232148a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet if (WantTemplateArgs && TemplateArgs) 232248a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc, 232348a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet TemplateArgs->RAngleLoc)); 232448a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet 232548a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet if (Kind == DeclarationName::CXXOperatorName) { 232648a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet Pieces.push_back(SourceLocation::getFromRawEncoding( 232748a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet NI.getInfo().CXXOperatorName.BeginOpNameLoc)); 232848a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet Pieces.push_back(SourceLocation::getFromRawEncoding( 232948a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet NI.getInfo().CXXOperatorName.EndOpNameLoc)); 233048a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet } 233148a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet 233248a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet if (WantSinglePiece) { 233348a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd()); 233448a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet Pieces.clear(); 233548a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet Pieces.push_back(R); 233648a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet } 233748a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet 233848a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet return Pieces; 233948a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet} 234048a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet} 234148a8d14fc6f064a5297024c2b34733a4080b2efeFrancois Pichet 2342c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===// 2343c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek// Misc. API hooks. 2344c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek//===----------------------------------------------------------------------===// 2345c0e1d923231d42fb0ac86e56a29ffc5c754657caTed Kremenek 23468c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregorstatic llvm::sys::Mutex EnableMultithreadingMutex; 23478c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregorstatic bool EnabledMultithreading; 23488c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor 23495e4bc590b0ea010e38372d0b4a0aab578a746fe6Benjamin Kramerextern "C" { 23500a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas GregorCXIndex clang_createIndex(int excludeDeclarationsFromPCH, 23510a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor int displayDiagnostics) { 235248615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar // Disable pretty stack trace functionality, which will otherwise be a very 235348615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar // poor citizen of the world and set up all sorts of signal handlers. 235448615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar llvm::DisablePrettyStackTrace = true; 235548615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar 2356c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar // We use crash recovery to make some of our APIs more reliable, implicitly 2357c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar // enable it. 2358c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar llvm::CrashRecoveryContext::Enable(); 2359c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar 23608c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor // Enable support for multithreading in LLVM. 23618c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor { 23628c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor llvm::sys::ScopedLock L(EnableMultithreadingMutex); 23638c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor if (!EnabledMultithreading) { 23648c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor llvm::llvm_start_multithreaded(); 23658c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor EnabledMultithreading = true; 23668c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor } 23678c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor } 23688c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor 2369a030b7cf5e6aad5889b1b662b6979840bc75f87fDouglas Gregor CIndexer *CIdxr = new CIndexer(); 2370e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff if (excludeDeclarationsFromPCH) 2371e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff CIdxr->setOnlyLocalDecls(); 23720a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor if (displayDiagnostics) 23730a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor CIdxr->setDisplayDiagnostics(); 2374e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff return CIdxr; 2375600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff} 2376600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff 23779ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarvoid clang_disposeIndex(CXIndex CIdx) { 23782b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (CIdx) 23792b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor delete static_cast<CIndexer *>(CIdx); 23802bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff} 23812bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff 2382d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenekvoid clang_toggleCrashRecovery(unsigned isEnabled) { 2383d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek if (isEnabled) 2384d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek llvm::CrashRecoveryContext::Enable(); 2385d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek else 2386d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek llvm::CrashRecoveryContext::Disable(); 2387d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek} 2388d2427ddf00aacdc288c386f3882e0821ca9bd27bTed Kremenek 23899ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXTranslationUnit clang_createTranslationUnit(CXIndex CIdx, 2390a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor const char *ast_filename) { 23912b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (!CIdx) 23922b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor return 0; 2393f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 23947d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); 2395389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis FileSystemOptions FileSystemOpts; 2396389db16c63eec6ecfa9b235155252d8da766e94eArgyrios Kyrtzidis FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory(); 23970d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 239828019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags; 2399a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts, 2400a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor CXXIdx->getOnlyLocalDecls(), 2401a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 0, 0, true); 2402a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXTranslationUnit(TU); 2403600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff} 2404600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff 2405b1c031be513705d924038f497279b9b599868ba1Douglas Gregorunsigned clang_defaultEditingTranslationUnitOptions() { 24062a2c50b330e7754499f42173616a36865b5f313bDouglas Gregor return CXTranslationUnit_PrecompiledPreamble | 2407b5af843a20e237ad1a13ad66a867e200695b8c8eDouglas Gregor CXTranslationUnit_CacheCompletionResults; 2408b1c031be513705d924038f497279b9b599868ba1Douglas Gregor} 2409b1c031be513705d924038f497279b9b599868ba1Douglas Gregor 24109ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXTranslationUnit 24119ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarclang_createTranslationUnitFromSourceFile(CXIndex CIdx, 24129ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar const char *source_filename, 24139ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar int num_command_line_args, 24142ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char * const *command_line_args, 24154db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor unsigned num_unsaved_files, 2416a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor struct CXUnsavedFile *unsaved_files) { 2417dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord | 2418ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth CXTranslationUnit_NestedMacroExpansions; 24195a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor return clang_parseTranslationUnit(CIdx, source_filename, 24205a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor command_line_args, num_command_line_args, 24215a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor unsaved_files, num_unsaved_files, 2422dca8ee8b7bc86076916a3a80f553f7a4e98c14afDouglas Gregor Options); 24235a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor} 242419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar 242519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbarstruct ParseTranslationUnitInfo { 242619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar CXIndex CIdx; 242719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar const char *source_filename; 24282ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char *const *command_line_args; 242919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar int num_command_line_args; 243019ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar struct CXUnsavedFile *unsaved_files; 243119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned num_unsaved_files; 243219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned options; 243319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar CXTranslationUnit result; 243419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar}; 2435b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarstatic void clang_parseTranslationUnit_Impl(void *UserData) { 243619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar ParseTranslationUnitInfo *PTUI = 243719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar static_cast<ParseTranslationUnitInfo*>(UserData); 243819ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar CXIndex CIdx = PTUI->CIdx; 243919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar const char *source_filename = PTUI->source_filename; 24402ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char * const *command_line_args = PTUI->command_line_args; 244119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar int num_command_line_args = PTUI->num_command_line_args; 244219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files; 244319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned num_unsaved_files = PTUI->num_unsaved_files; 244419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned options = PTUI->options; 244519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar PTUI->result = 0; 24465a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor 24472b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (!CIdx) 244819ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar return; 2449f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2450e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); 2451e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff 245244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble; 2453467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor // FIXME: Add a flag for modules. 2454467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor TranslationUnitKind TUKind 2455467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete; 245687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor bool CacheCodeCompetionResults 245787c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor = options & CXTranslationUnit_CacheCompletionResults; 245887c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 24595352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor // Configure the diagnostics. 24605352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor DiagnosticOptions DiagOpts; 246125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::IntrusiveRefCntPtr<Diagnostic> 246225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args, 246325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek command_line_args)); 246425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 246525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek // Recover resources if we crash before exiting this function. 246625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic, 246725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> > 246825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek DiagCleanup(Diags.getPtr()); 246925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 247025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> > 247125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek RemappedFiles(new std::vector<ASTUnit::RemappedFile>()); 247225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 247325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek // Recover resources if we crash before exiting this function. 247425a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar< 247525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get()); 2476f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 24774db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != num_unsaved_files; ++I) { 24785f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); 2479f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek const llvm::MemoryBuffer *Buffer 2480a0a270c0f1c0a4e3482438bdc5f4a7bd3d25f0a6Chris Lattner = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); 248125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename, 248225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek Buffer)); 24834db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 2484f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 248525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::OwningPtr<std::vector<const char *> > 248625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek Args(new std::vector<const char*>()); 248725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 248825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek // Recover resources if we crash before exiting this method. 248925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> > 249025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek ArgsCleanup(Args.get()); 249125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 249252ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // Since the Clang C library is primarily used by batch tools dealing with 249352ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // (often very broken) source code, where spell-checking can have a 249452ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // significant negative impact on performance (particularly when 249552ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // precompiled headers are involved), we disable it by default. 2496b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // Only do this if we haven't found a spell-checking-related argument. 2497b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor bool FoundSpellCheckingArgument = false; 2498b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor for (int I = 0; I != num_command_line_args; ++I) { 2499b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 || 2500b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor strcmp(command_line_args[I], "-fspell-checking") == 0) { 2501b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor FoundSpellCheckingArgument = true; 2502b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor break; 2503e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff } 2504b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor } 2505b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor if (!FoundSpellCheckingArgument) 250625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek Args->push_back("-fno-spell-checking"); 2507b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor 250825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek Args->insert(Args->end(), command_line_args, 250925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek command_line_args + num_command_line_args); 2510d93256e55673a17d18543397ec462416acb13792Douglas Gregor 2511c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis // The 'source_filename' argument is optional. If the caller does not 2512c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis // specify it then it is assumed that the source file is specified 2513c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis // in the actual argument list. 2514c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis // Put the source file after command_line_args otherwise if '-x' flag is 2515c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis // present it will be unused. 2516c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis if (source_filename) 251725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek Args->push_back(source_filename); 2518c842955140adf7b0a7c73c61390bf580c50a182dArgyrios Kyrtzidis 251944c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Do we need the detailed preprocessing record? 2520ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth bool NestedMacroExpansions = false; 252144c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (options & CXTranslationUnit_DetailedPreprocessingRecord) { 252225a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek Args->push_back("-Xclang"); 252325a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek Args->push_back("-detailed-preprocessing-record"); 2524ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth NestedMacroExpansions 2525ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth = (options & CXTranslationUnit_NestedMacroExpansions); 252644c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 252744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 2528026f6911bb985c800a54446de9f6da8745ae025aArgyrios Kyrtzidis unsigned NumErrors = Diags->getClient()->getNumErrors(); 2529b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor llvm::OwningPtr<ASTUnit> Unit( 25304ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0 25314ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek /* vector::data() not portable */, 25324ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek Args->size() ? (&(*Args)[0] + Args->size()) :0, 2533b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Diags, 2534b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXXIdx->getClangResourcesPath(), 2535b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXXIdx->getOnlyLocalDecls(), 2536e47be3e9682e82da15059006f43c7f3c021e4fffDouglas Gregor /*CaptureDiagnostics=*/true, 25374ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek RemappedFiles->size() ? &(*RemappedFiles)[0]:0, 253825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek RemappedFiles->size(), 2539299a4a967b02c9f0d0d94ad8560e3ced893f9116Argyrios Kyrtzidis /*RemappedFilesKeepOriginalName=*/true, 2540b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor PrecompilePreamble, 2541467dc88512b4ba4bb16e274ea3771dc1415d31daDouglas Gregor TUKind, 254299ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor CacheCodeCompetionResults, 2543ba7537febdf1bc1cc617e1f1746f2644feba6274Chandler Carruth NestedMacroExpansions)); 2544b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor 2545026f6911bb985c800a54446de9f6da8745ae025aArgyrios Kyrtzidis if (NumErrors != Diags->getClient()->getNumErrors()) { 2546b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // Make sure to check that 'Unit' is non-NULL. 2547b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor if (CXXIdx->getDisplayDiagnostics() && Unit.get()) { 2548b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), 2549b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor DEnd = Unit->stored_diag_end(); 2550b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor D != DEnd; ++D) { 2551b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions()); 2552b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXString Msg = clang_formatDiagnostic(&Diag, 2553b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor clang_defaultDiagnosticDisplayOptions()); 2554b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor fprintf(stderr, "%s\n", clang_getCString(Msg)); 2555b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor clang_disposeString(Msg); 2556b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor } 2557274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor#ifdef LLVM_ON_WIN32 2558b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // On Windows, force a flush, since there may be multiple copies of 2559b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // stderr and stdout in the file system, all with different buffers 2560b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // but writing to the same device. 2561b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor fflush(stderr); 2562b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor#endif 2563b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor } 2564a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 2565d93256e55673a17d18543397ec462416acb13792Douglas Gregor 2566a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek PTUI->result = MakeCXTranslationUnit(Unit.take()); 256719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar} 256819ffd492a31a25fb691098bf79f317e5f3edf177Daniel DunbarCXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, 256919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar const char *source_filename, 25702ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char * const *command_line_args, 257119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar int num_command_line_args, 25729e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar struct CXUnsavedFile *unsaved_files, 257319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned num_unsaved_files, 257419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned options) { 257519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args, 25769e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar num_command_line_args, unsaved_files, 25779e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar num_unsaved_files, options, 0 }; 257819ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar llvm::CrashRecoveryContext CRC; 257919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar 2580bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) { 258160a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "libclang: crash detected during parsing: {\n"); 258260a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'source_filename' : '%s'\n", source_filename); 258360a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'command_line_args' : ["); 258460a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar for (int i = 0; i != num_command_line_args; ++i) { 258560a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar if (i) 258660a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, ", "); 258760a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "'%s'", command_line_args[i]); 258860a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar } 258960a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "],\n"); 259060a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'unsaved_files' : ["); 259160a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar for (unsigned i = 0; i != num_unsaved_files; ++i) { 259260a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar if (i) 259360a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, ", "); 259460a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename, 259560a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar unsaved_files[i].Length); 259660a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar } 259760a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "],\n"); 259860a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'options' : %d,\n", options); 259960a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "}\n"); 260060a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar 260119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar return 0; 26026df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor } else if (getenv("LIBCLANG_RESOURCE_USAGE")) { 26036df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor PrintLibclangResourceUsage(PTUI.result); 260419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar } 26056df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor 260619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar return PTUI.result; 26075b7d8e254f6c2855b37b5521c0aee0a560dab237Steve Naroff} 26085b7d8e254f6c2855b37b5521c0aee0a560dab237Steve Naroff 26091999844e7a18786e61e619e1dc6c789827541863Douglas Gregorunsigned clang_defaultSaveOptions(CXTranslationUnit TU) { 26101999844e7a18786e61e619e1dc6c789827541863Douglas Gregor return CXSaveTranslationUnit_None; 26111999844e7a18786e61e619e1dc6c789827541863Douglas Gregor} 26121999844e7a18786e61e619e1dc6c789827541863Douglas Gregor 26131999844e7a18786e61e619e1dc6c789827541863Douglas Gregorint clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName, 26141999844e7a18786e61e619e1dc6c789827541863Douglas Gregor unsigned options) { 26157ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor if (!TU) 261639c411fa229b2a6747b92f945d1702ee674d3470Douglas Gregor return CXSaveError_InvalidTU; 26177ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 261839c411fa229b2a6747b92f945d1702ee674d3470Douglas Gregor CXSaveError result = static_cast<ASTUnit *>(TU->TUData)->Save(FileName); 26196df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor if (getenv("LIBCLANG_RESOURCE_USAGE")) 26206df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor PrintLibclangResourceUsage(TU); 26216df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor return result; 26227ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor} 262319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar 26249ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarvoid clang_disposeTranslationUnit(CXTranslationUnit CTUnit) { 2625ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar if (CTUnit) { 2626ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar // If the translation unit has been marked as unsafe to free, just discard 2627ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar // it. 2628a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree()) 2629ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return; 2630ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 2631a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek delete static_cast<ASTUnit *>(CTUnit->TUData); 2632a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek disposeCXStringPool(CTUnit->StringPool); 2633a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek delete CTUnit; 2634ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar } 26352bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff} 26360d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 2637e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregorunsigned clang_defaultReparseOptions(CXTranslationUnit TU) { 2638e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor return CXReparse_None; 2639e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor} 2640e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor 2641ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbarstruct ReparseTranslationUnitInfo { 2642ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar CXTranslationUnit TU; 2643ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned num_unsaved_files; 2644ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar struct CXUnsavedFile *unsaved_files; 2645ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned options; 2646ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar int result; 2647ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar}; 2648593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor 2649b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarstatic void clang_reparseTranslationUnit_Impl(void *UserData) { 2650ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar ReparseTranslationUnitInfo *RTUI = 2651ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar static_cast<ReparseTranslationUnitInfo*>(UserData); 2652ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar CXTranslationUnit TU = RTUI->TU; 2653ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned num_unsaved_files = RTUI->num_unsaved_files; 2654ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files; 2655ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned options = RTUI->options; 2656ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar (void) options; 2657ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar RTUI->result = 1; 2658ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 2659abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor if (!TU) 2660ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return; 2661593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor 2662a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); 2663593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor ASTUnit::ConcurrencyCheck Check(*CXXUnit); 2664abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 266525a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> > 266625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek RemappedFiles(new std::vector<ASTUnit::RemappedFile>()); 266725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 266825a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek // Recover resources if we crash before exiting this function. 266925a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar< 267025a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get()); 267125a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek 2672abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor for (unsigned I = 0; I != num_unsaved_files; ++I) { 26735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); 2674abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor const llvm::MemoryBuffer *Buffer 26751abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); 267625a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename, 267725a11e1c5fad62dbad25a265e334720157e3fbc1Ted Kremenek Buffer)); 2678abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor } 2679abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 26804ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0, 26814ee9926671913ea6189ef9840a244d7c4385a7d5Ted Kremenek RemappedFiles->size())) 2682593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor RTUI->result = 0; 2683abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 2684593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor 2685ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbarint clang_reparseTranslationUnit(CXTranslationUnit TU, 2686ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned num_unsaved_files, 2687ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar struct CXUnsavedFile *unsaved_files, 2688ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned options) { 2689ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files, 2690ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar options, 0 }; 2691ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar llvm::CrashRecoveryContext CRC; 2692ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 2693bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) { 2694b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar fprintf(stderr, "libclang: crash detected during reparsing\n"); 2695a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true); 2696ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return 1; 26976df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor } else if (getenv("LIBCLANG_RESOURCE_USAGE")) 26986df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor PrintLibclangResourceUsage(TU); 26991dfb26af4d6aa4f7818e256659a79f1ec2cba784Ted Kremenek 2700ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return RTUI.result; 2701ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar} 2702ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 2703df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 27049ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) { 27052b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (!CTUnit) 2706ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 2707f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2708a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData); 2709ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(CXXUnit->getOriginalSourceFileName(), true); 2710af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff} 27111eb79b58e56b99cf557d5d353586a10c5360364dDaniel Dunbar 27127eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas GregorCXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) { 2713b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } }; 27147eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor return Result; 27157eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor} 27167eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor 2717fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C" 2718600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff 2719fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 27201db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor// CXSourceLocation and CXSourceRange Operations. 27211db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor//===----------------------------------------------------------------------===// 27221db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 2723b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregorextern "C" { 2724b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceLocation clang_getNullLocation() { 27255352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor CXSourceLocation Result = { { 0, 0 }, 0 }; 2726b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return Result; 2727b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2728b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 2729b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregorunsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) { 273090a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar return (loc1.ptr_data[0] == loc2.ptr_data[0] && 273190a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar loc1.ptr_data[1] == loc2.ptr_data[1] && 273290a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar loc1.int_data == loc2.int_data); 2733b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2734b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 2735b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceLocation clang_getLocation(CXTranslationUnit tu, 2736b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor CXFile file, 2737b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor unsigned line, 2738b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor unsigned column) { 273942748ec5cb2d75fe0dbb3a6db5aee6c11b5dc190Douglas Gregor if (!tu || !file) 2740b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return clang_getNullLocation(); 274142748ec5cb2d75fe0dbb3a6db5aee6c11b5dc190Douglas Gregor 274286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor bool Logging = ::getenv("LIBCLANG_LOGGING"); 2743a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData); 274486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor const FileEntry *File = static_cast<const FileEntry *>(file); 2745b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor SourceLocation SLoc 274686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor = CXXUnit->getSourceManager().getLocation(File, line, column); 274786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (SLoc.isInvalid()) { 274886a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (Logging) 274986a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor llvm::errs() << "clang_getLocation(\"" << File->getName() 275086a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor << "\", " << line << ", " << column << ") = invalid\n"; 275186a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor return clang_getNullLocation(); 275286a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor } 275386a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor 275486a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor if (Logging) 275586a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor llvm::errs() << "clang_getLocation(\"" << File->getName() 275686a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor << "\", " << line << ", " << column << ") = " 275786a4d0dd6a630639aab7715323ed068940e650afDouglas Gregor << SLoc.getRawEncoding() << "\n"; 275883889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 275983889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc); 276083889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall} 276183889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 276283889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid ChisnallCXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu, 276383889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall CXFile file, 276483889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall unsigned offset) { 276583889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall if (!tu || !file) 276683889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall return clang_getNullLocation(); 276783889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 2768a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData); 276983889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall SourceLocation Start 277083889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall = CXXUnit->getSourceManager().getLocation( 277183889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall static_cast<const FileEntry *>(file), 277283889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 1, 1); 277383889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall if (Start.isInvalid()) return clang_getNullLocation(); 277483889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 277583889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall SourceLocation SLoc = Start.getFileLocWithOffset(offset); 277683889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 277783889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall if (SLoc.isInvalid()) return clang_getNullLocation(); 2778f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 27791a9a0bc472ee4fec72ee8be8b575fb66ca600d1bTed Kremenek return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc); 2780b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2781b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 27825352ac06d8f6194825bb2a99ffa009b61bafb503Douglas GregorCXSourceRange clang_getNullRange() { 27835352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor CXSourceRange Result = { { 0, 0 }, 0, 0 }; 27845352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return Result; 27855352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor} 2786d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar 2787b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) { 27885352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor if (begin.ptr_data[0] != end.ptr_data[0] || 27895352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor begin.ptr_data[1] != end.ptr_data[1]) 27905352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullRange(); 2791f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2792f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] }, 27935352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor begin.int_data, end.int_data }; 2794b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return Result; 2795b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2796ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor 2797ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregorunsigned clang_equalRanges(CXSourceRange range1, CXSourceRange range2) 2798ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor{ 2799ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor return range1.ptr_data[0] == range2.ptr_data[0] 2800ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor && range1.ptr_data[1] == range2.ptr_data[1] 2801ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor && range1.begin_int_data == range2.begin_int_data 2802ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor && range1.end_int_data == range2.end_int_data; 2803ab4e83b904d81d8ab1f8c594655822a023cad87dDouglas Gregor} 28049d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek} // end: extern "C" 2805b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 28069d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenekstatic void createNullLocation(CXFile *file, unsigned *line, 28079d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek unsigned *column, unsigned *offset) { 28089d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek if (file) 28099d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek *file = 0; 28109d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek if (line) 28119d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek *line = 0; 28129d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek if (column) 28139d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek *column = 0; 28149d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek if (offset) 28159d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek *offset = 0; 28169d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek return; 28179d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek} 28189d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek 28199d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenekextern "C" { 282020174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruthvoid clang_getExpansionLocation(CXSourceLocation location, 282120174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth CXFile *file, 282220174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth unsigned *line, 282320174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth unsigned *column, 282420174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth unsigned *offset) { 28251db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data); 28261db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 2827bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar if (!location.ptr_data[0] || Loc.isInvalid()) { 28289d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek createNullLocation(file, line, column, offset); 282946766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor return; 283046766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor } 283146766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor 2832bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar const SourceManager &SM = 2833bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar *static_cast<const SourceManager*>(location.ptr_data[0]); 283420174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc); 28351db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 2836cea731a9cb7de3f473d60e5ea544e25621cebd76Chandler Carruth // Check that the FileID is invalid on the expansion location. 28379d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek // This can manifest in invalid code. 283820174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth FileID fileID = SM.getFileID(ExpansionLoc); 2839e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor bool Invalid = false; 2840e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid); 2841e23ac65af568ffe611b0990818ac3a57c856a4d8Douglas Gregor if (!sloc.isFile() || Invalid) { 28429d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek createNullLocation(file, line, column, offset); 28439d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek return; 28449d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek } 28459d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek 28461db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor if (file) 28479d5a165d301cc9df68631e624322dd2a962f65b3Ted Kremenek *file = (void *)SM.getFileEntryForSLocEntry(sloc); 28481db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor if (line) 284920174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth *line = SM.getExpansionLineNumber(ExpansionLoc); 28501db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor if (column) 285120174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth *column = SM.getExpansionColumnNumber(ExpansionLoc); 2852e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor if (offset) 285320174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth *offset = SM.getDecomposedLoc(ExpansionLoc).second; 285420174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth} 285520174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth 285620174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruthvoid clang_getInstantiationLocation(CXSourceLocation location, 285720174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth CXFile *file, 285820174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth unsigned *line, 285920174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth unsigned *column, 286020174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth unsigned *offset) { 286120174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth // Redirect to new API. 286220174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth clang_getExpansionLocation(location, file, line, column, offset); 2863e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor} 2864e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor 2865a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregorvoid clang_getSpellingLocation(CXSourceLocation location, 2866a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor CXFile *file, 2867a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor unsigned *line, 2868a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor unsigned *column, 2869a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor unsigned *offset) { 2870a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data); 2871a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor 28725adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis if (!location.ptr_data[0] || Loc.isInvalid()) 28735adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis return createNullLocation(file, line, column, offset); 2874a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor 2875a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor const SourceManager &SM = 2876a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *static_cast<const SourceManager*>(location.ptr_data[0]); 2877a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor SourceLocation SpellLoc = Loc; 2878a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (SpellLoc.isMacroID()) { 2879a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc); 2880a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (SimpleSpellingLoc.isFileID() && 2881a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first)) 2882a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor SpellLoc = SimpleSpellingLoc; 2883a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor else 2884402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth SpellLoc = SM.getExpansionLoc(SpellLoc); 2885a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor } 2886a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor 2887a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc); 2888a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor FileID FID = LocInfo.first; 2889a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor unsigned FileOffset = LocInfo.second; 2890a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor 28915adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis if (FID.isInvalid()) 28925adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis return createNullLocation(file, line, column, offset); 28935adc0515aaacb6c4d4f0c9626d86c1e5c177467cArgyrios Kyrtzidis 2894a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (file) 2895a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *file = (void *)SM.getFileEntryForID(FID); 2896a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (line) 2897a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *line = SM.getLineNumber(FID, FileOffset); 2898a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (column) 2899a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *column = SM.getColumnNumber(FID, FileOffset); 2900a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor if (offset) 2901a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor *offset = FileOffset; 2902a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor} 2903a9b06d4c246d6c301e3dd1844f5dba669ed9c631Douglas Gregor 29041db19dea8d221f27be46332d668d1e2decb7f1abDouglas GregorCXSourceLocation clang_getRangeStart(CXSourceRange range) { 2905f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, 29065352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor range.begin_int_data }; 29071db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor return Result; 29081db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor} 29091db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 29101db19dea8d221f27be46332d668d1e2decb7f1abDouglas GregorCXSourceLocation clang_getRangeEnd(CXSourceRange range) { 2911bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, 29125352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor range.end_int_data }; 29131db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor return Result; 29141db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor} 29151db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 2916b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} // end: extern "C" 2917b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 29181db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor//===----------------------------------------------------------------------===// 2919fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek// CXFile Operations. 2920fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 2921fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 2922fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekextern "C" { 292374844072411bae91d5dbb89955d200cbe1e0a1c8Ted KremenekCXString clang_getFileName(CXFile SFile) { 292498258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor if (!SFile) 2925a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return createCXString((const char*)NULL); 2926f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 292788145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff FileEntry *FEnt = static_cast<FileEntry *>(SFile); 292874844072411bae91d5dbb89955d200cbe1e0a1c8Ted Kremenek return createCXString(FEnt->getName()); 292988145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff} 293088145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff 293188145034694ed5267fa6fa5febc54fadc02bd479Steve Narofftime_t clang_getFileTime(CXFile SFile) { 293298258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor if (!SFile) 293398258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor return 0; 2934f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 293588145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff FileEntry *FEnt = static_cast<FileEntry *>(SFile); 293688145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff return FEnt->getModificationTime(); 2937ee9405e807d7c447c0143c2bd865b759192e97b3Steve Naroff} 2938f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2939b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXFile clang_getFile(CXTranslationUnit tu, const char *file_name) { 2940b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor if (!tu) 2941b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return 0; 2942f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2943a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData); 2944f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2945b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor FileManager &FMgr = CXXUnit->getFileManager(); 294639b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner return const_cast<FileEntry *>(FMgr.getFile(file_name)); 2947b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2948f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2949dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregorunsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file) { 2950dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor if (!tu || !file) 2951dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor return 0; 2952dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 2953dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData); 2954dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor FileEntry *FEnt = static_cast<FileEntry *>(file); 2955dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor return CXXUnit->getPreprocessor().getHeaderSearchInfo() 2956dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor .isFileMultipleIncludeGuarded(FEnt); 2957dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor} 2958dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 2959fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C" 2960fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 2961fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 2962fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek// CXCursor Operations. 2963fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 2964fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 2965fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekstatic Decl *getDeclFromExpr(Stmt *E) { 2966c2954616fbd11f5a6117236f58420029b773a639Argyrios Kyrtzidis if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) 2967db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor return getDeclFromExpr(CE->getSubExpr()); 2968db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor 2969fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E)) 2970fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return RefExpr->getDecl(); 297138f28c1189142429384996409fffbc57f67b5c60Douglas Gregor if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E)) 297238f28c1189142429384996409fffbc57f67b5c60Douglas Gregor return RefExpr->getDecl(); 2973fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) 2974fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return ME->getMemberDecl(); 2975fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E)) 2976fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return RE->getDecl(); 2977db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) 297812f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0; 2979db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor 2980fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (CallExpr *CE = dyn_cast<CallExpr>(E)) 2981fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return getDeclFromExpr(CE->getCallee()); 29825f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E)) 298393798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor if (!CE->isElidable()) 298493798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor return CE->getConstructor(); 2985fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E)) 2986fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return OME->getMethodDecl(); 2987f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2988db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E)) 2989db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor return PE->getProtocol(); 2990c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor if (SubstNonTypeTemplateParmPackExpr *NTTP 2991c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E)) 2992c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor return NTTP->getParameterPack(); 299394d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E)) 299494d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) || 299594d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor isa<ParmVarDecl>(SizeOfPack->getPack())) 299694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor return SizeOfPack->getPack(); 2997db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor 2998fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return 0; 2999fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} 3000ee9405e807d7c447c0143c2bd865b759192e97b3Steve Naroff 3001c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbarstatic SourceLocation getLocationFromExpr(Expr *E) { 3002c2954616fbd11f5a6117236f58420029b773a639Argyrios Kyrtzidis if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) 3003c2954616fbd11f5a6117236f58420029b773a639Argyrios Kyrtzidis return getLocationFromExpr(CE->getSubExpr()); 3004c2954616fbd11f5a6117236f58420029b773a639Argyrios Kyrtzidis 3005c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) 3006c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return /*FIXME:*/Msg->getLeftLoc(); 3007c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 3008c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return DRE->getLocation(); 300938f28c1189142429384996409fffbc57f67b5c60Douglas Gregor if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E)) 301038f28c1189142429384996409fffbc57f67b5c60Douglas Gregor return RefExpr->getLocation(); 3011c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (MemberExpr *Member = dyn_cast<MemberExpr>(E)) 3012c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return Member->getMemberLoc(); 3013c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E)) 3014c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return Ivar->getLocation(); 301594d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E)) 301694d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor return SizeOfPack->getPackLoc(); 301794d96291cd041adc5731a2294828a9c20e450b74Douglas Gregor 3018c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return E->getLocStart(); 3019c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar} 3020c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar 3021fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekextern "C" { 3022f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3023f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekunsigned clang_visitChildren(CXCursor parent, 3024b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXCursorVisitor visitor, 3025b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXClientData client_data) { 3026a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data, 302704a9eb3f0dfcc42b317057e236f73e9b196a2ff8Douglas Gregor false); 3028b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return CursorVis.VisitChildren(parent); 3029b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} 3030b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor 30313387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#ifndef __has_feature 30323387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#define __has_feature(x) 0 30333387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#endif 30343387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#if __has_feature(blocks) 30353387c65a094a02b2a94c05111d035a97d3d5c794David Chisnalltypedef enum CXChildVisitResult 30363387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent); 30373387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall 30383387c65a094a02b2a94c05111d035a97d3d5c794David Chisnallstatic enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent, 30393387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall CXClientData client_data) { 30403387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data; 30413387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall return block(cursor, parent); 30423387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall} 30433387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#else 30443387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall// If we are compiled with a compiler that doesn't have native blocks support, 30453387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall// define and call the block manually, so the 30463387c65a094a02b2a94c05111d035a97d3d5c794David Chisnalltypedef struct _CXChildVisitResult 30473387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall{ 30483387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall void *isa; 30493387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall int flags; 30503387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall int reserved; 30519e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor, 30529e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar CXCursor); 30533387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall} *CXCursorVisitorBlock; 30543387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall 30553387c65a094a02b2a94c05111d035a97d3d5c794David Chisnallstatic enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent, 30563387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall CXClientData client_data) { 30573387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data; 30583387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall return block->invoke(block, cursor, parent); 30593387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall} 30603387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall#endif 30613387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall 30623387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall 30639e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbarunsigned clang_visitChildrenWithBlock(CXCursor parent, 30649e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar CXCursorVisitorBlock block) { 30653387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall return clang_visitChildren(parent, visitWithBlock, block); 30663387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall} 30673387c65a094a02b2a94c05111d035a97d3d5c794David Chisnall 306878205d4bada39d95097e766af9eb30cdd0159461Douglas Gregorstatic CXString getDeclSpelling(Decl *D) { 306978205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D); 3070e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor if (!ND) { 30715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D)) 3072e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl()) 3073e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor return createCXString(Property->getIdentifier()->getName()); 3074e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor 3075ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 3076e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor } 3077e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor 307878205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) 3079ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(OMD->getSelector().getAsString()); 3080f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 308178205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND)) 308278205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor // No, this isn't the same as the code below. getIdentifier() is non-virtual 308378205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor // and returns different names. NamedDecl returns the class name and 308478205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor // ObjCCategoryImplDecl returns the category name. 3085ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(CIMP->getIdentifier()->getNameStart()); 3086f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 30870a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor if (isa<UsingDirectiveDecl>(D)) 30880a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor return createCXString(""); 30890a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 309050aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek llvm::SmallString<1024> S; 309150aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek llvm::raw_svector_ostream os(S); 309250aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek ND->printName(os); 309350aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek 309450aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek return createCXString(os.str()); 309578205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor} 3096f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 30979ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXString clang_getCursorSpelling(CXCursor C) { 30987eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor if (clang_isTranslationUnit(C.kind)) 3099a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return clang_getTranslationUnitSpelling( 3100a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek static_cast<CXTranslationUnit>(C.data[2])); 31017eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor 3102f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff if (clang_isReference(C.kind)) { 3103f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff switch (C.kind) { 3104acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar case CXCursor_ObjCSuperClassRef: { 31052e331b938b38057e333fab0ba841130ea8467794Douglas Gregor ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first; 3106ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(Super->getIdentifier()->getNameStart()); 3107acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar } 3108acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar case CXCursor_ObjCClassRef: { 31091adb082a709f7b588f03672999294e061234b2cfDouglas Gregor ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; 3110ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(Class->getIdentifier()->getNameStart()); 3111acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar } 3112acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar case CXCursor_ObjCProtocolRef: { 311378db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first; 3114f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor assert(OID && "getCursorSpelling(): Missing protocol decl"); 3115ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(OID->getIdentifier()->getNameStart()); 3116acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar } 31173064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: { 31183064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); 31193064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return createCXString(B->getType().getAsString()); 31203064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 31217d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor case CXCursor_TypeRef: { 31227d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor TypeDecl *Type = getCursorTypeRef(C).first; 31237d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor assert(Type && "Missing type decl"); 31247d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 3125ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(getCursorContext(C).getTypeDeclType(Type). 3126ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek getAsString()); 31277d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor } 31280b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: { 31290b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor TemplateDecl *Template = getCursorTemplateRef(C).first; 31306931900f43cea558c6974075256c07728dbfecc6Douglas Gregor assert(Template && "Missing template decl"); 31310b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 31320b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return createCXString(Template->getNameAsString()); 31330b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor } 31346931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 31356931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: { 31366931900f43cea558c6974075256c07728dbfecc6Douglas Gregor NamedDecl *NS = getCursorNamespaceRef(C).first; 31376931900f43cea558c6974075256c07728dbfecc6Douglas Gregor assert(NS && "Missing namespace decl"); 31386931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 31396931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return createCXString(NS->getNameAsString()); 31406931900f43cea558c6974075256c07728dbfecc6Douglas Gregor } 31417d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 3142a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: { 3143a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor FieldDecl *Field = getCursorMemberRef(C).first; 3144a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor assert(Field && "Missing member decl"); 3145a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 3146a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return createCXString(Field->getNameAsString()); 3147a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 3148a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 314936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: { 315036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor LabelStmt *Label = getCursorLabelRef(C).first; 315136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor assert(Label && "Missing label"); 315236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 3153ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner return createCXString(Label->getName()); 315436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 315536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 31561f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: { 31571f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first; 31581f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Decl *D = Storage.dyn_cast<Decl *>()) { 31591f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) 31601f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(ND->getNameAsString()); 31611f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(""); 31621f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 31631f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) 31641f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(E->getName().getAsString()); 31651f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedTemplateStorage *Ovl 31661f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = Storage.get<OverloadedTemplateStorage*>(); 31671f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Ovl->size() == 0) 31681f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(""); 31691f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString((*Ovl->begin())->getNameAsString()); 31701f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 31711f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 3172acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar default: 3173ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString("<not implemented>"); 3174f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff } 3175f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff } 317697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 317797b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) { 317897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor Decl *D = getDeclFromExpr(getCursorExpr(C)); 317997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (D) 318078205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor return getDeclSpelling(D); 3181ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 318297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor } 318397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 318436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (clang_isStatement(C.kind)) { 318536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor Stmt *S = getCursorStmt(C); 318636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) 3187ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner return createCXString(Label->getName()); 318836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 318936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString(""); 319036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 319136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 31929b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth if (C.kind == CXCursor_MacroExpansion) 31939e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth return createCXString(getCursorMacroExpansion(C)->getName() 31944ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor ->getNameStart()); 31954ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor 3196572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor if (C.kind == CXCursor_MacroDefinition) 3197572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor return createCXString(getCursorMacroDefinition(C)->getName() 3198572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor ->getNameStart()); 3199572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor 3200ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (C.kind == CXCursor_InclusionDirective) 3201ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return createCXString(getCursorInclusionDirective(C)->getFileName()); 3202ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 320360cbfacd947590f83257a4191566dda92fbbde69Douglas Gregor if (clang_isDeclaration(C.kind)) 320460cbfacd947590f83257a4191566dda92fbbde69Douglas Gregor return getDeclSpelling(getCursorDecl(C)); 3205e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 3206ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 3207f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff} 3208f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff 3209358559d8d7b458c5f64941842383a16e61f0828dDouglas GregorCXString clang_getCursorDisplayName(CXCursor C) { 3210358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (!clang_isDeclaration(C.kind)) 3211358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return clang_getCursorSpelling(C); 3212358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3213358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor Decl *D = getCursorDecl(C); 3214358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (!D) 3215358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(""); 3216358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3217358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy; 3218358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) 3219358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor D = FunTmpl->getTemplatedDecl(); 3220358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3221358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { 3222358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::SmallString<64> Str; 3223358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::raw_svector_ostream OS(Str); 3224358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << Function->getNameAsString(); 3225358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Function->getPrimaryTemplate()) 3226358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "<>"; 3227358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "("; 3228358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) { 3229358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (I) 3230358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ", "; 3231358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << Function->getParamDecl(I)->getType().getAsString(Policy); 3232358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 3233358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3234358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Function->isVariadic()) { 3235358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Function->getNumParams()) 3236358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ", "; 3237358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "..."; 3238358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 3239358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ")"; 3240358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(OS.str()); 3241358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 3242358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3243358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) { 3244358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::SmallString<64> Str; 3245358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::raw_svector_ostream OS(Str); 3246358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ClassTemplate->getNameAsString(); 3247358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "<"; 3248358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor TemplateParameterList *Params = ClassTemplate->getTemplateParameters(); 3249358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor for (unsigned I = 0, N = Params->size(); I != N; ++I) { 3250358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (I) 3251358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ", "; 3252358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3253358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor NamedDecl *Param = Params->getParam(I); 3254358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Param->getIdentifier()) { 3255358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << Param->getIdentifier()->getName(); 3256358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor continue; 3257358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 3258358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3259358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor // There is no parameter name, which makes this tricky. Try to come up 3260358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor // with something useful that isn't too long. 3261358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) 3262358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << (TTP->wasDeclaredWithTypename()? "typename" : "class"); 3263358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor else if (NonTypeTemplateParmDecl *NTTP 3264358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor = dyn_cast<NonTypeTemplateParmDecl>(Param)) 3265358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << NTTP->getType().getAsString(Policy); 3266358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor else 3267358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "template<...> class"; 3268358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 3269358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3270358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ">"; 3271358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(OS.str()); 3272358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 3273358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3274358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (ClassTemplateSpecializationDecl *ClassSpec 3275358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 3276358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor // If the type was explicitly written, use that. 3277358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten()) 3278358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(TSInfo->getType().getAsString(Policy)); 3279358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3280358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::SmallString<64> Str; 3281358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::raw_svector_ostream OS(Str); 3282358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ClassSpec->getNameAsString(); 3283358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << TemplateSpecializationType::PrintTemplateArgumentList( 3284910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor ClassSpec->getTemplateArgs().data(), 3285910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor ClassSpec->getTemplateArgs().size(), 3286358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor Policy); 3287358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(OS.str()); 3288358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 3289358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3290358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return clang_getCursorSpelling(C); 3291358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor} 3292358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 3293e68fff6fc083c6270d835216a3de0b82c6ef0310Ted KremenekCXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { 329489922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff switch (Kind) { 3295e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_FunctionDecl: 3296e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("FunctionDecl"); 3297e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_TypedefDecl: 3298e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("TypedefDecl"); 3299e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_EnumDecl: 3300e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("EnumDecl"); 3301e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_EnumConstantDecl: 3302e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("EnumConstantDecl"); 3303e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_StructDecl: 3304e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("StructDecl"); 3305e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnionDecl: 3306e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnionDecl"); 3307e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ClassDecl: 3308e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ClassDecl"); 3309e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_FieldDecl: 3310e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("FieldDecl"); 3311e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_VarDecl: 3312e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("VarDecl"); 3313e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ParmDecl: 3314e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ParmDecl"); 3315e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCInterfaceDecl: 3316e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCInterfaceDecl"); 3317e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCCategoryDecl: 3318e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCCategoryDecl"); 3319e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCProtocolDecl: 3320e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCProtocolDecl"); 3321e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCPropertyDecl: 3322e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCPropertyDecl"); 3323e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCIvarDecl: 3324e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCIvarDecl"); 3325e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCInstanceMethodDecl: 3326e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCInstanceMethodDecl"); 3327e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCClassMethodDecl: 3328e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCClassMethodDecl"); 3329e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCImplementationDecl: 3330e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCImplementationDecl"); 3331e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCCategoryImplDecl: 3332e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCCategoryImplDecl"); 33338bd5a69999cfd06b6b5a58fdd04e4f802b2df5a4Ted Kremenek case CXCursor_CXXMethod: 33348bd5a69999cfd06b6b5a58fdd04e4f802b2df5a4Ted Kremenek return createCXString("CXXMethod"); 3335e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnexposedDecl: 3336e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnexposedDecl"); 3337e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCSuperClassRef: 3338e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCSuperClassRef"); 3339e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCProtocolRef: 3340e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCProtocolRef"); 3341e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCClassRef: 3342e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCClassRef"); 3343e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_TypeRef: 3344e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("TypeRef"); 33450b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: 33460b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return createCXString("TemplateRef"); 33476931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: 33486931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return createCXString("NamespaceRef"); 3349a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: 3350a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return createCXString("MemberRef"); 335136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: 335236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString("LabelRef"); 33531f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 33541f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString("OverloadedDeclRef"); 3355e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnexposedExpr: 3356e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnexposedExpr"); 33571ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek case CXCursor_BlockExpr: 33581ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek return createCXString("BlockExpr"); 3359e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_DeclRefExpr: 3360e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("DeclRefExpr"); 3361e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_MemberRefExpr: 3362e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("MemberRefExpr"); 3363e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_CallExpr: 3364e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("CallExpr"); 3365e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCMessageExpr: 3366e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCMessageExpr"); 3367e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnexposedStmt: 3368e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnexposedStmt"); 336936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelStmt: 337036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString("LabelStmt"); 3371e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_InvalidFile: 3372e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("InvalidFile"); 3373292db6401f040795db3ea4e00fc02622d6c3ba1dTed Kremenek case CXCursor_InvalidCode: 3374292db6401f040795db3ea4e00fc02622d6c3ba1dTed Kremenek return createCXString("InvalidCode"); 3375e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_NoDeclFound: 3376e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("NoDeclFound"); 3377e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_NotImplemented: 3378e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("NotImplemented"); 3379e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_TranslationUnit: 3380e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("TranslationUnit"); 3381e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek case CXCursor_UnexposedAttr: 3382e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek return createCXString("UnexposedAttr"); 3383e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek case CXCursor_IBActionAttr: 3384e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek return createCXString("attribute(ibaction)"); 33859f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor case CXCursor_IBOutletAttr: 33869f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return createCXString("attribute(iboutlet)"); 3387857e918a8a40deb128840308a318bf623d68295fTed Kremenek case CXCursor_IBOutletCollectionAttr: 3388857e918a8a40deb128840308a318bf623d68295fTed Kremenek return createCXString("attribute(iboutletcollection)"); 33896639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis case CXCursor_CXXFinalAttr: 33906639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis return createCXString("attribute(final)"); 33916639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis case CXCursor_CXXOverrideAttr: 33926639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis return createCXString("attribute(override)"); 33939f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor case CXCursor_PreprocessingDirective: 33949f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return createCXString("preprocessing directive"); 3395572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor case CXCursor_MacroDefinition: 3396572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor return createCXString("macro definition"); 33979b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth case CXCursor_MacroExpansion: 33989b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth return createCXString("macro expansion"); 3399ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor case CXCursor_InclusionDirective: 3400ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return createCXString("inclusion directive"); 34018f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek case CXCursor_Namespace: 34028f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek return createCXString("Namespace"); 3403a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek case CXCursor_LinkageSpec: 3404a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek return createCXString("LinkageSpec"); 34053064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: 34063064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return createCXString("C++ base class specifier"); 340701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case CXCursor_Constructor: 340801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return createCXString("CXXConstructor"); 340901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case CXCursor_Destructor: 341001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return createCXString("CXXDestructor"); 341101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case CXCursor_ConversionFunction: 341201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return createCXString("CXXConversion"); 3413fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_TemplateTypeParameter: 3414fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("TemplateTypeParameter"); 3415fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_NonTypeTemplateParameter: 3416fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("NonTypeTemplateParameter"); 3417fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_TemplateTemplateParameter: 3418fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("TemplateTemplateParameter"); 3419fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_FunctionTemplate: 3420fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("FunctionTemplate"); 342139d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor case CXCursor_ClassTemplate: 342239d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor return createCXString("ClassTemplate"); 342374dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor case CXCursor_ClassTemplatePartialSpecialization: 342474dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return createCXString("ClassTemplatePartialSpecialization"); 34256931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceAlias: 34266931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return createCXString("NamespaceAlias"); 34270a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor case CXCursor_UsingDirective: 34280a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor return createCXString("UsingDirective"); 34297e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor case CXCursor_UsingDeclaration: 34307e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return createCXString("UsingDeclaration"); 3431162e1c1b487352434552147967c3dd296ebee2f7Richard Smith case CXCursor_TypeAliasDecl: 3432352697a87bca664356f21a838b162084013625eaDouglas Gregor return createCXString("TypeAliasDecl"); 3433352697a87bca664356f21a838b162084013625eaDouglas Gregor case CXCursor_ObjCSynthesizeDecl: 3434352697a87bca664356f21a838b162084013625eaDouglas Gregor return createCXString("ObjCSynthesizeDecl"); 3435352697a87bca664356f21a838b162084013625eaDouglas Gregor case CXCursor_ObjCDynamicDecl: 3436352697a87bca664356f21a838b162084013625eaDouglas Gregor return createCXString("ObjCDynamicDecl"); 343789922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff } 3438e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 3439deb06bd3566e18f677e76bc435d478b033fe328bTed Kremenek llvm_unreachable("Unhandled CXCursorKind"); 3440a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return createCXString((const char*) 0); 3441600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff} 344289922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff 3443064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidisstruct GetCursorData { 3444064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis SourceLocation TokenBeginLoc; 34454b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis bool PointsAtMacroArgExpansion; 3446064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis CXCursor &BestCursor; 3447064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis 34484b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis GetCursorData(SourceManager &SM, 34494b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis SourceLocation tokenBegin, CXCursor &outputCursor) 34504b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) { 34514b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin); 34524b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis } 3453064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis}; 3454064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis 34554b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidisstatic enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, 34564b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis CXCursor parent, 34574b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis CXClientData client_data) { 3458064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis GetCursorData *Data = static_cast<GetCursorData *>(client_data); 3459064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis CXCursor *BestCursor = &Data->BestCursor; 34604b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis 34614b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis // If we point inside a macro argument we should provide info of what the 34624b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis // token is so use the actual cursor, don't replace it with a macro expansion 34634b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis // cursor. 34644b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion) 34654b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis return CXChildVisit_Recurse; 3466064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis 3467064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis if (clang_isExpression(cursor.kind) && 3468064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis clang_isDeclaration(BestCursor->kind)) { 3469064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis Decl *D = getCursorDecl(*BestCursor); 3470064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis 3471064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis // Avoid having the cursor of an expression replace the declaration cursor 3472064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis // when the expression source range overlaps the declaration range. 3473064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis // This can happen for C++ constructor expressions whose range generally 3474064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis // include the variable declaration, e.g.: 3475064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor. 3476064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() && 3477064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis D->getLocation() == Data->TokenBeginLoc) 3478064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis return CXChildVisit_Break; 3479064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis } 3480064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis 348193798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor // If our current best cursor is the construction of a temporary object, 348293798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor // don't replace that cursor with a type reference, because we want 348393798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor // clang_getCursor() to point at the constructor. 348493798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor if (clang_isExpression(BestCursor->kind) && 348593798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) && 348693798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor cursor.kind == CXCursor_TypeRef) 348793798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor return CXChildVisit_Recurse; 348893798e25d68e2d146cff9bd0355d4b7b1ca765f1Douglas Gregor 348985fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor // Don't override a preprocessing cursor with another preprocessing 349085fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor // cursor; we want the outermost preprocessing cursor. 349185fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor if (clang_isPreprocessing(cursor.kind) && 349285fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor clang_isPreprocessing(BestCursor->kind)) 349385fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor return CXChildVisit_Recurse; 349485fe1560b061b5f93a52dbd07cddd6e808854710Douglas Gregor 349533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor *BestCursor = cursor; 349633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return CXChildVisit_Recurse; 349733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor} 3498e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 3499b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { 3500b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor if (!TU) 3501f462989fe8d6f59ab2d7d0fe2b4b96292ce706eaTed Kremenek return clang_getNullCursor(); 3502e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 3503a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); 3504bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor ASTUnit::ConcurrencyCheck Check(*CXXUnit); 3505bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor 3506a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor // Translate the given source location to make it point at the beginning of 3507a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor // the token under the cursor. 3508a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek SourceLocation SLoc = cxloc::translateSourceLocation(Loc); 3509a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek 3510a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek // Guard against an invalid SourceLocation, or we may assert in one 3511a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek // of the following calls. 3512a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek if (SLoc.isInvalid()) 3513a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek return clang_getNullCursor(); 3514a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek 351540749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor bool Logging = getenv("LIBCLANG_LOGGING"); 3516a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(), 3517a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor CXXUnit->getASTContext().getLangOptions()); 3518a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 351933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound); 352033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor if (SLoc.isValid()) { 352133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // FIXME: Would be great to have a "hint" cursor, then walk from that 352233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // hint cursor upward until we find a cursor whose source range encloses 352333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // the region of interest, rather than starting from the translation unit. 35244b43b305342ae2e49d473d0fa6152e5d0c343765Argyrios Kyrtzidis GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result); 3525a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXCursor Parent = clang_getTranslationUnitCursor(TU); 3526064c44b8a17d4c426b87ad1c58de81d76a13fca3Argyrios Kyrtzidis CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData, 352708e0bc16b3312c27e87d33be7dcf3d4fe5bdd2e2Douglas Gregor /*VisitPreprocessorLast=*/true, 352808e0bc16b3312c27e87d33be7dcf3d4fe5bdd2e2Douglas Gregor SourceLocation(SLoc)); 352933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CursorVis.VisitChildren(Parent); 353077128ddd3077fc045751a55bb3226802b15d5510Steve Naroff } 353140749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor 353240749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor if (Logging) { 353340749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor CXFile SearchFile; 353440749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor unsigned SearchLine, SearchColumn; 353540749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor CXFile ResultFile; 353640749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor unsigned ResultLine, ResultColumn; 35376653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor CXString SearchFileName, ResultFileName, KindSpelling, USR; 35386653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : ""; 353940749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor CXSourceLocation ResultLoc = clang_getCursorLocation(Result); 354040749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor 354120174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth clang_getExpansionLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0); 354220174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth clang_getExpansionLocation(ResultLoc, &ResultFile, &ResultLine, 354320174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth &ResultColumn, 0); 354440749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor SearchFileName = clang_getFileName(SearchFile); 354540749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor ResultFileName = clang_getFileName(ResultFile); 354640749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor KindSpelling = clang_getCursorKindSpelling(Result.kind); 35476653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor USR = clang_getCursorUSR(Result); 35486653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n", 354940749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_getCString(SearchFileName), SearchLine, SearchColumn, 355040749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_getCString(KindSpelling), 35516653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor clang_getCString(ResultFileName), ResultLine, ResultColumn, 35526653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor clang_getCString(USR), IsDef); 355340749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_disposeString(SearchFileName); 355440749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_disposeString(ResultFileName); 355540749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor clang_disposeString(KindSpelling); 35566653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor clang_disposeString(USR); 35570aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor 35580aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor CXCursor Definition = clang_getCursorDefinition(Result); 35590aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor if (!clang_equalCursors(Definition, clang_getNullCursor())) { 35600aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition); 35610aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor CXString DefinitionKindSpelling 35620aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor = clang_getCursorKindSpelling(Definition.kind); 35630aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor CXFile DefinitionFile; 35640aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor unsigned DefinitionLine, DefinitionColumn; 356520174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth clang_getExpansionLocation(DefinitionLoc, &DefinitionFile, 356620174221af145554b76a0b0f5e4eb3ac70d05945Chandler Carruth &DefinitionLine, &DefinitionColumn, 0); 35670aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor CXString DefinitionFileName = clang_getFileName(DefinitionFile); 35680aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor fprintf(stderr, " -> %s(%s:%d:%d)\n", 35690aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor clang_getCString(DefinitionKindSpelling), 35700aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor clang_getCString(DefinitionFileName), 35710aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor DefinitionLine, DefinitionColumn); 35720aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor clang_disposeString(DefinitionFileName); 35730aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor clang_disposeString(DefinitionKindSpelling); 35740aefbd8d6a82fe8f70ec92871ea42fa5240a960fDouglas Gregor } 357540749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor } 357640749ee585abc84fbb3c8fdbd8aaac062f153062Douglas Gregor 3577e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return Result; 357877128ddd3077fc045751a55bb3226802b15d5510Steve Naroff} 357977128ddd3077fc045751a55bb3226802b15d5510Steve Naroff 3580738855554394a6afcf39cc8345fd22c3756b8dd0Ted KremenekCXCursor clang_getNullCursor(void) { 35815bfb8c128c2ac8eb4032afc180cdc400a0f953caDouglas Gregor return MakeCXCursorInvalid(CXCursor_InvalidFile); 3582738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek} 3583738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek 3584738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenekunsigned clang_equalCursors(CXCursor X, CXCursor Y) { 3585283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor return X == Y; 3586738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek} 35870d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 35889ce5584553054d0cb934940586aca0186e87fa57Douglas Gregorunsigned clang_hashCursor(CXCursor C) { 35899ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor unsigned Index = 0; 35909ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor if (clang_isExpression(C.kind) || clang_isStatement(C.kind)) 35919ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor Index = 1; 35929ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor 35939ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue( 35949ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor std::make_pair(C.kind, C.data[Index])); 35959ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor} 35969ce5584553054d0cb934940586aca0186e87fa57Douglas Gregor 35979ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isInvalid(enum CXCursorKind K) { 359877128ddd3077fc045751a55bb3226802b15d5510Steve Naroff return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid; 359977128ddd3077fc045751a55bb3226802b15d5510Steve Naroff} 360077128ddd3077fc045751a55bb3226802b15d5510Steve Naroff 36019ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isDeclaration(enum CXCursorKind K) { 360289922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl; 360389922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff} 36042d4d629d8a0de5112c7ae9d05c03ddbf6dcd956aSteve Naroff 36059ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isReference(enum CXCursorKind K) { 3606f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff return K >= CXCursor_FirstRef && K <= CXCursor_LastRef; 3607f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff} 3608f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff 360997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregorunsigned clang_isExpression(enum CXCursorKind K) { 361097b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr; 361197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor} 361297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 361397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregorunsigned clang_isStatement(enum CXCursorKind K) { 361497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt; 361597b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor} 361697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 36178be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregorunsigned clang_isAttribute(enum CXCursorKind K) { 36188be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr; 36198be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor} 36208be80e1e6effd5a333bc70e7f030dc9397d0554eDouglas Gregor 36217eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregorunsigned clang_isTranslationUnit(enum CXCursorKind K) { 36227eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor return K == CXCursor_TranslationUnit; 36237eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor} 36247eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor 36259f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregorunsigned clang_isPreprocessing(enum CXCursorKind K) { 36269f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing; 36279f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor} 36289f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor 3629ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenekunsigned clang_isUnexposed(enum CXCursorKind K) { 3630ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek switch (K) { 3631ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedDecl: 3632ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedExpr: 3633ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedStmt: 3634ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedAttr: 3635ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek return true; 3636ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek default: 3637ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek return false; 3638ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek } 3639ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek} 3640ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek 36419ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXCursorKind clang_getCursorKind(CXCursor C) { 36429efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff return C.kind; 36439efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff} 36449efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff 364598258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas GregorCXSourceLocation clang_getCursorLocation(CXCursor C) { 364698258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor if (clang_isReference(C.kind)) { 3647f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor switch (C.kind) { 3648f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCSuperClassRef: { 3649f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor std::pair<ObjCInterfaceDecl *, SourceLocation> P 3650f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor = getCursorObjCSuperClassRef(C); 3651a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 3652f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 3653f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor 3654f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCProtocolRef: { 3655f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor std::pair<ObjCProtocolDecl *, SourceLocation> P 3656f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor = getCursorObjCProtocolRef(C); 3657a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 3658f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 3659f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor 3660f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCClassRef: { 3661f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor std::pair<ObjCInterfaceDecl *, SourceLocation> P 3662f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor = getCursorObjCClassRef(C); 3663a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 3664f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 36657d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 3666f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_TypeRef: { 36677d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C); 3668a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 36697d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor } 36700b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 36710b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: { 36720b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C); 36730b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 36740b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor } 36750b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 36766931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: { 36776931900f43cea558c6974075256c07728dbfecc6Douglas Gregor std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C); 36786931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 36796931900f43cea558c6974075256c07728dbfecc6Douglas Gregor } 36806931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 3681a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: { 3682a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C); 3683a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 3684a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 3685a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 36863064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: { 36871b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C); 36881b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor if (!BaseSpec) 36891b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return clang_getNullLocation(); 36901b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor 36911b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo()) 36921b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 36931b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor TSInfo->getTypeLoc().getBeginLoc()); 36941b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor 36951b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 36961b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor BaseSpec->getSourceRange().getBegin()); 36973064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 3698f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 369936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: { 370036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C); 370136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), P.second); 370236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 370336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 37041f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 37051f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 37061f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor getCursorOverloadedDeclRef(C).second); 37071f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 3708f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor default: 3709f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor // FIXME: Need a way to enumerate all non-reference cases. 3710f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor llvm_unreachable("Missed a reference kind"); 3711f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 371298258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor } 371397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 371497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) 3715f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return cxloc::translateSourceLocation(getCursorContext(C), 371697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor getLocationFromExpr(getCursorExpr(C))); 371797b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 371836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (clang_isStatement(C.kind)) 371936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 372036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor getCursorStmt(C)->getLocStart()); 372136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 37229f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor if (C.kind == CXCursor_PreprocessingDirective) { 37239f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin(); 37249f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 37259f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 37264807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor 37279b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth if (C.kind == CXCursor_MacroExpansion) { 37284ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor SourceLocation L 37299e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth = cxcursor::getCursorMacroExpansion(C)->getSourceRange().getBegin(); 37304807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 37314807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor } 3732572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor 3733572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor if (C.kind == CXCursor_MacroDefinition) { 3734572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation(); 3735572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 3736572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor } 3737ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 3738ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (C.kind == CXCursor_InclusionDirective) { 3739ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor SourceLocation L 3740ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin(); 3741ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 3742ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor } 3743ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 37449a700d277c38d9afaa7cb3fe93a714bfe9b62eecTed Kremenek if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl) 37455352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullLocation(); 374698258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor 3747f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor Decl *D = getCursorDecl(C); 3748f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor SourceLocation Loc = D->getLocation(); 3749f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D)) 3750f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor Loc = Class->getClassLoc(); 3751007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // FIXME: Multiple variables declared in a single declaration 3752007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // currently lack the information needed to correctly determine their 3753007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // ranges when accounting for the type-specifier. We use context 3754007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, 3755007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // and if so, whether it is the first decl. 3756007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 3757007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (!cxcursor::isFirstInDeclGroup(C)) 3758007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek Loc = VD->getLocation(); 3759007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek } 3760007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek 37612ca54feee89d7277fb967e3247a64f40ef155a82Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), Loc); 376288145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff} 3763a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor 3764a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor} // end extern "C" 3765a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 3766a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorstatic SourceRange getRawCursorExtent(CXCursor C) { 3767a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor if (clang_isReference(C.kind)) { 3768a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor switch (C.kind) { 3769a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_ObjCSuperClassRef: 3770a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorObjCSuperClassRef(C).second; 3771f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3772a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_ObjCProtocolRef: 3773a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorObjCProtocolRef(C).second; 3774f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3775a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_ObjCClassRef: 3776a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorObjCClassRef(C).second; 37777d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 3778a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_TypeRef: 3779a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorTypeRef(C).second; 37800b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 37810b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: 37820b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return getCursorTemplateRef(C).second; 37830b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 37846931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: 37856931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return getCursorNamespaceRef(C).second; 3786a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 3787a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: 3788a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return getCursorMemberRef(C).second; 3789a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 37903064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: 37911b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return getCursorCXXBaseSpecifier(C)->getSourceRange(); 3792f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 379336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: 379436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return getCursorLabelRef(C).second; 379536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 37961f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 37971f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return getCursorOverloadedDeclRef(C).second; 37981f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 3799a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor default: 3800a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor // FIXME: Need a way to enumerate all non-reference cases. 3801a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor llvm_unreachable("Missed a reference kind"); 3802a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor } 3803a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor } 380497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 380597b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) 3806a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorExpr(C)->getSourceRange(); 380733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 380833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor if (clang_isStatement(C.kind)) 3809a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorStmt(C)->getSourceRange(); 3810f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 38116639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis if (clang_isAttribute(C.kind)) 38126639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis return getCursorAttr(C)->getRange(); 38136639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis 3814a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (C.kind == CXCursor_PreprocessingDirective) 3815a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return cxcursor::getCursorPreprocessingDirective(C); 38164807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor 38179b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth if (C.kind == CXCursor_MacroExpansion) 38189e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth return cxcursor::getCursorMacroExpansion(C)->getSourceRange(); 3819572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor 3820a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (C.kind == CXCursor_MacroDefinition) 3821a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return cxcursor::getCursorMacroDefinition(C)->getSourceRange(); 3822ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 3823ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (C.kind == CXCursor_InclusionDirective) 3824ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return cxcursor::getCursorInclusionDirective(C)->getSourceRange(); 3825ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 3826007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) { 3827007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek Decl *D = cxcursor::getCursorDecl(C); 3828007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek SourceRange R = D->getSourceRange(); 3829007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // FIXME: Multiple variables declared in a single declaration 3830007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // currently lack the information needed to correctly determine their 3831007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // ranges when accounting for the type-specifier. We use context 3832007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, 3833007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // and if so, whether it is the first decl. 3834007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 3835007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (!cxcursor::isFirstInDeclGroup(C)) 3836007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek R.setBegin(VD->getLocation()); 3837007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek } 3838007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek return R; 3839007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek } 38406653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor return SourceRange(); 38416653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor} 38426653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor 38436653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor/// \brief Retrieves the "raw" cursor extent, which is then extended to include 38446653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor/// the decl-specifier-seq for declarations. 38456653798ff5ce6deb58112777e21307ccc453133dDouglas Gregorstatic SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) { 38466653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) { 38476653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor Decl *D = cxcursor::getCursorDecl(C); 38486653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor SourceRange R = D->getSourceRange(); 38492494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor 38502494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor // Adjust the start of the location for declarations preceded by 38512494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor // declaration specifiers. 38522494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor SourceLocation StartLoc; 38536653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { 38542494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) 38552494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor StartLoc = TI->getTypeLoc().getSourceRange().getBegin(); 38562494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) { 38572494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo()) 38582494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor StartLoc = TI->getTypeLoc().getSourceRange().getBegin(); 38592494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor } 38606653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor 38612494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor if (StartLoc.isValid() && R.getBegin().isValid() && 38622494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin())) 38632494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor R.setBegin(StartLoc); 38642494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor 38652494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor // FIXME: Multiple variables declared in a single declaration 38662494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor // currently lack the information needed to correctly determine their 38672494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor // ranges when accounting for the type-specifier. We use context 38682494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, 38692494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor // and if so, whether it is the first decl. 38702494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 38712494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor if (!cxcursor::isFirstInDeclGroup(C)) 38722494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor R.setBegin(VD->getLocation()); 38736653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor } 38746653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor 38756653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor return R; 38766653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor } 38776653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor 38786653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor return getRawCursorExtent(C); 38796653798ff5ce6deb58112777e21307ccc453133dDouglas Gregor} 3880a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 3881a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorextern "C" { 3882a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 3883a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas GregorCXSourceRange clang_getCursorExtent(CXCursor C) { 3884a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor SourceRange R = getRawCursorExtent(C); 3885a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (R.isInvalid()) 38865352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullRange(); 3887f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3888a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return cxloc::translateSourceRange(getCursorContext(C), R); 3889a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor} 3890c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor 3891c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas GregorCXCursor clang_getCursorReferenced(CXCursor C) { 3892b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (clang_isInvalid(C.kind)) 3893b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getNullCursor(); 3894f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3895a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXTranslationUnit tu = getCursorTU(C); 38961f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (clang_isDeclaration(C.kind)) { 38971f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = getCursorDecl(C); 38981f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) 3899a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu); 39001f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D)) 3901a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), tu); 39021f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCForwardProtocolDecl *Protocols 39031f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = dyn_cast<ObjCForwardProtocolDecl>(D)) 3904a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu); 39055f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D)) 3906e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl()) 3907e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor return MakeCXCursor(Property, tu); 3908e3c60a7ce9e0f42c7ca2344b33203266aceca1dbDouglas Gregor 3909c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor return C; 39101f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 39111f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 391297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) { 39131f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Expr *E = getCursorExpr(C); 39141f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = getDeclFromExpr(E); 391597b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (D) 3916a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(D, tu); 39171f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 39181f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E)) 3919a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCursorOverloadedDeclRef(Ovl, tu); 39201f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 392197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor return clang_getNullCursor(); 392297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor } 392397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 392436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (clang_isStatement(C.kind)) { 392536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor Stmt *S = getCursorStmt(C); 392636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S)) 392737c2e9664316b013b9a86f841f143f19ffbc0a02Ted Kremenek if (LabelDecl *label = Goto->getLabel()) 392837c2e9664316b013b9a86f841f143f19ffbc0a02Ted Kremenek if (LabelStmt *labelS = label->getStmt()) 392937c2e9664316b013b9a86f841f143f19ffbc0a02Ted Kremenek return MakeCXCursor(labelS, getCursorDecl(C), tu); 393036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 393136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return clang_getNullCursor(); 393236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 393336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 39349b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth if (C.kind == CXCursor_MacroExpansion) { 39359e5bb85ac899eeab7c21b5ff9030c3da6ff4837bChandler Carruth if (MacroDefinition *Def = getCursorMacroExpansion(C)->getDefinition()) 3936a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeMacroDefinitionCursor(Def, tu); 3937bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor } 3938bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor 3939c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor if (!clang_isReference(C.kind)) 3940c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor return clang_getNullCursor(); 3941f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3942c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor switch (C.kind) { 3943c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor case CXCursor_ObjCSuperClassRef: 3944a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu); 3945f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3946f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCProtocolRef: { 3947a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(getCursorObjCProtocolRef(C).first, tu); 3948f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3949f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCClassRef: 3950a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(getCursorObjCClassRef(C).first, tu ); 39517d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 3952f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_TypeRef: 3953a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(getCursorTypeRef(C).first, tu ); 39540b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 39550b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: 3956a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(getCursorTemplateRef(C).first, tu ); 39570b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 39586931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: 3959a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(getCursorNamespaceRef(C).first, tu ); 39606931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 3961a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: 3962a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(getCursorMemberRef(C).first, tu ); 3963a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 39643064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: { 39653064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); 39663064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), 3967a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek tu )); 39683064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 3969f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 397036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: 397136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor // FIXME: We end up faking the "parent" declaration here because we 397236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor // don't want to make CXCursor larger. 397336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return MakeCXCursor(getCursorLabelRef(C).first, 3974a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek static_cast<ASTUnit*>(tu->TUData)->getASTContext() 3975a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek .getTranslationUnitDecl(), 3976a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek tu); 397736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 39781f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 39791f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return C; 39801f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 3981c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor default: 3982c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor // We would prefer to enumerate all non-reference cursor kinds here. 3983c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor llvm_unreachable("Unhandled reference cursor kind"); 3984c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor break; 3985c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor } 3986c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor } 3987f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3988c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor return clang_getNullCursor(); 3989c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor} 3990c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor 3991b699866820102a69d83d6ac6941985c5ef4e8c40Douglas GregorCXCursor clang_getCursorDefinition(CXCursor C) { 3992b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (clang_isInvalid(C.kind)) 3993b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getNullCursor(); 3994f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3995a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXTranslationUnit TU = getCursorTU(C); 3996f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3997b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor bool WasReference = false; 399897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isReference(C.kind) || clang_isExpression(C.kind)) { 3999b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor C = clang_getCursorReferenced(C); 4000b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor WasReference = true; 4001b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 4002b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 40039b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth if (C.kind == CXCursor_MacroExpansion) 4004bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor return clang_getCursorReferenced(C); 4005bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor 4006b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!clang_isDeclaration(C.kind)) 4007b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4008b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4009b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor Decl *D = getCursorDecl(C); 4010b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!D) 4011b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4012f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4013b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor switch (D->getKind()) { 4014b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Declaration kinds that don't really separate the notions of 4015b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // declaration and definition. 4016b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Namespace: 4017b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Typedef: 4018162e1c1b487352434552147967c3dd296ebee2f7Richard Smith case Decl::TypeAlias: 40193e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith case Decl::TypeAliasTemplate: 4020b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::TemplateTypeParm: 4021b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::EnumConstant: 4022b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Field: 4023d98114647e16796a976b04af79975b4f0eacf22bBenjamin Kramer case Decl::IndirectField: 4024b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCIvar: 4025b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCAtDefsField: 4026b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ImplicitParam: 4027b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ParmVar: 4028b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::NonTypeTemplateParm: 4029b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::TemplateTemplateParm: 4030b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCCategoryImpl: 4031b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCImplementation: 40326206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara case Decl::AccessSpec: 4033b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::LinkageSpec: 4034b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCPropertyImpl: 4035b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::FileScopeAsm: 4036b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::StaticAssert: 4037b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Block: 4038ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner case Decl::Label: // FIXME: Is this right?? 4039af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet case Decl::ClassScopeFunctionSpecialization: 4040b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 4041b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4042b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Declaration kinds that don't make any sense here, but are 4043b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // nonetheless harmless. 4044b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::TranslationUnit: 4045b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor break; 4046b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4047b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Declaration kinds for which the definition is not resolvable. 4048b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UnresolvedUsingTypename: 4049b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UnresolvedUsingValue: 4050b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor break; 4051b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4052b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UsingDirective: 4053b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(), 4054a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek TU); 4055b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4056b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::NamespaceAlias: 4057a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU); 4058b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4059b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Enum: 4060b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Record: 4061b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXRecord: 4062b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ClassTemplateSpecialization: 4063b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ClassTemplatePartialSpecialization: 4064952b017601f9c82b51119c3a1600f1312a833db9Douglas Gregor if (TagDecl *Def = cast<TagDecl>(D)->getDefinition()) 4065a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(Def, TU); 4066b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4067b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4068b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Function: 4069b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXMethod: 4070b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXConstructor: 4071b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXDestructor: 4072b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXConversion: { 4073b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor const FunctionDecl *Def = 0; 4074b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (cast<FunctionDecl>(D)->getBody(Def)) 4075a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU); 4076b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4077b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 4078b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4079b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Var: { 408031310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl // Ask the variable if it has a definition. 408131310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl if (VarDecl *Def = cast<VarDecl>(D)->getDefinition()) 4082a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(Def, TU); 408331310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl return clang_getNullCursor(); 4084b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 4085f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4086b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::FunctionTemplate: { 4087b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor const FunctionDecl *Def = 0; 4088b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def)) 4089a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU); 4090b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4091b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 4092f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4093b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ClassTemplate: { 4094b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl() 4095952b017601f9c82b51119c3a1600f1312a833db9Douglas Gregor ->getDefinition()) 40960b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(), 4097a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek TU); 4098b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4099b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 4100b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 41011f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case Decl::Using: 41021f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), 4103a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek D->getLocation(), TU); 4104b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4105b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UsingShadow: 4106b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getCursorDefinition( 4107f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), 4108a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek TU)); 4109b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4110b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCMethod: { 4111b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D); 4112b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (Method->isThisDeclarationADefinition()) 4113b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 4114b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4115b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Dig out the method definition in the associated 4116b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // @implementation, if we have it. 4117b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // FIXME: The ASTs should make finding the definition easier. 4118b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCInterfaceDecl *Class 4119b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) 4120b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCImplementationDecl *ClassImpl = Class->getImplementation()) 4121b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(), 4122b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor Method->isInstanceMethod())) 4123b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (Def->isThisDeclarationADefinition()) 4124a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(Def, TU); 4125b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4126b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4127b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 4128b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4129b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCCategory: 4130b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCCategoryImplDecl *Impl 4131b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = cast<ObjCCategoryDecl>(D)->getImplementation()) 4132a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(Impl, TU); 4133b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4134b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4135b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCProtocol: 4136b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!cast<ObjCProtocolDecl>(D)->isForwardDecl()) 4137b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 4138b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4139b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4140b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCInterface: 4141b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // There are two notions of a "definition" for an Objective-C 4142b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // class: the interface and its implementation. When we resolved a 4143b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // reference to an Objective-C class, produce the @interface as 4144b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // the definition; when we were provided with the interface, 4145b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // produce the @implementation as the definition. 4146b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (WasReference) { 4147b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl()) 4148b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 4149b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } else if (ObjCImplementationDecl *Impl 4150b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = cast<ObjCInterfaceDecl>(D)->getImplementation()) 4151a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(Impl, TU); 4152b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4153f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4154b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCProperty: 4155b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // FIXME: We don't really know where to find the 4156b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // ObjCPropertyImplDecls that implement this property. 4157b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4158b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4159b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCCompatibleAlias: 4160b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCInterfaceDecl *Class 4161b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface()) 4162b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!Class->isForwardDecl()) 4163a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(Class, TU); 4164f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4165b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4166b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 41671f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case Decl::ObjCForwardProtocol: 41681f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D), 4169a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek D->getLocation(), TU); 4170b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 41711f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case Decl::ObjCClass: 41729e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(), 4173a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek TU); 4174b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4175b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Friend: 4176b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl()) 4177a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return clang_getCursorDefinition(MakeCXCursor(Friend, TU)); 4178b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4179b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4180b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::FriendTemplate: 4181b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl()) 4182a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return clang_getCursorDefinition(MakeCXCursor(Friend, TU)); 4183b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4184b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 4185b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4186b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 4187b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor} 4188b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4189b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregorunsigned clang_isCursorDefinition(CXCursor C) { 4190b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!clang_isDeclaration(C.kind)) 4191b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return 0; 4192b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 4193b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getCursorDefinition(C) == C; 4194b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor} 4195b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 41961a9d0503b67a499797141af0fd6d315d5045f0eaDouglas GregorCXCursor clang_getCanonicalCursor(CXCursor C) { 41971a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor if (!clang_isDeclaration(C.kind)) 41981a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor return C; 41991a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor 4200e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis if (Decl *D = getCursorDecl(C)) { 4201debb00f9ce1dd0f855d2b4fff3372b2ceeb20735Argyrios Kyrtzidis if (ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) 4202debb00f9ce1dd0f855d2b4fff3372b2ceeb20735Argyrios Kyrtzidis if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl()) 4203debb00f9ce1dd0f855d2b4fff3372b2ceeb20735Argyrios Kyrtzidis return MakeCXCursor(CatD, getCursorTU(C)); 4204debb00f9ce1dd0f855d2b4fff3372b2ceeb20735Argyrios Kyrtzidis 4205e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D)) 4206e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) 4207e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis return MakeCXCursor(IFD, getCursorTU(C)); 4208e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis 42091a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C)); 4210e2f854ddd365e6837cef3e1a1b7621b32200fc71Argyrios Kyrtzidis } 42111a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor 42121a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor return C; 42131a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor} 42141a9d0503b67a499797141af0fd6d315d5045f0eaDouglas Gregor 42151f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregorunsigned clang_getNumOverloadedDecls(CXCursor C) { 42167c432dd959609a3689c2e4406450c092e6d76d6dDouglas Gregor if (C.kind != CXCursor_OverloadedDeclRef) 42171f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return 0; 42181f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 42191f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first; 42201f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) 42211f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return E->getNumDecls(); 42221f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 42231f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadedTemplateStorage *S 42241f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = Storage.dyn_cast<OverloadedTemplateStorage*>()) 42251f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return S->size(); 42261f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 42271f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = Storage.get<Decl*>(); 42281f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) 4229826faa22bae112e01293a58534a40711043cce65Argyrios Kyrtzidis return Using->shadow_size(); 423095ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian if (isa<ObjCClassDecl>(D)) 423195ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian return 1; 42321f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D)) 42331f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return Protocols->protocol_size(); 42341f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 42351f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return 0; 42361f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 42371f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 42381f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas GregorCXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) { 42397c432dd959609a3689c2e4406450c092e6d76d6dDouglas Gregor if (cursor.kind != CXCursor_OverloadedDeclRef) 42401f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return clang_getNullCursor(); 42411f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 42421f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (index >= clang_getNumOverloadedDecls(cursor)) 42431f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return clang_getNullCursor(); 42441f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 4245a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXTranslationUnit TU = getCursorTU(cursor); 42461f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first; 42471f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) 4248a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(E->decls_begin()[index], TU); 42491f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 42501f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadedTemplateStorage *S 42511f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = Storage.dyn_cast<OverloadedTemplateStorage*>()) 4252a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(S->begin()[index], TU); 42531f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 42541f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = Storage.get<Decl*>(); 42551f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) { 42561f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor // FIXME: This is, unfortunately, linear time. 42571f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor UsingDecl::shadow_iterator Pos = Using->shadow_begin(); 42581f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor std::advance(Pos, index); 4259a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU); 42601f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 42611f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D)) 426295ed7784a335aca53b0c6e952cf31a4cfb633360Fariborz Jahanian return MakeCXCursor(Classes->getForwardInterfaceDecl(), TU); 42631f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D)) 4264a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(Protocols->protocol_begin()[index], TU); 42651f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 42661f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return clang_getNullCursor(); 42671f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 42681f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 42690d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbarvoid clang_getDefinitionSpellingAndExtent(CXCursor C, 42704ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff const char **startBuf, 42714ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff const char **endBuf, 42724ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff unsigned *startLine, 42734ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff unsigned *startColumn, 42744ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff unsigned *endLine, 42759ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar unsigned *endColumn) { 4276283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor assert(getCursorDecl(C) && "CXCursor has null decl"); 4277283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C)); 42784ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff FunctionDecl *FD = dyn_cast<FunctionDecl>(ND); 42794ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody()); 4280f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 42814ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff SourceManager &SM = FD->getASTContext().getSourceManager(); 42824ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *startBuf = SM.getCharacterData(Body->getLBracLoc()); 42834ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *endBuf = SM.getCharacterData(Body->getRBracLoc()); 42844ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *startLine = SM.getSpellingLineNumber(Body->getLBracLoc()); 42854ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc()); 42864ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *endLine = SM.getSpellingLineNumber(Body->getRBracLoc()); 42874ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc()); 42884ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff} 4289f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4290430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor 4291430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas GregorCXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags, 4292430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor unsigned PieceIndex) { 4293430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor RefNamePieces Pieces; 4294430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor 4295430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor switch (C.kind) { 4296430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor case CXCursor_MemberRefExpr: 4297430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor if (MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C))) 4298430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(), 4299430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor E->getQualifierLoc().getSourceRange()); 4300430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor break; 4301430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor 4302430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor case CXCursor_DeclRefExpr: 4303430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor if (DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) 4304430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor Pieces = buildPieces(NameFlags, false, E->getNameInfo(), 4305430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor E->getQualifierLoc().getSourceRange(), 4306430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor E->getExplicitTemplateArgsOpt()); 4307430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor break; 4308430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor 4309430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor case CXCursor_CallExpr: 4310430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor if (CXXOperatorCallExpr *OCE = 4311430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) { 4312430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor Expr *Callee = OCE->getCallee(); 4313430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) 4314430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor Callee = ICE->getSubExpr(); 4315430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor 4316430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee)) 4317430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(), 4318430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor DRE->getQualifierLoc().getSourceRange()); 4319430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor } 4320430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor break; 4321430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor 4322430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor default: 4323430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor break; 4324430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor } 4325430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor 4326430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor if (Pieces.empty()) { 4327430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor if (PieceIndex == 0) 4328430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor return clang_getCursorExtent(C); 4329430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor } else if (PieceIndex < Pieces.size()) { 4330430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor SourceRange R = Pieces[PieceIndex]; 4331430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor if (R.isValid()) 4332430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor return cxloc::translateSourceRange(getCursorContext(C), R); 4333430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor } 4334430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor 4335430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor return clang_getNullRange(); 4336430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor} 4337430d7a1a621a126a9ffe442ad8987ba02b46dae9Douglas Gregor 43380a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregorvoid clang_enableStackTraces(void) { 43390a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor llvm::sys::PrintStackTraceOnErrorSignal(); 43400a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor} 43410a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor 4342995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbarvoid clang_executeOnThread(void (*fn)(void*), void *user_data, 4343995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar unsigned stack_size) { 4344995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar llvm::llvm_execute_on_thread(fn, user_data, stack_size); 4345995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar} 4346995aaf9c8f0131bef0215a9a0bc794b83a49e0b7Daniel Dunbar 4347fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C" 4348fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 4349fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 4350fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor// Token-based Operations. 4351fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor//===----------------------------------------------------------------------===// 4352fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 4353fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor/* CXToken layout: 4354fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[0]: a CXTokenKind 4355fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[1]: starting token location 4356fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[2]: token length 4357fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[3]: reserved 4358f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek * ptr_data: for identifiers and keywords, an IdentifierInfo*. 4359fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * otherwise unused. 4360fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor */ 4361fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregorextern "C" { 4362fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 4363fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXTokenKind clang_getTokenKind(CXToken CXTok) { 4364fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return static_cast<CXTokenKind>(CXTok.int_data[0]); 4365fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 4366fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 4367fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) { 4368fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor switch (clang_getTokenKind(CXTok)) { 4369fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Identifier: 4370fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Keyword: 4371fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // We know we have an IdentifierInfo*, so use that. 4372ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data) 4373ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek ->getNameStart()); 4374fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 4375fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Literal: { 4376fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // We have stashed the starting pointer in the ptr_data field. Use it. 4377fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor const char *Text = static_cast<const char *>(CXTok.ptr_data); 43785f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner return createCXString(StringRef(Text, CXTok.int_data[2])); 4379fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } 4380f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4381fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Punctuation: 4382fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Comment: 4383fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor break; 4384fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } 4385f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4386f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek // We have to find the starting buffer pointer the hard way, by 4387fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // deconstructing the source location. 4388a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); 4389fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (!CXXUnit) 4390ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 4391f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4392fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]); 4393fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor std::pair<FileID, unsigned> LocInfo 4394a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc); 4395f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor bool Invalid = false; 43965f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Buffer 4397f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); 4398f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor if (Invalid) 4399aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor return createCXString(""); 4400fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 4401f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2])); 4402fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 4403f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4404fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) { 4405a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); 4406fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (!CXXUnit) 4407fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return clang_getNullLocation(); 4408f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4409fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return cxloc::translateSourceLocation(CXXUnit->getASTContext(), 4410fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceLocation::getFromRawEncoding(CXTok.int_data[1])); 4411fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 4412fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 4413fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) { 4414a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); 44155352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor if (!CXXUnit) 44165352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullRange(); 4417f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4418f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return cxloc::translateSourceRange(CXXUnit->getASTContext(), 4419fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceLocation::getFromRawEncoding(CXTok.int_data[1])); 4420fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 4421f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4422fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregorvoid clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, 4423fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXToken **Tokens, unsigned *NumTokens) { 4424fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (Tokens) 4425fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *Tokens = 0; 4426fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (NumTokens) 4427fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *NumTokens = 0; 4428f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4429a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); 4430fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (!CXXUnit || !Tokens || !NumTokens) 4431fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 4432f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4433bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor ASTUnit::ConcurrencyCheck Check(*CXXUnit); 4434bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor 443585b988fdfa6adab6d43e16efd19ad4f3f7e2b49bDaniel Dunbar SourceRange R = cxloc::translateCXSourceRange(Range); 4436fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (R.isInvalid()) 4437fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 4438f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4439fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceManager &SourceMgr = CXXUnit->getSourceManager(); 4440fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor std::pair<FileID, unsigned> BeginLocInfo 4441fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = SourceMgr.getDecomposedLoc(R.getBegin()); 4442fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor std::pair<FileID, unsigned> EndLocInfo 4443fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = SourceMgr.getDecomposedLoc(R.getEnd()); 4444f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4445fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Cannot tokenize across files. 4446fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (BeginLocInfo.first != EndLocInfo.first) 4447fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 4448f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4449f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek // Create a lexer 4450f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor bool Invalid = false; 44515f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Buffer 4452f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid); 445347a3fcd4afe122b23f9e7b6148f147bfa460cfe8Douglas Gregor if (Invalid) 445447a3fcd4afe122b23f9e7b6148f147bfa460cfe8Douglas Gregor return; 4455aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor 4456fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), 4457fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXXUnit->getASTContext().getLangOptions(), 4458f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end()); 4459fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Lex.SetCommentRetentionState(true); 4460f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4461fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Lex tokens until we hit the end of the range. 4462f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second; 44635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXToken, 32> CXTokens; 4464fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Token Tok; 4465096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall bool previousWasAt = false; 4466fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor do { 4467fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Lex the next token 4468fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Lex.LexFromRawLexer(Tok); 4469fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (Tok.is(tok::eof)) 4470fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor break; 4471f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4472fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Initialize the CXToken. 4473fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXToken CXTok; 4474f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4475fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // - Common fields 4476fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[1] = Tok.getLocation().getRawEncoding(); 4477fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[2] = Tok.getLength(); 4478fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[3] = 0; 4479f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4480fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // - Kind-specific fields 4481fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (Tok.isLiteral()) { 4482fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[0] = CXToken_Literal; 4483fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = (void *)Tok.getLiteralData(); 4484c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara } else if (Tok.is(tok::raw_identifier)) { 4485aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor // Lookup the identifier to determine whether we have a keyword. 4486fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor IdentifierInfo *II 4487c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok); 4488aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek 4489096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) { 4490aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek CXTok.int_data[0] = CXToken_Keyword; 4491aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek } 4492aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek else { 4493c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara CXTok.int_data[0] = Tok.is(tok::identifier) 4494c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara ? CXToken_Identifier 4495c4bf2b9afb7d47445a9dc6bc848657098a4e3851Abramo Bagnara : CXToken_Keyword; 4496aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek } 4497fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = II; 4498fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } else if (Tok.is(tok::comment)) { 4499fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[0] = CXToken_Comment; 4500fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = 0; 4501fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } else { 4502fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[0] = CXToken_Punctuation; 4503fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = 0; 4504fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } 4505fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTokens.push_back(CXTok); 4506096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall previousWasAt = Tok.is(tok::at); 4507fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } while (Lex.getBufferLocation() <= EffectiveBufferEnd); 4508f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4509fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (CXTokens.empty()) 4510fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 4511f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 4512fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size()); 4513fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); 4514fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *NumTokens = CXTokens.size(); 4515fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 45160045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor 45176db610934bedc6896393c1e1099525b35380acd6Ted Kremenekvoid clang_disposeTokens(CXTranslationUnit TU, 45186db610934bedc6896393c1e1099525b35380acd6Ted Kremenek CXToken *Tokens, unsigned NumTokens) { 45196db610934bedc6896393c1e1099525b35380acd6Ted Kremenek free(Tokens); 45206db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} 45216db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 45226db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} // end: extern "C" 45236db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 45246db610934bedc6896393c1e1099525b35380acd6Ted Kremenek//===----------------------------------------------------------------------===// 45256db610934bedc6896393c1e1099525b35380acd6Ted Kremenek// Token annotation APIs. 45266db610934bedc6896393c1e1099525b35380acd6Ted Kremenek//===----------------------------------------------------------------------===// 45276db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 45280045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregortypedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData; 4529fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekstatic enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, 4530fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXCursor parent, 4531fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXClientData client_data); 45326db610934bedc6896393c1e1099525b35380acd6Ted Kremeneknamespace { 45336db610934bedc6896393c1e1099525b35380acd6Ted Kremenekclass AnnotateTokensWorker { 45346db610934bedc6896393c1e1099525b35380acd6Ted Kremenek AnnotateTokensData &Annotated; 453511949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek CXToken *Tokens; 453611949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek CXCursor *Cursors; 453711949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek unsigned NumTokens; 4538fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek unsigned TokIdx; 45394419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor unsigned PreprocessingTokIdx; 4540fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CursorVisitor AnnotateVis; 4541fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceManager &SrcMgr; 4542f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor bool HasContextSensitiveKeywords; 4543f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor 4544fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek bool MoreTokens() const { return TokIdx < NumTokens; } 4545fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek unsigned NextToken() const { return TokIdx; } 4546fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek void AdvanceToken() { ++TokIdx; } 4547fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation GetTokenLoc(unsigned tokI) { 4548fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]); 4549fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 45505f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis bool isFunctionMacroToken(unsigned tokI) const { 4551a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis return Tokens[tokI].int_data[3] != 0; 4552a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } 45535f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const { 4554a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]); 4555a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } 4556a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4557a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange); 45585f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult, 45595f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis SourceRange); 4560fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 45616db610934bedc6896393c1e1099525b35380acd6Ted Kremenekpublic: 456211949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek AnnotateTokensWorker(AnnotateTokensData &annotated, 4563fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXToken *tokens, CXCursor *cursors, unsigned numTokens, 4564a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXTranslationUnit tu, SourceRange RegionOfInterest) 456511949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek : Annotated(annotated), Tokens(tokens), Cursors(cursors), 45664419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0), 4567a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek AnnotateVis(tu, 456808e0bc16b3312c27e87d33be7dcf3d4fe5bdd2e2Douglas Gregor AnnotateTokensVisitor, this, true, RegionOfInterest), 4569f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()), 4570f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor HasContextSensitiveKeywords(false) { } 457111949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek 4572fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); } 45736db610934bedc6896393c1e1099525b35380acd6Ted Kremenek enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent); 4574fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek void AnnotateTokens(CXCursor parent); 4575ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek void AnnotateTokens() { 4576a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek AnnotateTokens(clang_getTranslationUnitCursor(AnnotateVis.getTU())); 4577ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek } 4578f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor 4579f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor /// \brief Determine whether the annotator saw any cursors that have 4580f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor /// context-sensitive keywords. 4581f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor bool hasContextSensitiveKeywords() const { 4582f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor return HasContextSensitiveKeywords; 4583f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 45846db610934bedc6896393c1e1099525b35380acd6Ted Kremenek}; 45856db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} 45860045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor 4587fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekvoid AnnotateTokensWorker::AnnotateTokens(CXCursor parent) { 4588fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Walk the AST within the region of interest, annotating tokens 4589fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // along the way. 4590fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek VisitChildren(parent); 4591fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4592fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek for (unsigned I = 0 ; I < TokIdx ; ++I) { 459311949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); 45944419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor if (Pos != Annotated.end() && 45954419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor (clang_isInvalid(Cursors[I].kind) || 45964419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor Pos->second.kind != CXCursor_PreprocessingDirective)) 4597fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = Pos->second; 4598fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 4599fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4600fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Finish up annotating any tokens left. 4601fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (!MoreTokens()) 4602fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return; 460311949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek 4604fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const CXCursor &C = clang_getNullCursor(); 4605fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek for (unsigned I = TokIdx ; I < NumTokens ; ++I) { 4606fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); 4607fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second; 460811949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek } 460911949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek} 461011949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek 4611a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// \brief It annotates and advances tokens with a cursor until the comparison 4612a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis//// between the cursor location and the source range is the same as 4613a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// \arg compResult. 4614a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// 4615a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// Pass RangeBefore to annotate tokens with a cursor until a range is reached. 4616a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// Pass RangeOverlap to annotate tokens inside a range. 4617a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidisvoid AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC, 4618a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis RangeComparisonResult compResult, 4619a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis SourceRange range) { 4620a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis while (MoreTokens()) { 4621a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis const unsigned I = NextToken(); 46225f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis if (isFunctionMacroToken(I)) 46235f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range); 4624a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4625a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis SourceLocation TokLoc = GetTokenLoc(I); 4626a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (LocationCompare(SrcMgr, TokLoc, range) == compResult) { 4627a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis Cursors[I] = updateC; 4628a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis AdvanceToken(); 4629a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis continue; 4630a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } 4631a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis break; 4632a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } 4633a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis} 4634a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4635a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// \brief Special annotation handling for macro argument tokens. 46365f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidisvoid AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens( 46375f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis CXCursor updateC, 4638a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis RangeComparisonResult compResult, 4639a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis SourceRange range) { 46405f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis assert(MoreTokens()); 46415f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis assert(isFunctionMacroToken(NextToken()) && 4642a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis "Should be called only for macro arg tokens"); 4643a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4644a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // This works differently than annotateAndAdvanceTokens; because expanded 4645a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // macro arguments can have arbitrary translation-unit source order, we do not 4646a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // advance the token index one by one until a token fails the range test. 4647a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // We only advance once past all of the macro arg tokens if all of them 4648a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // pass the range test. If one of them fails we keep the token index pointing 4649a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // at the start of the macro arg tokens so that the failing token will be 4650a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // annotated by a subsequent annotation try. 4651a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4652a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis bool atLeastOneCompFail = false; 4653a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4654a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis unsigned I = NextToken(); 46555f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis for (; I < NumTokens && isFunctionMacroToken(I); ++I) { 46565f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis SourceLocation TokLoc = getFunctionMacroTokenLoc(I); 4657a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (TokLoc.isFileID()) 4658a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis continue; // not macro arg token, it's parens or comma. 4659a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (LocationCompare(SrcMgr, TokLoc, range) == compResult) { 4660a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (clang_isInvalid(clang_getCursorKind(Cursors[I]))) 4661a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis Cursors[I] = updateC; 4662a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } else 4663a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis atLeastOneCompFail = true; 4664a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } 4665a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4666a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (!atLeastOneCompFail) 4667a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis TokIdx = I; // All of the tokens were handled, advance beyond all of them. 4668a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis} 4669a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 46706db610934bedc6896393c1e1099525b35380acd6Ted Kremenekenum CXChildVisitResult 46714419b675577d7c281a659fab1fec10e1bfbe04c5Douglas GregorAnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { 4672fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXSourceLocation Loc = clang_getCursorLocation(cursor); 46734419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor SourceRange cursorRange = getRawCursorExtent(cursor); 467481d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor if (cursorRange.isInvalid()) 467581d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor return CXChildVisit_Recurse; 4676f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor 4677f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (!HasContextSensitiveKeywords) { 4678f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor // Objective-C properties can have context-sensitive keywords. 4679f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (cursor.kind == CXCursor_ObjCPropertyDecl) { 4680f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (ObjCPropertyDecl *Property 4681f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor))) 4682f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0; 4683f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 4684f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor // Objective-C methods can have context-sensitive keywords. 4685f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl || 4686f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor cursor.kind == CXCursor_ObjCClassMethodDecl) { 4687f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (ObjCMethodDecl *Method 4688f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) { 4689f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (Method->getObjCDeclQualifier()) 4690f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor HasContextSensitiveKeywords = true; 4691f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor else { 4692f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor for (ObjCMethodDecl::param_iterator P = Method->param_begin(), 4693f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor PEnd = Method->param_end(); 4694f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor P != PEnd; ++P) { 4695f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if ((*P)->getObjCDeclQualifier()) { 4696f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor HasContextSensitiveKeywords = true; 4697f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor break; 4698f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 4699f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 4700f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 4701f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 4702f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 4703f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor // C++ methods can have context-sensitive keywords. 4704f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor else if (cursor.kind == CXCursor_CXXMethod) { 4705f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (CXXMethodDecl *Method 4706f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) { 4707f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>()) 4708f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor HasContextSensitiveKeywords = true; 4709f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 4710f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 4711f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor // C++ classes can have context-sensitive keywords. 4712f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor else if (cursor.kind == CXCursor_StructDecl || 4713f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor cursor.kind == CXCursor_ClassDecl || 4714f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor cursor.kind == CXCursor_ClassTemplate || 4715f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor cursor.kind == CXCursor_ClassTemplatePartialSpecialization) { 4716f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (Decl *D = getCursorDecl(cursor)) 4717f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (D->hasAttr<FinalAttr>()) 4718f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor HasContextSensitiveKeywords = true; 4719f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 4720f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 4721f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor 47224419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor if (clang_isPreprocessing(cursor.kind)) { 4723cea731a9cb7de3f473d60e5ea544e25621cebd76Chandler Carruth // For macro expansions, just note where the beginning of the macro 4724cea731a9cb7de3f473d60e5ea544e25621cebd76Chandler Carruth // expansion occurs. 47259b2a0ac970a077bdc0bf08c6c682f80ad733c892Chandler Carruth if (cursor.kind == CXCursor_MacroExpansion) { 47264419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor Annotated[Loc.int_data] = cursor; 47274419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor return CXChildVisit_Recurse; 47284419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 47294419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 47304419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Items in the preprocessing record are kept separate from items in 47314419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // declarations, so we keep a separate token index. 47324419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor unsigned SavedTokIdx = TokIdx; 47334419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor TokIdx = PreprocessingTokIdx; 47344419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 47354419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Skip tokens up until we catch up to the beginning of the preprocessing 47364419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // entry. 47374419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor while (MoreTokens()) { 47384419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor const unsigned I = NextToken(); 47394419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor SourceLocation TokLoc = GetTokenLoc(I); 47404419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 47414419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeBefore: 47424419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor AdvanceToken(); 47434419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor continue; 47444419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeAfter: 47454419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeOverlap: 47464419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 47474419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 47484419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 47494419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 47504419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 47514419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Look at all of the tokens within this range. 47524419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor while (MoreTokens()) { 47534419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor const unsigned I = NextToken(); 47544419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor SourceLocation TokLoc = GetTokenLoc(I); 47554419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 47564419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeBefore: 47574419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor assert(0 && "Infeasible"); 47584419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeAfter: 47594419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 47604419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeOverlap: 47614419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor Cursors[I] = cursor; 47624419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor AdvanceToken(); 47634419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor continue; 47644419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 47654419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 47664419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 47674419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 47684419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Save the preprocessing token index; restore the non-preprocessing 47694419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // token index. 47704419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor PreprocessingTokIdx = TokIdx; 47714419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor TokIdx = SavedTokIdx; 47720045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor return CXChildVisit_Recurse; 47730045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor } 4774fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4775fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (cursorRange.isInvalid()) 4776fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return CXChildVisit_Continue; 4777a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek 4778fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data); 4779fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4780a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek // Adjust the annotated range based specific declarations. 4781a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek const enum CXCursorKind cursorK = clang_getCursorKind(cursor); 4782a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) { 478323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek Decl *D = cxcursor::getCursorDecl(cursor); 47842494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor 47852494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor SourceLocation StartLoc; 478623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { 47872494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) 47882494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor StartLoc = TI->getTypeLoc().getSourceRange().getBegin(); 47892494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) { 47902494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo()) 47912494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor StartLoc = TI->getTypeLoc().getSourceRange().getBegin(); 4792a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek } 47932494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor 47942494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor if (StartLoc.isValid() && L.isValid() && 47952494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor SrcMgr.isBeforeInTranslationUnit(StartLoc, L)) 47962494dd024b392b8def58bf067cc94b51c214cf77Douglas Gregor cursorRange.setBegin(StartLoc); 4797a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek } 479881d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor 47993f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // If the location of the cursor occurs within a macro instantiation, record 48003f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // the spelling location of the cursor in our annotation map. We can then 48013f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // paper over the token labelings during a post-processing step to try and 48023f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // get cursor mappings for tokens that are the *arguments* of a macro 48033f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // instantiation. 48043f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek if (L.isMacroID()) { 48053f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding(); 48063f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // Only invalidate the old annotation if it isn't part of a preprocessing 48073f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // directive. Here we assume that the default construction of CXCursor 48083f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // results in CXCursor.kind being an initialized value (i.e., 0). If 48093f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // this isn't the case, we can fix by doing lookup + insertion. 48104419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 48113f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek CXCursor &oldC = Annotated[rawEncoding]; 48123f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek if (!clang_isPreprocessing(oldC.kind)) 48133f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek oldC = cursor; 48143f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek } 48153f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek 4816fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const enum CXCursorKind K = clang_getCursorKind(parent); 4817fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const CXCursor updateC = 4818d8b0a84d586bc0a08695968acf2f169c9d01da69Ted Kremenek (clang_isInvalid(K) || K == CXCursor_TranslationUnit) 4819d8b0a84d586bc0a08695968acf2f169c9d01da69Ted Kremenek ? clang_getNullCursor() : parent; 4820fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4821a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange); 4822fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 48235517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis // Avoid having the cursor of an expression "overwrite" the annotation of the 48245517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis // variable declaration that it belongs to. 48255517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis // This can happen for C++ constructor expressions whose range generally 48265517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis // include the variable declaration, e.g.: 48275517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor. 48285517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis if (clang_isExpression(cursorK)) { 48295517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis Expr *E = getCursorExpr(cursor); 48308ccac3de1335f1cfd7cea56ba1cefcf0b724ce3fArgyrios Kyrtzidis if (Decl *D = getCursorParentDecl(cursor)) { 48315517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis const unsigned I = NextToken(); 48325517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis if (E->getLocStart().isValid() && D->getLocation().isValid() && 48335517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis E->getLocStart() == D->getLocation() && 48345517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis E->getLocStart() == GetTokenLoc(I)) { 48355517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis Cursors[I] = updateC; 48365517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis AdvanceToken(); 48375517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis } 48385517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis } 48395517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis } 48405517b89953e3c9276f161ce29831de388bb2573dArgyrios Kyrtzidis 4841fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Visit children to get their cursor information. 4842fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned BeforeChildren = NextToken(); 4843fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek VisitChildren(cursor); 4844fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned AfterChildren = NextToken(); 4845fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4846a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // Scan the tokens that are at the end of the cursor, but are not captured 4847a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // but the child cursors. 4848a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange); 48496db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 4850fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Scan the tokens that are at the beginning of the cursor, but are not 4851fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // capture by the child cursors. 4852fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek for (unsigned I = BeforeChildren; I != AfterChildren; ++I) { 4853fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (!clang_isInvalid(clang_getCursorKind(Cursors[I]))) 4854fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek break; 48554419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 4856fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = cursor; 4857fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 4858fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 4859fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return CXChildVisit_Continue; 48600045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor} 48610045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor 48626db610934bedc6896393c1e1099525b35380acd6Ted Kremenekstatic enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, 48636db610934bedc6896393c1e1099525b35380acd6Ted Kremenek CXCursor parent, 48646db610934bedc6896393c1e1099525b35380acd6Ted Kremenek CXClientData client_data) { 48656db610934bedc6896393c1e1099525b35380acd6Ted Kremenek return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent); 48666db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} 48676db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 48686628a614c504263ae539462f049d523dd07ac1baTed Kremeneknamespace { 4869a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4870a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// \brief Uses the macro expansions in the preprocessing record to find 4871a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// and mark tokens that are macro arguments. This info is used by the 4872a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis/// AnnotateTokensWorker. 4873a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidisclass MarkMacroArgTokensVisitor { 4874a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis SourceManager &SM; 4875a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis CXToken *Tokens; 4876a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis unsigned NumTokens; 4877a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis unsigned CurIdx; 4878a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4879a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidispublic: 4880a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis MarkMacroArgTokensVisitor(SourceManager &SM, 4881a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis CXToken *tokens, unsigned numTokens) 4882a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { } 4883a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4884a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis CXChildVisitResult visit(CXCursor cursor, CXCursor parent) { 4885a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (cursor.kind != CXCursor_MacroExpansion) 4886a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis return CXChildVisit_Continue; 4887a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4888a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis SourceRange macroRange = getCursorMacroExpansion(cursor)->getSourceRange(); 4889a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (macroRange.getBegin() == macroRange.getEnd()) 4890a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis return CXChildVisit_Continue; // it's not a function macro. 4891a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4892a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis for (; CurIdx < NumTokens; ++CurIdx) { 4893a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx), 4894a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis macroRange.getBegin())) 4895a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis break; 4896a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } 4897a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4898a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (CurIdx == NumTokens) 4899a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis return CXChildVisit_Break; 4900a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4901a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis for (; CurIdx < NumTokens; ++CurIdx) { 4902a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis SourceLocation tokLoc = getTokenLoc(CurIdx); 4903a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd())) 4904a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis break; 4905a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 49065f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc)); 4907a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } 4908a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4909a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (CurIdx == NumTokens) 4910a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis return CXChildVisit_Break; 4911a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4912a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis return CXChildVisit_Continue; 4913a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } 4914a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4915a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidisprivate: 4916a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis SourceLocation getTokenLoc(unsigned tokI) { 4917a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]); 4918a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } 4919a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 49205f616b726fdf5db3cbc2fd8d92c42cc624dd4550Argyrios Kyrtzidis void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) { 4921a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // The third field is reserved and currently not used. Use it here 4922a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // to mark macro arg expanded tokens with their expanded locations. 4923a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis Tokens[tokI].int_data[3] = loc.getRawEncoding(); 4924a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } 4925a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis}; 4926a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4927a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis} // end anonymous namespace 4928a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4929a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidisstatic CXChildVisitResult 4930a676379b26edc959193f9f919ba9c6d296a57824Argyrios KyrtzidisMarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent, 4931a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis CXClientData client_data) { 4932a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor, 4933a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis parent); 4934a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis} 4935a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 4936a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidisnamespace { 49376628a614c504263ae539462f049d523dd07ac1baTed Kremenek struct clang_annotateTokens_Data { 49386628a614c504263ae539462f049d523dd07ac1baTed Kremenek CXTranslationUnit TU; 49396628a614c504263ae539462f049d523dd07ac1baTed Kremenek ASTUnit *CXXUnit; 49406628a614c504263ae539462f049d523dd07ac1baTed Kremenek CXToken *Tokens; 49416628a614c504263ae539462f049d523dd07ac1baTed Kremenek unsigned NumTokens; 49426628a614c504263ae539462f049d523dd07ac1baTed Kremenek CXCursor *Cursors; 49436628a614c504263ae539462f049d523dd07ac1baTed Kremenek }; 4944ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek} 4945ab97961fb4424d0822076eb0fd4f8faee9992763Ted Kremenek 49466628a614c504263ae539462f049d523dd07ac1baTed Kremenek// This gets run a separate thread to avoid stack blowout. 49476628a614c504263ae539462f049d523dd07ac1baTed Kremenekstatic void clang_annotateTokensImpl(void *UserData) { 49486628a614c504263ae539462f049d523dd07ac1baTed Kremenek CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU; 49496628a614c504263ae539462f049d523dd07ac1baTed Kremenek ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit; 49506628a614c504263ae539462f049d523dd07ac1baTed Kremenek CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens; 49516628a614c504263ae539462f049d523dd07ac1baTed Kremenek const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens; 49526628a614c504263ae539462f049d523dd07ac1baTed Kremenek CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors; 4953fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 49540396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // Determine the region of interest, which contains all of the tokens. 49550045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor SourceRange RegionOfInterest; 49566628a614c504263ae539462f049d523dd07ac1baTed Kremenek RegionOfInterest.setBegin( 49576628a614c504263ae539462f049d523dd07ac1baTed Kremenek cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0]))); 49586628a614c504263ae539462f049d523dd07ac1baTed Kremenek RegionOfInterest.setEnd( 49596628a614c504263ae539462f049d523dd07ac1baTed Kremenek cxloc::translateSourceLocation(clang_getTokenLocation(TU, 49606628a614c504263ae539462f049d523dd07ac1baTed Kremenek Tokens[NumTokens-1]))); 4961fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 49620396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // A mapping from the source locations found when re-lexing or traversing the 49630396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // region of interest to the corresponding cursors. 49640045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor AnnotateTokensData Annotated; 49656628a614c504263ae539462f049d523dd07ac1baTed Kremenek 4966fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Relex the tokens within the source range to look for preprocessing 49670396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // directives. 49689f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor SourceManager &SourceMgr = CXXUnit->getSourceManager(); 49699f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor std::pair<FileID, unsigned> BeginLocInfo 49709f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin()); 49719f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor std::pair<FileID, unsigned> EndLocInfo 49729f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd()); 49736628a614c504263ae539462f049d523dd07ac1baTed Kremenek 49745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Buffer; 49750396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor bool Invalid = false; 49760396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (BeginLocInfo.first == EndLocInfo.first && 49770396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) && 49780396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor !Invalid) { 49799f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), 49809f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor CXXUnit->getASTContext().getLangOptions(), 4981fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Buffer.begin(), Buffer.data() + BeginLocInfo.second, 49824ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor Buffer.end()); 49839f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Lex.SetCommentRetentionState(true); 49846628a614c504263ae539462f049d523dd07ac1baTed Kremenek 4985fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Lex tokens in raw mode until we hit the end of the range, to avoid 49869f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // entering #includes or expanding macros. 49874807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor while (true) { 49889f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Token Tok; 49899f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Lex.LexFromRawLexer(Tok); 49906628a614c504263ae539462f049d523dd07ac1baTed Kremenek 49919f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor reprocess: 49929f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) { 49939f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // We have found a preprocessing directive. Gobble it up so that we 49949e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar // don't see it while preprocessing these tokens later, but keep track 49959e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar // of all of the token locations inside this preprocessing directive so 49969e1ebdd97ba0c593900cb7f103324c43471e96eeDaniel Dunbar // that we can annotate them appropriately. 49979f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // 49989f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // FIXME: Some simple tests here could identify macro definitions and 49999f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // #undefs, to provide specific cursor kinds for those. 50005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<SourceLocation, 32> Locations; 50019f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor do { 50029f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Locations.push_back(Tok.getLocation()); 5003fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Lex.LexFromRawLexer(Tok); 50049f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof)); 50056628a614c504263ae539462f049d523dd07ac1baTed Kremenek 50069f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor using namespace cxcursor; 50079f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor CXCursor Cursor 50086628a614c504263ae539462f049d523dd07ac1baTed Kremenek = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(), 50096628a614c504263ae539462f049d523dd07ac1baTed Kremenek Locations.back()), 5010a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek TU); 50119f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor for (unsigned I = 0, N = Locations.size(); I != N; ++I) { 50129f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Annotated[Locations[I].getRawEncoding()] = Cursor; 50139f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 50146628a614c504263ae539462f049d523dd07ac1baTed Kremenek 50159f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor if (Tok.isAtStartOfLine()) 50169f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor goto reprocess; 50176628a614c504263ae539462f049d523dd07ac1baTed Kremenek 50189f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor continue; 50199f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 50206628a614c504263ae539462f049d523dd07ac1baTed Kremenek 50214807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor if (Tok.is(tok::eof)) 50229f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor break; 50239f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 50244ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor } 50256628a614c504263ae539462f049d523dd07ac1baTed Kremenek 5026a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis if (CXXUnit->getPreprocessor().getPreprocessingRecord()) { 5027a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis // Search and mark tokens that are macro argument expansions. 5028a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), 5029a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis Tokens, NumTokens); 5030a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis CursorVisitor MacroArgMarker(TU, 5031a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis MarkMacroArgTokensVisitorDelegate, &Visitor, 503208e0bc16b3312c27e87d33be7dcf3d4fe5bdd2e2Douglas Gregor true, RegionOfInterest); 5033a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis MacroArgMarker.visitPreprocessedEntitiesInRegion(); 5034a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis } 5035a676379b26edc959193f9f919ba9c6d296a57824Argyrios Kyrtzidis 50360396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // Annotate all of the source locations in the region of interest that map to 5037fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // a specific cursor. 5038fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens, 5039a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek TU, RegionOfInterest); 50406628a614c504263ae539462f049d523dd07ac1baTed Kremenek 50416c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek // FIXME: We use a ridiculous stack size here because the data-recursion 50426c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek // algorithm uses a large stack frame than the non-data recursive version, 50436c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek // and AnnotationTokensWorker currently transforms the data-recursion 50446c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek // algorithm back into a traditional recursion by explicitly calling 50456c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek // VisitChildren(). We will need to remove this explicit recursive call. 50466628a614c504263ae539462f049d523dd07ac1baTed Kremenek W.AnnotateTokens(); 50476628a614c504263ae539462f049d523dd07ac1baTed Kremenek 5048f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor // If we ran into any entities that involve context-sensitive keywords, 5049f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor // take another pass through the tokens to mark them as such. 5050f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (W.hasContextSensitiveKeywords()) { 5051f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor for (unsigned I = 0; I != NumTokens; ++I) { 5052f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier) 5053f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor continue; 5054f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor 5055f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) { 5056f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data); 5057f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (ObjCPropertyDecl *Property 50586628a614c504263ae539462f049d523dd07ac1baTed Kremenek = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) { 5059f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (Property->getPropertyAttributesAsWritten() != 0 && 5060f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor llvm::StringSwitch<bool>(II->getName()) 50616628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("readonly", true) 50626628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("assign", true) 5063f85e193739c953358c865005855253af4f68a497John McCall .Case("unsafe_unretained", true) 50646628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("readwrite", true) 50656628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("retain", true) 50666628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("copy", true) 50676628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("nonatomic", true) 50686628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("atomic", true) 50696628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("getter", true) 50706628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("setter", true) 5071f85e193739c953358c865005855253af4f68a497John McCall .Case("strong", true) 5072f85e193739c953358c865005855253af4f68a497John McCall .Case("weak", true) 50736628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Default(false)) 5074f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor Tokens[I].int_data[0] = CXToken_Keyword; 5075f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 5076f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor continue; 5077f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 5078f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor 5079f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl || 5080f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor Cursors[I].kind == CXCursor_ObjCClassMethodDecl) { 5081f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data); 5082f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor if (llvm::StringSwitch<bool>(II->getName()) 50836628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("in", true) 50846628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("out", true) 50856628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("inout", true) 50866628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("oneway", true) 50876628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("bycopy", true) 50886628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Case("byref", true) 50896628a614c504263ae539462f049d523dd07ac1baTed Kremenek .Default(false)) 5090f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor Tokens[I].int_data[0] = CXToken_Keyword; 5091f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor continue; 5092f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 50936639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis 50946639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis if (Cursors[I].kind == CXCursor_CXXFinalAttr || 50956639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis Cursors[I].kind == CXCursor_CXXOverrideAttr) { 50966639e9255489ad8e10278d5658fdd4b3c0e1e4cdArgyrios Kyrtzidis Tokens[I].int_data[0] = CXToken_Keyword; 50976628a614c504263ae539462f049d523dd07ac1baTed Kremenek continue; 5098f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 5099f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 5100f52516038ab5d0b1b90a6dd32f46b7d6dabd04c8Douglas Gregor } 5101fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 51026628a614c504263ae539462f049d523dd07ac1baTed Kremenek 51036628a614c504263ae539462f049d523dd07ac1baTed Kremenekextern "C" { 51046628a614c504263ae539462f049d523dd07ac1baTed Kremenek 51056628a614c504263ae539462f049d523dd07ac1baTed Kremenekvoid clang_annotateTokens(CXTranslationUnit TU, 51066628a614c504263ae539462f049d523dd07ac1baTed Kremenek CXToken *Tokens, unsigned NumTokens, 51076628a614c504263ae539462f049d523dd07ac1baTed Kremenek CXCursor *Cursors) { 51086628a614c504263ae539462f049d523dd07ac1baTed Kremenek 51096628a614c504263ae539462f049d523dd07ac1baTed Kremenek if (NumTokens == 0 || !Tokens || !Cursors) 51106628a614c504263ae539462f049d523dd07ac1baTed Kremenek return; 51116628a614c504263ae539462f049d523dd07ac1baTed Kremenek 51126628a614c504263ae539462f049d523dd07ac1baTed Kremenek // Any token we don't specifically annotate will have a NULL cursor. 51136628a614c504263ae539462f049d523dd07ac1baTed Kremenek CXCursor C = clang_getNullCursor(); 51146628a614c504263ae539462f049d523dd07ac1baTed Kremenek for (unsigned I = 0; I != NumTokens; ++I) 51156628a614c504263ae539462f049d523dd07ac1baTed Kremenek Cursors[I] = C; 51166628a614c504263ae539462f049d523dd07ac1baTed Kremenek 51176628a614c504263ae539462f049d523dd07ac1baTed Kremenek ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); 51186628a614c504263ae539462f049d523dd07ac1baTed Kremenek if (!CXXUnit) 51196628a614c504263ae539462f049d523dd07ac1baTed Kremenek return; 51206628a614c504263ae539462f049d523dd07ac1baTed Kremenek 51216628a614c504263ae539462f049d523dd07ac1baTed Kremenek ASTUnit::ConcurrencyCheck Check(*CXXUnit); 51226628a614c504263ae539462f049d523dd07ac1baTed Kremenek 51236628a614c504263ae539462f049d523dd07ac1baTed Kremenek clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors }; 51246628a614c504263ae539462f049d523dd07ac1baTed Kremenek llvm::CrashRecoveryContext CRC; 51256628a614c504263ae539462f049d523dd07ac1baTed Kremenek if (!RunSafely(CRC, clang_annotateTokensImpl, &data, 51266628a614c504263ae539462f049d523dd07ac1baTed Kremenek GetSafetyThreadStackSize() * 2)) { 51276628a614c504263ae539462f049d523dd07ac1baTed Kremenek fprintf(stderr, "libclang: crash detected while annotating tokens\n"); 51286628a614c504263ae539462f049d523dd07ac1baTed Kremenek } 51296628a614c504263ae539462f049d523dd07ac1baTed Kremenek} 51306628a614c504263ae539462f049d523dd07ac1baTed Kremenek 5131fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} // end: extern "C" 5132fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 5133fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor//===----------------------------------------------------------------------===// 513416b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek// Operations for querying linkage of a cursor. 513516b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek//===----------------------------------------------------------------------===// 513616b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek 513716b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenekextern "C" { 513816b4259aecaa22b642d35d36fd89965ed700c1e0Ted KremenekCXLinkageKind clang_getCursorLinkage(CXCursor cursor) { 51390396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (!clang_isDeclaration(cursor.kind)) 51400396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor return CXLinkage_Invalid; 51410396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor 514216b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek Decl *D = cxcursor::getCursorDecl(cursor); 514316b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D)) 514416b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek switch (ND->getLinkage()) { 514516b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case NoLinkage: return CXLinkage_NoLinkage; 514616b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case InternalLinkage: return CXLinkage_Internal; 514716b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case UniqueExternalLinkage: return CXLinkage_UniqueExternal; 514816b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case ExternalLinkage: return CXLinkage_External; 514916b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek }; 515016b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek 515116b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek return CXLinkage_Invalid; 515216b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek} 515316b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek} // end: extern "C" 515416b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek 515516b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek//===----------------------------------------------------------------------===// 515645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek// Operations for querying language of a cursor. 515745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek//===----------------------------------------------------------------------===// 515845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 515945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenekstatic CXLanguageKind getDeclLanguage(const Decl *D) { 516045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek switch (D->getKind()) { 516145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek default: 516245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek break; 516345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ImplicitParam: 516445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCAtDefsField: 516545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCCategory: 516645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCCategoryImpl: 516745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCClass: 516845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCCompatibleAlias: 516945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCForwardProtocol: 517045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCImplementation: 517145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCInterface: 517245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCIvar: 517345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCMethod: 517445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCProperty: 517545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCPropertyImpl: 517645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCProtocol: 517745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_ObjC; 517845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXConstructor: 517945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXConversion: 518045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXDestructor: 518145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXMethod: 518245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXRecord: 518345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ClassTemplate: 518445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ClassTemplatePartialSpecialization: 518545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ClassTemplateSpecialization: 518645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::Friend: 518745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::FriendTemplate: 518845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::FunctionTemplate: 518945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::LinkageSpec: 519045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::Namespace: 519145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::NamespaceAlias: 519245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::NonTypeTemplateParm: 519345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::StaticAssert: 519445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::TemplateTemplateParm: 519545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::TemplateTypeParm: 519645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UnresolvedUsingTypename: 519745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UnresolvedUsingValue: 519845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::Using: 519945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UsingDirective: 520045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UsingShadow: 520145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_CPlusPlus; 520245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek } 520345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 520445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_C; 520545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek} 520645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 520745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenekextern "C" { 520858ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 520958ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregorenum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) { 521058ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor if (clang_isDeclaration(cursor.kind)) 521158ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor if (Decl *D = cxcursor::getCursorDecl(cursor)) { 52120a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()) 521358ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor return CXAvailability_Available; 521458ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 52150a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor switch (D->getAvailability()) { 52160a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor case AR_Available: 52170a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor case AR_NotYetIntroduced: 52180a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return CXAvailability_Available; 52190a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 52200a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor case AR_Deprecated: 522158ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor return CXAvailability_Deprecated; 52220a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 52230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor case AR_Unavailable: 52240a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor return CXAvailability_NotAvailable; 52250a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor } 522658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor } 52270a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor 522858ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor return CXAvailability_Available; 522958ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor} 523058ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 523145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted KremenekCXLanguageKind clang_getCursorLanguage(CXCursor cursor) { 523245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek if (clang_isDeclaration(cursor.kind)) 523345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return getDeclLanguage(cxcursor::getCursorDecl(cursor)); 523445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 523545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_Invalid; 523645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek} 52373910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor 52383910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor /// \brief If the given cursor is the "templated" declaration 52393910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor /// descibing a class or function template, return the class or 52403910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor /// function template. 52413910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregorstatic Decl *maybeGetTemplateCursor(Decl *D) { 52423910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor if (!D) 52433910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor return 0; 52443910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor 52453910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 52463910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate()) 52473910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor return FunTmpl; 52483910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor 52493910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) 52503910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate()) 52513910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor return ClassTmpl; 52523910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor 52533910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor return D; 52543910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor} 52553910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor 52562be5bc9ad3981347a000742f81b91ab3080f1214Douglas GregorCXCursor clang_getCursorSemanticParent(CXCursor cursor) { 52572be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (clang_isDeclaration(cursor.kind)) { 52582be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (Decl *D = getCursorDecl(cursor)) { 52592be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor DeclContext *DC = D->getDeclContext(); 52603910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor if (!DC) 52613910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor return clang_getNullCursor(); 52623910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor 52633910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)), 52643910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor getCursorTU(cursor)); 52652be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 52662be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 52672be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 52682be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) { 52692be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (Decl *D = getCursorDecl(cursor)) 5270a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return MakeCXCursor(D, getCursorTU(cursor)); 52712be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 52722be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 52732be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return clang_getNullCursor(); 52742be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor} 52752be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 52762be5bc9ad3981347a000742f81b91ab3080f1214Douglas GregorCXCursor clang_getCursorLexicalParent(CXCursor cursor) { 52772be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (clang_isDeclaration(cursor.kind)) { 52782be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (Decl *D = getCursorDecl(cursor)) { 52792be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor DeclContext *DC = D->getLexicalDeclContext(); 52803910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor if (!DC) 52813910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor return clang_getNullCursor(); 52823910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor 52833910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)), 52843910cfd17fcd99ac80158e625fc63e4784d26435Douglas Gregor getCursorTU(cursor)); 52852be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 52862be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 52872be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 52882be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor // FIXME: Note that we can't easily compute the lexical context of a 52892be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor // statement or expression, so we return nothing. 52902be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return clang_getNullCursor(); 52912be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor} 52922be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 52939f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorstatic void CollectOverriddenMethods(DeclContext *Ctx, 52949f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor ObjCMethodDecl *Method, 52955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<ObjCMethodDecl *> &Methods) { 52969f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!Ctx) 52979f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 52989f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 52999f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // If we have a class or category implementation, jump straight to the 53009f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // interface. 53019f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx)) 53029f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods); 53039f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53049f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx); 53059f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!Container) 53069f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 53079f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53089f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // Check whether we have a matching method at this level. 53099f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(), 53109f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Method->isInstanceMethod())) 53119f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (Method != Overridden) { 53129f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // We found an override at this level; there is no need to look 53139f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // into other protocols or categories. 53149f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Methods.push_back(Overridden); 53159f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 53169f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 53179f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53189f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { 53199f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(), 53209f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor PEnd = Protocol->protocol_end(); 53219f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor P != PEnd; ++P) 53229f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(*P, Method, Methods); 53239f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 53249f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53259f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) { 53269f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(), 53279f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor PEnd = Category->protocol_end(); 53289f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor P != PEnd; ++P) 53299f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(*P, Method, Methods); 53309f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 53319f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53329f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) { 53339f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(), 53349f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor PEnd = Interface->protocol_end(); 53359f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor P != PEnd; ++P) 53369f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(*P, Method, Methods); 53379f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53389f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCCategoryDecl *Category = Interface->getCategoryList(); 53399f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Category; Category = Category->getNextClassCategory()) 53409f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(Category, Method, Methods); 53419f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53429f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // We only look into the superclass if we haven't found anything yet. 53439f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (Methods.empty()) 53449f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) 53459f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return CollectOverriddenMethods(Super, Method, Methods); 53469f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 53479f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor} 53489f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53499f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorvoid clang_getOverriddenCursors(CXCursor cursor, 53509f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CXCursor **overridden, 53519f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor unsigned *num_overridden) { 53529f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (overridden) 53539f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *overridden = 0; 53549f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (num_overridden) 53559f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *num_overridden = 0; 53569f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!overridden || !num_overridden) 53579f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 53589f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53599f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!clang_isDeclaration(cursor.kind)) 53609f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 53619f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53629f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Decl *D = getCursorDecl(cursor); 53639f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!D) 53649f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 53659f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53669f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // Handle C++ member functions. 5367a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXTranslationUnit TU = getCursorTU(cursor); 53689f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) { 53699f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *num_overridden = CXXMethod->size_overridden_methods(); 53709f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!*num_overridden) 53719f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 53729f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53739f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *overridden = new CXCursor [*num_overridden]; 53749f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor unsigned I = 0; 53759f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (CXXMethodDecl::method_iterator 53769f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor M = CXXMethod->begin_overridden_methods(), 53779f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor MEnd = CXXMethod->end_overridden_methods(); 53789f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor M != MEnd; (void)++M, ++I) 5379a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU); 53809f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 53819f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 53829f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53839f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D); 53849f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!Method) 53859f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 53869f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53879f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // Handle Objective-C methods. 53885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<ObjCMethodDecl *, 4> Methods; 53899f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(Method->getDeclContext(), Method, Methods); 53909f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53919f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (Methods.empty()) 53929f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 53939f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 53949f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *num_overridden = Methods.size(); 53959f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *overridden = new CXCursor [Methods.size()]; 53969f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (unsigned I = 0, N = Methods.size(); I != N; ++I) 5397a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek (*overridden)[I] = MakeCXCursor(Methods[I], TU); 53989f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor} 53999f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 54009f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorvoid clang_disposeOverriddenCursors(CXCursor *overridden) { 54019f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor delete [] overridden; 54029f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor} 54039f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 5404ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas GregorCXFile clang_getIncludedFile(CXCursor cursor) { 5405ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (cursor.kind != CXCursor_InclusionDirective) 5406ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return 0; 5407ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 5408ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor InclusionDirective *ID = getCursorInclusionDirective(cursor); 5409ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return (void *)ID->getFile(); 5410ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor} 5411ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 541245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek} // end: extern "C" 541345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 54149ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek 54159ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek//===----------------------------------------------------------------------===// 54169ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek// C++ AST instrospection. 54179ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek//===----------------------------------------------------------------------===// 54189ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek 54199ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenekextern "C" { 54209ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenekunsigned clang_CXXMethod_isStatic(CXCursor C) { 54219ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek if (!clang_isDeclaration(C.kind)) 54229ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek return 0; 542349f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor 542449f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor CXXMethodDecl *Method = 0; 542549f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor Decl *D = cxcursor::getCursorDecl(C); 542649f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D)) 542749f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); 542849f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor else 542949f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor Method = dyn_cast_or_null<CXXMethodDecl>(D); 543049f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor return (Method && Method->isStatic()) ? 1 : 0; 543140b492a43bac3ed0c465772aa6921d011cfc273fTed Kremenek} 5432b12903e1a4b8d1b611b8c7e4f910665d628e68cdTed Kremenek 5433211924b563aa31421836cee7655be729ad02733fDouglas Gregorunsigned clang_CXXMethod_isVirtual(CXCursor C) { 5434211924b563aa31421836cee7655be729ad02733fDouglas Gregor if (!clang_isDeclaration(C.kind)) 5435211924b563aa31421836cee7655be729ad02733fDouglas Gregor return 0; 5436211924b563aa31421836cee7655be729ad02733fDouglas Gregor 5437211924b563aa31421836cee7655be729ad02733fDouglas Gregor CXXMethodDecl *Method = 0; 5438211924b563aa31421836cee7655be729ad02733fDouglas Gregor Decl *D = cxcursor::getCursorDecl(C); 5439211924b563aa31421836cee7655be729ad02733fDouglas Gregor if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D)) 5440211924b563aa31421836cee7655be729ad02733fDouglas Gregor Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); 5441211924b563aa31421836cee7655be729ad02733fDouglas Gregor else 5442211924b563aa31421836cee7655be729ad02733fDouglas Gregor Method = dyn_cast_or_null<CXXMethodDecl>(D); 5443211924b563aa31421836cee7655be729ad02733fDouglas Gregor return (Method && Method->isVirtual()) ? 1 : 0; 5444211924b563aa31421836cee7655be729ad02733fDouglas Gregor} 5445211924b563aa31421836cee7655be729ad02733fDouglas Gregor 54469ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek} // end: extern "C" 54479ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek 544845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek//===----------------------------------------------------------------------===// 544995f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek// Attribute introspection. 545095f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek//===----------------------------------------------------------------------===// 545195f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 545295f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenekextern "C" { 545395f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted KremenekCXType clang_getIBOutletCollectionType(CXCursor C) { 545495f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek if (C.kind != CXCursor_IBOutletCollectionAttr) 5455a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C)); 545695f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 545795f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek IBOutletCollectionAttr *A = 545895f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C)); 545995f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 546018aa2ff4641847d7f8866e8c5912d4d0ddb858ceArgyrios Kyrtzidis return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C)); 546195f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek} 546295f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek} // end: extern "C" 546395f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 546495f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek//===----------------------------------------------------------------------===// 546559fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek// Inspecting memory usage. 546659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek//===----------------------------------------------------------------------===// 546759fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 5468f787002478f09af1741fb0f82a562002e6799c49Ted Kremenektypedef std::vector<CXTUResourceUsageEntry> MemUsageEntries; 546959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 5470f787002478f09af1741fb0f82a562002e6799c49Ted Kremenekstatic inline void createCXTUResourceUsageEntry(MemUsageEntries &entries, 5471f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek enum CXTUResourceUsageKind k, 5472ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek unsigned long amount) { 5473f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek CXTUResourceUsageEntry entry = { k, amount }; 547459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek entries.push_back(entry); 547559fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek} 547659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 547759fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenekextern "C" { 547859fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 5479f787002478f09af1741fb0f82a562002e6799c49Ted Kremenekconst char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) { 548059fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek const char *str = ""; 548159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek switch (kind) { 5482f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek case CXTUResourceUsage_AST: 548359fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek str = "ASTContext: expressions, declarations, and types"; 548459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek break; 5485f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek case CXTUResourceUsage_Identifiers: 548659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek str = "ASTContext: identifiers"; 548759fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek break; 5488f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek case CXTUResourceUsage_Selectors: 548959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek str = "ASTContext: selectors"; 5490e294ab717fc9535429ca5d8f575d41ae4441d822Ted Kremenek break; 5491f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek case CXTUResourceUsage_GlobalCompletionResults: 54924e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek str = "Code completion: cached global results"; 5493e294ab717fc9535429ca5d8f575d41ae4441d822Ted Kremenek break; 5494457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek case CXTUResourceUsage_SourceManagerContentCache: 5495457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek str = "SourceManager: content cache allocator"; 5496457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek break; 5497ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek case CXTUResourceUsage_AST_SideTables: 5498ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek str = "ASTContext: side tables"; 5499ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek break; 5500f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek case CXTUResourceUsage_SourceManager_Membuffer_Malloc: 5501f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek str = "SourceManager: malloc'ed memory buffers"; 5502f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek break; 5503f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek case CXTUResourceUsage_SourceManager_Membuffer_MMap: 5504f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek str = "SourceManager: mmap'ed memory buffers"; 5505f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek break; 5506e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc: 5507e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek str = "ExternalASTSource: malloc'ed memory buffers"; 5508e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek break; 5509e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap: 5510e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek str = "ExternalASTSource: mmap'ed memory buffers"; 5511e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek break; 55125e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek case CXTUResourceUsage_Preprocessor: 55135e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek str = "Preprocessor: malloc'ed memory"; 55145e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek break; 55155e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek case CXTUResourceUsage_PreprocessingRecord: 55165e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek str = "Preprocessor: PreprocessingRecord"; 55175e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek break; 5518ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek case CXTUResourceUsage_SourceManager_DataStructures: 5519ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek str = "SourceManager: data structures and tables"; 5520ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek break; 5521d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek case CXTUResourceUsage_Preprocessor_HeaderSearch: 5522d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek str = "Preprocessor: header search tables"; 5523d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek break; 552459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek } 552559fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek return str; 552659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek} 552759fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 5528f787002478f09af1741fb0f82a562002e6799c49Ted KremenekCXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) { 552959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek if (!TU) { 5530f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek CXTUResourceUsage usage = { (void*) 0, 0, 0 }; 553159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek return usage; 553259fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek } 553359fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 553459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData); 553559fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek llvm::OwningPtr<MemUsageEntries> entries(new MemUsageEntries()); 553659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek ASTContext &astContext = astUnit->getASTContext(); 553759fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 553859fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek // How much memory is used by AST nodes and types? 5539f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST, 5540ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek (unsigned long) astContext.getASTAllocatedMemory()); 554159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 554259fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek // How much memory is used by identifiers? 5543f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers, 554459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek (unsigned long) astContext.Idents.getAllocator().getTotalMemory()); 554559fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 554659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek // How much memory is used for selectors? 5547f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors, 554859fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek (unsigned long) astContext.Selectors.getTotalMemory()); 554959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 5550ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek // How much memory is used by ASTContext's side tables? 5551ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables, 5552ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek (unsigned long) astContext.getSideTableAllocatedMemory()); 5553ba29bd25515fbd99e98ba0fedb9d93617b27609eTed Kremenek 55544e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek // How much memory is used for caching global code completion results? 55554e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek unsigned long completionBytes = 0; 55564e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek if (GlobalCodeCompletionAllocator *completionAllocator = 55574e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek astUnit->getCachedCompletionAllocator().getPtr()) { 55585e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek completionBytes = completionAllocator->getTotalMemory(); 55594e6a3f7310d3d9232877ed6f439247b1054b1e47Ted Kremenek } 5560457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek createCXTUResourceUsageEntry(*entries, 5561457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek CXTUResourceUsage_GlobalCompletionResults, 5562457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek completionBytes); 5563457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek 5564457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek // How much memory is being used by SourceManager's content cache? 5565457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek createCXTUResourceUsageEntry(*entries, 5566457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek CXTUResourceUsage_SourceManagerContentCache, 5567457aaf0692dfb2d9638f383334b81027f637f20cTed Kremenek (unsigned long) astContext.getSourceManager().getContentCacheSize()); 5568f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 5569f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek // How much memory is being used by the MemoryBuffer's in SourceManager? 5570f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek const SourceManager::MemoryBufferSizes &srcBufs = 5571f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek astUnit->getSourceManager().getMemoryBufferSizes(); 5572f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek 5573f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek createCXTUResourceUsageEntry(*entries, 5574f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek CXTUResourceUsage_SourceManager_Membuffer_Malloc, 5575f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek (unsigned long) srcBufs.malloc_bytes); 5576ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek createCXTUResourceUsageEntry(*entries, 5577f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek CXTUResourceUsage_SourceManager_Membuffer_MMap, 5578f61b831d7f6a15676b07647f507de80324cb7056Ted Kremenek (unsigned long) srcBufs.mmap_bytes); 5579ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek createCXTUResourceUsageEntry(*entries, 5580ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek CXTUResourceUsage_SourceManager_DataStructures, 5581ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek (unsigned long) astContext.getSourceManager() 5582ca7dc2b755eb81ac95121ce1a1f1aa44a4a0fe12Ted Kremenek .getDataStructureSizes()); 5583e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek 5584e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek // How much memory is being used by the ExternalASTSource? 5585e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek if (ExternalASTSource *esrc = astContext.getExternalSource()) { 5586e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek const ExternalASTSource::MemoryBufferSizes &sizes = 5587e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek esrc->getMemoryBufferSizes(); 5588e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek 5589e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek createCXTUResourceUsageEntry(*entries, 5590e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc, 5591e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek (unsigned long) sizes.malloc_bytes); 5592e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek createCXTUResourceUsageEntry(*entries, 5593e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek CXTUResourceUsage_ExternalASTSource_Membuffer_MMap, 5594e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek (unsigned long) sizes.mmap_bytes); 5595e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3Ted Kremenek } 55965e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek 55975e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek // How much memory is being used by the Preprocessor? 55985e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek Preprocessor &pp = astUnit->getPreprocessor(); 55995e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek createCXTUResourceUsageEntry(*entries, 56005e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek CXTUResourceUsage_Preprocessor, 5601c5c5e92ec53f7e6ac7ebbbf77c6d8e4b7d88daecArgyrios Kyrtzidis pp.getTotalMemory()); 56025e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek 56035e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) { 56045e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek createCXTUResourceUsageEntry(*entries, 56055e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek CXTUResourceUsage_PreprocessingRecord, 56065e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek pRec->getTotalMemory()); 56075e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek } 56085e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek 5609d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek createCXTUResourceUsageEntry(*entries, 5610d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek CXTUResourceUsage_Preprocessor_HeaderSearch, 5611d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek pp.getHeaderSearchInfo().getTotalMemory()); 56125e1db6a434d0e3fe0fbde0bca2ec44552818fb22Ted Kremenek 5613f787002478f09af1741fb0f82a562002e6799c49Ted Kremenek CXTUResourceUsage usage = { (void*) entries.get(), 561459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek (unsigned) entries->size(), 561559fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek entries->size() ? &(*entries)[0] : 0 }; 561659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek entries.take(); 561759fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek return usage; 561859fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek} 561959fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 5620f787002478f09af1741fb0f82a562002e6799c49Ted Kremenekvoid clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) { 562159fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek if (usage.data) 562259fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek delete (MemUsageEntries*) usage.data; 562359fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek} 562459fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 562559fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek} // end extern "C" 562659fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 56276df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregorvoid clang::PrintLibclangResourceUsage(CXTranslationUnit TU) { 56286df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU); 56296df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor for (unsigned I = 0; I != Usage.numEntries; ++I) 56306df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor fprintf(stderr, " %s: %lu\n", 56316df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor clang_getTUResourceUsageName(Usage.entries[I].kind), 56326df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor Usage.entries[I].amount); 56336df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor 56346df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor clang_disposeCXTUResourceUsage(Usage); 56356df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor} 56366df78739f3b3f672f9735445741cbcfa7c10fb1fDouglas Gregor 563759fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek//===----------------------------------------------------------------------===// 563804bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek// Misc. utility functions. 563904bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek//===----------------------------------------------------------------------===// 5640f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 5641abdce7abc8a22dd2fe79a05c0b71864039bd8296Daniel Dunbar/// Default to using an 8 MB stack size on "safety" threads. 5642abdce7abc8a22dd2fe79a05c0b71864039bd8296Daniel Dunbarstatic unsigned SafetyStackThreadSize = 8 << 20; 5643bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 5644bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarnamespace clang { 5645bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 5646bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarbool RunSafely(llvm::CrashRecoveryContext &CRC, 56476c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek void (*Fn)(void*), void *UserData, 56486c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek unsigned Size) { 56496c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek if (!Size) 56506c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek Size = GetSafetyThreadStackSize(); 56516c53fdd88f0d75875365463822fa817d7b1a9573Ted Kremenek if (Size) 5652bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar return CRC.RunSafelyOnThread(Fn, UserData, Size); 5653bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar return CRC.RunSafely(Fn, UserData); 5654bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar} 5655bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 5656bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarunsigned GetSafetyThreadStackSize() { 5657bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar return SafetyStackThreadSize; 5658bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar} 5659bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 5660bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbarvoid SetSafetyThreadStackSize(unsigned Value) { 5661bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar SafetyStackThreadSize = Value; 5662bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar} 5663bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 5664bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar} 5665bf44c3b099602c9c967f1b20995919fb4ef39a51Daniel Dunbar 566604bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenekextern "C" { 566704bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek 5668a2a9d6e4e5b6001b86b7dfc5db1ea296ce29a3d3Ted KremenekCXString clang_getClangVersion() { 5669ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(getClangFullVersion()); 567004bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek} 567104bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek 567204bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek} // end: extern "C" 567359fc1e55da9c856d1703d3d3ac14a36320d26b30Ted Kremenek 5674