CIndex.cpp revision 0582c897ec7261b4c6af0fe26dc2a0b6b54d266c
1d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===// 2d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// 3d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// The LLVM Compiler Infrastructure 4d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// 5d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// This file is distributed under the University of Illinois Open Source 6d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// License. See LICENSE.TXT for details. 70d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar// 8d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//===----------------------------------------------------------------------===// 9d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// 10ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// This file implements the main API hooks in the Clang-C Source Indexing 11ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// library. 12d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek// 13d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek//===----------------------------------------------------------------------===// 14d2fa56687f8bd5ac6ebf9d9468d0efd714986a54Ted Kremenek 15ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "CIndexer.h" 1616c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "CXCursor.h" 1795f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek#include "CXType.h" 18a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek#include "CXSourceLocation.h" 195352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor#include "CIndexDiagnostic.h" 20ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek 2104bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek#include "clang/Basic/Version.h" 22936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor 2350398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff#include "clang/AST/DeclVisitor.h" 24fb5704295c6137685a7b90b92cd6b958028740c8Steve Naroff#include "clang/AST/StmtVisitor.h" 257d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor#include "clang/AST/TypeLocVisitor.h" 26b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Basic/Diagnostic.h" 27b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Frontend/ASTUnit.h" 28b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Frontend/CompilerInstance.h" 29936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor#include "clang/Frontend/FrontendDiagnostic.h" 30d8210650ed948de65a08a8daf16d291b747717c4Ted Kremenek#include "clang/Lex/Lexer.h" 31b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Lex/PreprocessingRecord.h" 3233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor#include "clang/Lex/Preprocessor.h" 33a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor#include "llvm/ADT/STLExtras.h" 34d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek#include "llvm/ADT/Optional.h" 35d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek#include "clang/Analysis/Support/SaveAndRestore.h" 36c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar#include "llvm/Support/CrashRecoveryContext.h" 3748615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar#include "llvm/Support/PrettyStackTrace.h" 3802465750c8c3fa96b1e7e596b02297e24361dc4fDouglas Gregor#include "llvm/Support/MemoryBuffer.h" 39358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor#include "llvm/Support/raw_ostream.h" 407a07fcb8f10fe45ea65a0a41798eb1c40777bde4Douglas Gregor#include "llvm/Support/Timer.h" 418c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor#include "llvm/System/Mutex.h" 420829a839b05c687d3f11af0640d84c5d05f94124Benjamin Kramer#include "llvm/System/Program.h" 430a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor#include "llvm/System/Signals.h" 448c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor#include "llvm/System/Threading.h" 45fc0622155fa61349698a8fd0053773c37d9f7ac4Ted Kremenek 46c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer// Needed to define L_TMPNAM on some systems. 47c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer#include <cstdio> 48c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer 4950398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroffusing namespace clang; 5016c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenekusing namespace clang::cxcursor; 51ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenekusing namespace clang::cxstring; 5250398199fb10e196a8d92fbf7a062dbe42ed88fdSteve Naroff 5333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \brief The result of comparing two source ranges. 5433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregorenum RangeComparisonResult { 5533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief Either the ranges overlap or one of the ranges is invalid. 5633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor RangeOverlap, 57f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 5833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The first range ends before the second range starts. 5933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor RangeBefore, 60f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 6133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The first range starts after the second range ends. 6233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor RangeAfter 6333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor}; 6433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 65f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek/// \brief Compare two source ranges to determine their relative position in 6633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// the translation unit. 67f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekstatic RangeComparisonResult RangeCompare(SourceManager &SM, 68f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek SourceRange R1, 6933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor SourceRange R2) { 7033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor assert(R1.isValid() && "First range is invalid?"); 7133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor assert(R2.isValid() && "Second range is invalid?"); 72a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (R1.getEnd() != R2.getBegin() && 73d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin())) 7433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return RangeBefore; 75a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (R2.getEnd() != R1.getBegin() && 76d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin())) 7733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return RangeAfter; 7833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return RangeOverlap; 7933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor} 8033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 81fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek/// \brief Determine if a source location falls within, before, or after a 82fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek/// a given source range. 83fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekstatic RangeComparisonResult LocationCompare(SourceManager &SM, 84fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation L, SourceRange R) { 85fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek assert(R.isValid() && "First range is invalid?"); 86fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek assert(L.isValid() && "Second range is invalid?"); 87a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (L == R.getBegin() || L == R.getEnd()) 88fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeOverlap; 89fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (SM.isBeforeInTranslationUnit(L, R.getBegin())) 90fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeBefore; 91fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (SM.isBeforeInTranslationUnit(R.getEnd(), L)) 92fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeAfter; 93fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return RangeOverlap; 94fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek} 95fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 9676dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// \brief Translate a Clang source range into a CIndex source range. 9776dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// 9876dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// Clang internally represents ranges where the end location points to the 9976dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// start of the token at the end. However, for external clients it is more 10076dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// useful to have a CXSourceRange be a proper half-open interval. This routine 10176dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar/// does the appropriate translation. 102f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed KremenekCXSourceRange cxloc::translateSourceRange(const SourceManager &SM, 10376dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar const LangOptions &LangOpts, 1040a76aae8c03cb7dd7bdbe683485560afaf695959Chris Lattner const CharSourceRange &R) { 10576dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar // We want the last character in this location, so we will adjust the 1066a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor // location accordingly. 1076a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor // FIXME: How do do this with a macro instantiation location? 10876dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar SourceLocation EndLoc = R.getEnd(); 1090a76aae8c03cb7dd7bdbe683485560afaf695959Chris Lattner if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) { 1106a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts); 11176dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar EndLoc = EndLoc.getFileLocWithOffset(Length); 11276dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar } 11376dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar 11476dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts }, 11576dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar R.getBegin().getRawEncoding(), 11676dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar EndLoc.getRawEncoding() }; 11776dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar return Result; 11876dd3c2ff274772dc5771cb73f856d14aaf5ee2fDaniel Dunbar} 1191db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 1208a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek//===----------------------------------------------------------------------===// 12133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor// Cursor visitor. 1228a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek//===----------------------------------------------------------------------===// 1238a8da7d17d4eb281b61d08d603c7bb180d280d5aTed Kremenek 12489922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroffnamespace { 125f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 126b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor// Cursor visitor. 1277d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorclass CursorVisitor : public DeclVisitor<CursorVisitor, bool>, 128a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor public TypeLocVisitor<CursorVisitor, bool>, 129a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor public StmtVisitor<CursorVisitor, bool> 1307d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor{ 13133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The translation unit we are traversing. 132b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor ASTUnit *TU; 133f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 13433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The parent cursor whose children we are traversing. 135b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXCursor Parent; 136f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 13733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The declaration that serves at the parent of any statement or 13833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// expression nodes. 139f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor Decl *StmtParent; 140f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 14133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The visitor function. 142b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXCursorVisitor Visitor; 143f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 14433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief The opaque client data, to be passed along to the visitor. 145b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXClientData ClientData; 146f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1477d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor // MaxPCHLevel - the maximum PCH level of declarations that we will pass on 1487d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor // to the visitor. Declarations with a PCH level greater than this value will 1497d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor // be suppressed. 1507d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor unsigned MaxPCHLevel; 15133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 15233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// \brief When valid, a source range to which the cursor should restrict 15333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// its search. 15433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor SourceRange RegionOfInterest; 155f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 156d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // FIXME: Eventually remove. This part of a hack to support proper 157d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // iteration over all Decls contained lexically within an ObjC container. 158d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator *DI_current; 159d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator DE_current; 160d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 161b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor using DeclVisitor<CursorVisitor, bool>::Visit; 1627d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor using TypeLocVisitor<CursorVisitor, bool>::Visit; 163a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor using StmtVisitor<CursorVisitor, bool>::Visit; 164f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 165f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek /// \brief Determine whether this particular source range comes before, comes 166f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek /// after, or overlaps the region of interest. 16733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor /// 168d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar /// \param R a half-open source range retrieved from the abstract syntax tree. 169f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek RangeComparisonResult CompareRegionOfInterest(SourceRange R); 170f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1710f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek class SetParentRAII { 1720f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek CXCursor &Parent; 1730f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek Decl *&StmtParent; 1740f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek CXCursor OldParent; 1750f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 1760f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek public: 1770f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent) 1780f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) 1790f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek { 1800f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek Parent = NewParent; 1810f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (clang_isDeclaration(Parent.kind)) 1820f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek StmtParent = getCursorDecl(Parent); 1830f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek } 1840f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 1850f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek ~SetParentRAII() { 1860f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek Parent = OldParent; 1870f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (clang_isDeclaration(Parent.kind)) 1880f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek StmtParent = getCursorDecl(Parent); 1890f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek } 1900f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek }; 1910f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 192b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorpublic: 193f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData, 194f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek unsigned MaxPCHLevel, 19533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor SourceRange RegionOfInterest = SourceRange()) 196f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek : TU(TU), Visitor(Visitor), ClientData(ClientData), 197d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest), 198d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DI_current(0) 199b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor { 200b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.kind = CXCursor_NoDeclFound; 201b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.data[0] = 0; 202b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.data[1] = 0; 203b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Parent.data[2] = 0; 204f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor StmtParent = 0; 205b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 206f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 20733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false); 208788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 209788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> 210788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor getPreprocessedEntities(); 211788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 212b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor bool VisitChildren(CXCursor Parent); 213f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2147d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor // Declaration visitors 21509dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek bool VisitAttributes(Decl *D); 2161ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek bool VisitBlockDecl(BlockDecl *B); 2173064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek bool VisitCXXRecordDecl(CXXRecordDecl *D); 218d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek llvm::Optional<bool> shouldVisitCursor(CXCursor C); 219b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor bool VisitDeclContext(DeclContext *DC); 22079758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitTranslationUnitDecl(TranslationUnitDecl *D); 22179758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitTypedefDecl(TypedefDecl *D); 22279758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitTagDecl(TagDecl *D); 2230ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D); 22474dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor bool VisitClassTemplatePartialSpecializationDecl( 22574dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor ClassTemplatePartialSpecializationDecl *D); 226fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); 2274540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitEnumConstantDecl(EnumConstantDecl *D); 22879758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitDeclaratorDecl(DeclaratorDecl *DD); 2294540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitFunctionDecl(FunctionDecl *ND); 23079758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitFieldDecl(FieldDecl *D); 23179758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitVarDecl(VarDecl *); 23284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); 233fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D); 23439d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor bool VisitClassTemplateDecl(ClassTemplateDecl *D); 23584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); 23679758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCMethodDecl(ObjCMethodDecl *ND); 2374540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitObjCContainerDecl(ObjCContainerDecl *D); 23879758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND); 23979758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID); 24023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD); 24179758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); 2424540c9c73787d6ef736792f24209727b64997c90Ted Kremenek bool VisitObjCImplDecl(ObjCImplDecl *D); 24379758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); 2441ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor bool VisitObjCImplementationDecl(ObjCImplementationDecl *D); 24579758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations. 24679758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); 24779758f614c83ba17757618de1459e2b481f19dd2Ted Kremenek bool VisitObjCClassDecl(ObjCClassDecl *D); 248a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek bool VisitLinkageSpecDecl(LinkageSpecDecl *D); 2498f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek bool VisitNamespaceDecl(NamespaceDecl *D); 2506931900f43cea558c6974075256c07728dbfecc6Douglas Gregor bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D); 2510a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D); 2527e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor bool VisitUsingDecl(UsingDecl *D); 2537e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); 2547e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); 2550a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 25601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Name visitor 25701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor bool VisitDeclarationNameInfo(DeclarationNameInfo Name); 258c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range); 25901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 260fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // Template visitors 261fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateParameters(const TemplateParameterList *Params); 2620b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor bool VisitTemplateName(TemplateName Name, SourceLocation Loc); 263fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL); 264fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 2657d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor // Type visitors 26601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL); 267f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL); 2687d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor bool VisitTypedefTypeLoc(TypedefTypeLoc TL); 269f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL); 270f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitTagTypeLoc(TagTypeLoc TL); 271fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL); 272f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL); 273c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL); 274f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL); 275f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitPointerTypeLoc(PointerTypeLoc TL); 276f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL); 277f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL); 278f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL); 279f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL); 28001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false); 281f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor bool VisitArrayTypeLoc(ArrayTypeLoc TL); 282fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL); 2832332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor // FIXME: Implement visitors here when the unimplemented TypeLocs get 2842332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor // implemented 2852332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL); 2862332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL); 287f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 288a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor // Statement visitors 289a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor bool VisitStmt(Stmt *S); 290a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor bool VisitDeclStmt(DeclStmt *S); 29136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor bool VisitGotoStmt(GotoStmt *S); 292f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor bool VisitIfStmt(IfStmt *S); 293f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor bool VisitSwitchStmt(SwitchStmt *S); 2940f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek bool VisitCaseStmt(CaseStmt *S); 295263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor bool VisitWhileStmt(WhileStmt *S); 296263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor bool VisitForStmt(ForStmt *S); 297f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 298336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor // Expression visitors 2998947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor bool VisitDeclRefExpr(DeclRefExpr *E); 3006cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E); 3011ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek bool VisitBlockExpr(BlockExpr *B); 302336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E); 3031ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek bool VisitExplicitCastExpr(ExplicitCastExpr *E); 304c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregor bool VisitObjCMessageExpr(ObjCMessageExpr *E); 30581d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor bool VisitObjCEncodeExpr(ObjCEncodeExpr *E); 3068ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor bool VisitOffsetOfExpr(OffsetOfExpr *E); 3071ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); 308fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor bool VisitMemberExpr(MemberExpr *E); 30936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor bool VisitAddrLabelExpr(AddrLabelExpr *E); 310648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor bool VisitTypesCompatibleExpr(TypesCompatibleExpr *E); 311648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor bool VisitVAArgExpr(VAArgExpr *E); 312fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor bool VisitInitListExpr(InitListExpr *E); 313fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor bool VisitDesignatedInitExpr(DesignatedInitExpr *E); 314948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor bool VisitCXXTypeidExpr(CXXTypeidExpr *E); 3153d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor bool VisitCXXUuidofExpr(CXXUuidofExpr *E); 316da135b14ad5366f27143c9cd9f51ad2320e62758Douglas Gregor bool VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { return false; } 317ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor bool VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E); 318ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor bool VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); 3191bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor bool VisitCXXNewExpr(CXXNewExpr *E); 3206f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor bool VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); 3213d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor bool VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E); 3221f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor bool VisitOverloadExpr(OverloadExpr *E); 323bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); 324ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor bool VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E); 32525d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); 326aaa80b208de3e2c706badf45060bd126fa747b84Douglas Gregor bool VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E); 327b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor}; 328f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 329b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} // end anonymous namespace 3300d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 331a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorstatic SourceRange getRawCursorExtent(CXCursor C); 332a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 33333e9abd21083a0191a7676a04b497006d2da184dDouglas GregorRangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) { 33433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return RangeCompare(TU->getSourceManager(), R, RegionOfInterest); 33533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor} 33633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 337b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \brief Visit the given cursor and, if requested by the visitor, 338b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// its children. 339b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// 34033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \param Cursor the cursor to visit. 34133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// 34233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// \param CheckRegionOfInterest if true, then the caller already checked that 34333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// this cursor is within the region of interest. 34433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor/// 345b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \returns true if the visitation should be aborted, false if it 346b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// should continue. 34733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregorbool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) { 348b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isInvalid(Cursor.kind)) 349b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 350f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 351b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isDeclaration(Cursor.kind)) { 352b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Decl *D = getCursorDecl(Cursor); 353b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor assert(D && "Invalid declaration cursor"); 354b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (D->getPCHLevel() > MaxPCHLevel) 355b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 356b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor 357b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (D->isImplicit()) 358b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 359b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 3600d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 36133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // If we have a range of interest, and this cursor doesn't intersect with it, 36233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // we're done. 36333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) { 364a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor SourceRange Range = getRawCursorExtent(Cursor); 365f408f32aa9ae3d97bc656267dc5d78fa7d03499bDaniel Dunbar if (Range.isInvalid() || CompareRegionOfInterest(Range)) 36633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return false; 36733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor } 368f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 369b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor switch (Visitor(Cursor, Parent, ClientData)) { 370b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor case CXChildVisit_Break: 371b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 3720d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 373b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor case CXChildVisit_Continue: 374b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 3752e331b938b38057e333fab0ba841130ea8467794Douglas Gregor 376b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor case CXChildVisit_Recurse: 377b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return VisitChildren(Cursor); 378b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 3790d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 380fd64377225a6a140bddb3f997d52a036486f9360Douglas Gregor return false; 381b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} 3820d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 383788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregorstd::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> 384788f5a1242c04762f91eaa7565c07b9865846d88Douglas GregorCursorVisitor::getPreprocessedEntities() { 385788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor PreprocessingRecord &PPRec 386788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = *TU->getPreprocessor().getPreprocessingRecord(); 387788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 388788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor bool OnlyLocalDecls 389788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = !TU->isMainFileAST() && TU->getOnlyLocalDecls(); 390788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 391788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // There is no region of interest; we have to walk everything. 392788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (RegionOfInterest.isInvalid()) 393788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor return std::make_pair(PPRec.begin(OnlyLocalDecls), 394788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor PPRec.end(OnlyLocalDecls)); 395788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 396788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // Find the file in which the region of interest lands. 397788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor SourceManager &SM = TU->getSourceManager(); 398788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor std::pair<FileID, unsigned> Begin 399788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin()); 400788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor std::pair<FileID, unsigned> End 401788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd()); 402788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 403788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // The region of interest spans files; we have to walk everything. 404788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (Begin.first != End.first) 405788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor return std::make_pair(PPRec.begin(OnlyLocalDecls), 406788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor PPRec.end(OnlyLocalDecls)); 407788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 408788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap 409788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = TU->getPreprocessedEntitiesByFile(); 410788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor if (ByFileMap.empty()) { 411788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor // Build the mapping from files to sets of preprocessed entities. 412788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor for (PreprocessingRecord::iterator E = PPRec.begin(OnlyLocalDecls), 413788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor EEnd = PPRec.end(OnlyLocalDecls); 414788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor E != EEnd; ++E) { 415788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor std::pair<FileID, unsigned> P 416788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin()); 417788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor ByFileMap[P.first].push_back(*E); 418788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor } 419788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor } 420788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 421788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor return std::make_pair(ByFileMap[Begin.first].begin(), 422788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor ByFileMap[Begin.first].end()); 423788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor} 424788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 425b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \brief Visit the children of the given cursor. 426b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// 427b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// \returns true if the visitation should be aborted, false if it 428b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor/// should continue. 429f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekbool CursorVisitor::VisitChildren(CXCursor Cursor) { 430a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor if (clang_isReference(Cursor.kind)) { 431a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor // By definition, references have no children. 432a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return false; 433a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor } 434f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 435f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek // Set the Parent field to Cursor, then back to its old value once we're 436b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor // done. 4370f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek SetParentRAII SetParent(Parent, StmtParent, Cursor); 438f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 439b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isDeclaration(Cursor.kind)) { 440b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Decl *D = getCursorDecl(Cursor); 441b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor assert(D && "Invalid declaration cursor"); 442539311e0221df256c70c1c3080c8af847cd29dffTed Kremenek return VisitAttributes(D) || Visit(D); 443b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 444f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 445a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor if (clang_isStatement(Cursor.kind)) 446a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return Visit(getCursorStmt(Cursor)); 447a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor if (clang_isExpression(Cursor.kind)) 448a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return Visit(getCursorExpr(Cursor)); 449f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 450b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (clang_isTranslationUnit(Cursor.kind)) { 451b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor ASTUnit *CXXUnit = getCursorASTUnit(Cursor); 45233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() && 45333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor RegionOfInterest.isInvalid()) { 454eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(), 455eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TLEnd = CXXUnit->top_level_end(); 456eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor TL != TLEnd; ++TL) { 457eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor if (Visit(MakeCXCursor(*TL, CXXUnit), true)) 4587b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor return true; 4597b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor } 4600396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor } else if (VisitDeclContext( 4610396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor CXXUnit->getASTContext().getTranslationUnitDecl())) 4620396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor return true; 4633178cb674ac8c3b59e1791e14d38d48619a1b621Bob Wilson 4640396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // Walk the preprocessing record. 4658de30ffa2b60dbc672c0f3bcdaa07a8efcc3bcf8Daniel Dunbar if (CXXUnit->getPreprocessor().getPreprocessingRecord()) { 4660396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // FIXME: Once we have the ability to deserialize a preprocessing record, 4670396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // do so. 468788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor PreprocessingRecord::iterator E, EEnd; 469788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) { 4700396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { 4710396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (Visit(MakeMacroInstantiationCursor(MI, CXXUnit))) 4720396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor return true; 473788f5a1242c04762f91eaa7565c07b9865846d88Douglas Gregor 4740396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor continue; 4750396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor } 4760396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor 4770396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { 4780396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (Visit(MakeMacroDefinitionCursor(MD, CXXUnit))) 4790396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor return true; 4800396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor 4810396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor continue; 4820396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor } 483ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 484ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) { 485ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (Visit(MakeInclusionDirectiveCursor(ID, CXXUnit))) 486ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return true; 487ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 488ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor continue; 489ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor } 4900396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor } 4910396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor } 4927b691f33829e6a302e256e138b3917390c2665bbDouglas Gregor return false; 493b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 494f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 495b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor // Nothing to visit at the moment. 496b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 497dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 498dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 4991ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenekbool CursorVisitor::VisitBlockDecl(BlockDecl *B) { 500fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall if (Visit(B->getSignatureAsWritten()->getTypeLoc())) 501fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall return true; 5021ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek 503664cffd330611d78fc0286f539589920a37ca328Ted Kremenek if (Stmt *Body = B->getBody()) 504664cffd330611d78fc0286f539589920a37ca328Ted Kremenek return Visit(MakeCXCursor(Body, StmtParent, TU)); 505664cffd330611d78fc0286f539589920a37ca328Ted Kremenek 506664cffd330611d78fc0286f539589920a37ca328Ted Kremenek return false; 5071ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek} 5081ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek 509d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenekllvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) { 510d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (RegionOfInterest.isValid()) { 511d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceRange Range = getRawCursorExtent(Cursor); 512d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (Range.isInvalid()) 513d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return llvm::Optional<bool>(); 51409dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek 515d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek switch (CompareRegionOfInterest(Range)) { 516d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek case RangeBefore: 517d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // This declaration comes before the region of interest; skip it. 518d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return llvm::Optional<bool>(); 51923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 520d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek case RangeAfter: 521d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // This declaration comes after the region of interest; we're done. 522d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 523d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar 524d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek case RangeOverlap: 525d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // This declaration overlaps the region of interest; visit it. 526d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 527d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 528d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 529d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return true; 530d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek} 531f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 532d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenekbool CursorVisitor::VisitDeclContext(DeclContext *DC) { 533d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); 534f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 535d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // FIXME: Eventually remove. This part of a hack to support proper 536d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // iteration over all Decls contained lexically within an ObjC container. 537d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I); 538d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E); 539f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 540d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek for ( ; I != E; ++I) { 541d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek Decl *D = *I; 542d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (D->getLexicalDeclContext() != DC) 543d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 544d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek CXCursor Cursor = MakeCXCursor(D, TU); 545d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek const llvm::Optional<bool> &V = shouldVisitCursor(Cursor); 546d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.hasValue()) 547d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 548d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.getValue()) 549d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 550d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar if (Visit(Cursor, true)) 551b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 552b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor } 553b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 554dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 555dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 5561ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) { 5571ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor llvm_unreachable("Translation units are visited directly by Visit()"); 5581ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 5591ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 5601ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 5611ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) { 5621ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo()) 5631ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(TSInfo->getTypeLoc()); 564f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 5651ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 5661ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 5671ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 5681ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitTagDecl(TagDecl *D) { 5691ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitDeclContext(D); 5701ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 5711ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 5720ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregorbool CursorVisitor::VisitClassTemplateSpecializationDecl( 5730ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor ClassTemplateSpecializationDecl *D) { 5740ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor bool ShouldVisitBody = false; 5750ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor switch (D->getSpecializationKind()) { 5760ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_Undeclared: 5770ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ImplicitInstantiation: 5780ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor // Nothing to visit 5790ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return false; 5800ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 5810ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ExplicitInstantiationDeclaration: 5820ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ExplicitInstantiationDefinition: 5830ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor break; 5840ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 5850ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor case TSK_ExplicitSpecialization: 5860ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor ShouldVisitBody = true; 5870ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor break; 5880ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor } 5890ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 5900ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor // Visit the template arguments used in the specialization. 5910ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) { 5920ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor TypeLoc TL = SpecType->getTypeLoc(); 5930ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (TemplateSpecializationTypeLoc *TSTLoc 5940ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) { 5950ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I) 5960ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I))) 5970ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return true; 5980ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor } 5990ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor } 6000ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6010ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor if (ShouldVisitBody && VisitCXXRecordDecl(D)) 6020ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return true; 6030ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 6040ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor return false; 6050ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor} 6060ab1e9f672a86cf3f094780d99251553a2b69fc7Douglas Gregor 60774dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregorbool CursorVisitor::VisitClassTemplatePartialSpecializationDecl( 60874dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor ClassTemplatePartialSpecializationDecl *D) { 60974dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor // FIXME: Visit the "outer" template parameter lists on the TagDecl 61074dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor // before visiting these template parameters. 61174dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 61274dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return true; 61374dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor 61474dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor // Visit the partial specialization arguments. 61574dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten(); 61674dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I) 61774dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor if (VisitTemplateArgumentLoc(TemplateArgs[I])) 61874dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return true; 61974dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor 62074dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return VisitCXXRecordDecl(D); 62174dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor} 62274dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor 623fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { 62484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor // Visit the default argument. 62584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) 62684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo()) 62784b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (Visit(DefArg->getTypeLoc())) 62884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 62984b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 630fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 631fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 632fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 6331ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) { 6341ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Expr *Init = D->getInitExpr()) 6351ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(MakeCXCursor(Init, StmtParent, TU)); 6361ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 6371ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 6381ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 6397d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorbool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { 6407d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo()) 6417d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor if (Visit(TSInfo->getTypeLoc())) 6427d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor return true; 6437d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 6447d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor return false; 6457d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor} 6467d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 647a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor/// \brief Compare two base or member initializers based on their source order. 648a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregorstatic int CompareCXXBaseOrMemberInitializers(const void* Xp, const void *Yp) { 649a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor CXXBaseOrMemberInitializer const * const *X 650a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor = static_cast<CXXBaseOrMemberInitializer const * const *>(Xp); 651a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor CXXBaseOrMemberInitializer const * const *Y 652a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor = static_cast<CXXBaseOrMemberInitializer const * const *>(Yp); 653a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 654a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if ((*X)->getSourceOrder() < (*Y)->getSourceOrder()) 655a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return -1; 656a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder()) 657a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return 1; 658a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor else 659a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return 0; 660a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor} 661a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 662b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { 66301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) { 66401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Visit the function declaration's syntactic components in the order 66501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // written. This requires a bit of work. 66601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor TypeLoc TL = TSInfo->getTypeLoc(); 66701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL); 66801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 66901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // If we have a function declared directly (without the use of a typedef), 67001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // visit just the return type. Otherwise, just visit the function's type 67101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // now. 67201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) || 67301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor (!FTL && Visit(TL))) 67401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return true; 67501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 676c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit the nested-name-specifier, if present. 677c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = ND->getQualifier()) 678c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, ND->getQualifierRange())) 679c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 68001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 68101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Visit the declaration name. 68201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (VisitDeclarationNameInfo(ND->getNameInfo())) 68301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return true; 68401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 68501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // FIXME: Visit explicitly-specified template arguments! 68601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 68701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // Visit the function parameters, if we have a function type. 68801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (FTL && VisitFunctionTypeLoc(*FTL, true)) 68901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return true; 69001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 69101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // FIXME: Attributes? 69201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor } 69301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 694a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (ND->isThisDeclarationADefinition()) { 695a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) { 696a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Find the initializers that were written in the source. 697a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor llvm::SmallVector<CXXBaseOrMemberInitializer *, 4> WrittenInits; 698a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(), 699a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor IEnd = Constructor->init_end(); 700a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor I != IEnd; ++I) { 701a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (!(*I)->isWritten()) 702a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor continue; 703a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 704a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor WrittenInits.push_back(*I); 705a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 706a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 707a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Sort the initializers in source order 708a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(), 709a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor &CompareCXXBaseOrMemberInitializers); 710a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 711a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Visit the initializers in source order 712a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) { 713a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor CXXBaseOrMemberInitializer *Init = WrittenInits[I]; 714a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Init->isMemberInitializer()) { 715a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Visit(MakeCursorMemberRef(Init->getMember(), 716a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor Init->getMemberLocation(), TU))) 717a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 718a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) { 719a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Visit(BaseInfo->getTypeLoc())) 720a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 721a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 722a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 723a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor // Visit the initializer value. 724a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Expr *Initializer = Init->getInit()) 725a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Visit(MakeCXCursor(Initializer, ND, TU))) 726a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 727a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 728a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 729a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 730a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) 731a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return true; 732a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 733f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 734b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return false; 735b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} 736dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 7371ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitFieldDecl(FieldDecl *D) { 7381ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (VisitDeclaratorDecl(D)) 7391ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 740f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 7411ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Expr *BitWidth = D->getBitWidth()) 7421ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(MakeCXCursor(BitWidth, StmtParent, TU)); 743f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 7441ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 7451ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 7461ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 7471ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitVarDecl(VarDecl *D) { 7481ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (VisitDeclaratorDecl(D)) 7491ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 750f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 7511ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Expr *Init = D->getInit()) 7521ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return Visit(MakeCXCursor(Init, StmtParent, TU)); 753f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 7541ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 7551ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 7561ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 75784b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregorbool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { 75884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (VisitDeclaratorDecl(D)) 75984b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 76084b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 76184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) 76284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (Expr *DefArg = D->getDefaultArgument()) 76384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return Visit(MakeCXCursor(DefArg, StmtParent, TU)); 76484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 76584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return false; 76684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor} 76784b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 768fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { 769fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // FIXME: Visit the "outer" template parameter lists on the FunctionDecl 770fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // before visiting these template parameters. 771fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 772fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return true; 773fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 774fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return VisitFunctionDecl(D->getTemplatedDecl()); 775fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 776fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 77739d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregorbool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) { 77839d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor // FIXME: Visit the "outer" template parameter lists on the TagDecl 77939d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor // before visiting these template parameters. 78039d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 78139d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor return true; 78239d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor 78339d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor return VisitCXXRecordDecl(D->getTemplatedDecl()); 78439d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor} 78539d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor 78684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregorbool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { 78784b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (VisitTemplateParameters(D->getTemplateParameters())) 78884b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 78984b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 79084b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() && 79184b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor VisitTemplateArgumentLoc(D->getDefaultArgument())) 79284b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return true; 79384b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 79484b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor return false; 79584b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor} 79684b51d77e11aaf6ea4607e01187343423ce6c8aeDouglas Gregor 7971ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) { 7984bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo()) 7994bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor if (Visit(TSInfo->getTypeLoc())) 8004bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor return true; 8014bc1cb6aa635a5bf8fae99bf69c56c724c1e786cDouglas Gregor 802f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek for (ObjCMethodDecl::param_iterator P = ND->param_begin(), 8031ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor PEnd = ND->param_end(); 8041ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor P != PEnd; ++P) { 8051ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Visit(MakeCXCursor(*P, TU))) 8061ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 8071ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor } 808f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8091ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (ND->isThisDeclarationADefinition() && 8101ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) 8111ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 812f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 8131ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 8141ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 8151ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 816d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremeneknamespace { 817d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek struct ContainerDeclsSort { 818d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceManager &SM; 819d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek ContainerDeclsSort(SourceManager &sm) : SM(sm) {} 820d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek bool operator()(Decl *A, Decl *B) { 821d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation L_A = A->getLocStart(); 822d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation L_B = B->getLocStart(); 823d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek assert(L_A.isValid() && L_B.isValid()); 824d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return SM.isBeforeInTranslationUnit(L_A, L_B); 825d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 826d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek }; 827d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek} 828d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 829a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregorbool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) { 830d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially 831d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // an @implementation can lexically contain Decls that are not properly 832d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // nested in the AST. When we identify such cases, we need to retrofit 833d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // this nesting here. 834d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!DI_current) 835d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return VisitDeclContext(D); 836d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 837d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Scan the Decls that immediately come after the container 838d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // in the current DeclContext. If any fall within the 839d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // container's lexical region, stash them into a vector 840d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // for later processing. 841d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek llvm::SmallVector<Decl *, 24> DeclsInContainer; 842d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation EndLoc = D->getSourceRange().getEnd(); 843d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceManager &SM = TU->getSourceManager(); 844d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (EndLoc.isValid()) { 845d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclContext::decl_iterator next = *DI_current; 846d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek while (++next != DE_current) { 847d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek Decl *D_next = *next; 848d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!D_next) 849d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 850d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek SourceLocation L = D_next->getLocStart(); 851d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!L.isValid()) 852d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 853d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (SM.isBeforeInTranslationUnit(L, EndLoc)) { 854d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek *DI_current = next; 855d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclsInContainer.push_back(D_next); 856d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 857d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 858d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek break; 859d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 860d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 861d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 862d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // The common case. 863d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (DeclsInContainer.empty()) 864d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return VisitDeclContext(D); 865d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 866d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Get all the Decls in the DeclContext, and sort them with the 867d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // additional ones we've collected. Then visit them. 868d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end(); 869d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek I!=E; ++I) { 870d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek Decl *subDecl = *I; 8710582c897ec7261b4c6af0fe26dc2a0b6b54d266cTed Kremenek if (!subDecl || subDecl->getLexicalDeclContext() != D || 8720582c897ec7261b4c6af0fe26dc2a0b6b54d266cTed Kremenek subDecl->getLocStart().isInvalid()) 873d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 874d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek DeclsInContainer.push_back(subDecl); 875d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 876d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 877d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Now sort the Decls so that they appear in lexical order. 878d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek std::sort(DeclsInContainer.begin(), DeclsInContainer.end(), 879d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek ContainerDeclsSort(SM)); 880d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek 881d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek // Now visit the decls. 882d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(), 883d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek E = DeclsInContainer.end(); I != E; ++I) { 884d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek CXCursor Cursor = MakeCXCursor(*I, TU); 885d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek const llvm::Optional<bool> &V = shouldVisitCursor(Cursor); 886d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.hasValue()) 887d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek continue; 888d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (!V.getValue()) 889d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 890d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek if (Visit(Cursor, true)) 891d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return true; 892d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek } 893d8c370ca95a3bccc36c4a6b92a4042809ff51ee4Ted Kremenek return false; 894a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor} 895a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor 896b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { 897b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(), 898b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor TU))) 899b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 900f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 90178db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin(); 90278db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(), 90378db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor E = ND->protocol_end(); I != E; ++I, ++PL) 904b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 905b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 906f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 907a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return VisitObjCContainerDecl(ND); 908dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 909dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 9101ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { 9111ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin(); 9121ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), 9131ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor E = PID->protocol_end(); I != E; ++I, ++PL) 9141ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 9151ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 916f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 9171ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCContainerDecl(PID); 9181ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 9191ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 92023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenekbool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) { 92183cb94269015bf2770ade71e616c5322ea7e76e1Douglas Gregor if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc())) 922fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall return true; 923fc929208193eff37e1d3a28b1ea3bd1c9a7913e0John McCall 92423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // FIXME: This implements a workaround with @property declarations also being 92523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // installed in the DeclContext for the @interface. Eventually this code 92623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // should be removed. 92723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext()); 92823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (!CDecl || !CDecl->IsClassExtension()) 92923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 93023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 93123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCInterfaceDecl *ID = CDecl->getClassInterface(); 93223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (!ID) 93323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 93423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 93523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek IdentifierInfo *PropertyId = PD->getIdentifier(); 93623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCPropertyDecl *prevDecl = 93723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId); 93823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 93923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (!prevDecl) 94023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 94123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 94223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // Visit synthesized methods since they will be skipped when visiting 94323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // the @interface. 94423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl()) 945a054fb46b1fb596d1719b89d2d9a5be3c32a4b0dTed Kremenek if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl) 94623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (Visit(MakeCXCursor(MD, TU))) 94723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return true; 94823173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 94923173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl()) 950a054fb46b1fb596d1719b89d2d9a5be3c32a4b0dTed Kremenek if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl) 95123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (Visit(MakeCXCursor(MD, TU))) 95223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return true; 95323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 95423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return false; 95523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek} 95623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek 957b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregorbool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { 958dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek // Issue callbacks for super class. 959b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor if (D->getSuperClass() && 960b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), 961f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek D->getSuperClassLoc(), 962b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor TU))) 963b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 964f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 96578db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); 96678db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), 96778db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor E = D->protocol_end(); I != E; ++I, ++PL) 968b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 969b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 970f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 971a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return VisitObjCContainerDecl(D); 972dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 973dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 9741ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) { 9751ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCContainerDecl(D); 9761ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 9771ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 9781ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { 979ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek // 'ID' could be null when dealing with invalid code. 980ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek if (ObjCInterfaceDecl *ID = D->getClassInterface()) 981ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU))) 982ebfa339321f8a4df9d5011e591a615d5765107d5Ted Kremenek return true; 983f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 9841ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCImplDecl(D); 9851ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor} 9861ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor 9871ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { 9881ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor#if 0 9891ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor // Issue callbacks for super class. 9901ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor // FIXME: No source location information! 9911ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (D->getSuperClass() && 9921ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), 993f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek D->getSuperClassLoc(), 9941ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor TU))) 995a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return true; 9961ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor#endif 997f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 9981ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return VisitObjCImplDecl(D); 999dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 1000dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 10011ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { 10021ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); 10031ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(), 10041ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor E = D->protocol_end(); 10051ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor I != E; ++I, ++PL) 1006b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 1007b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return true; 1008f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1009f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return false; 1010dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 1011dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek 10121ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregorbool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) { 10131ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C) 10141ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU))) 10151ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return true; 1016f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 10171ef2fc1888d8d14e97ebe561ccbd421282de3ce2Douglas Gregor return false; 1018dd6bcc5f79666b9298d91a0a6ee7a0b537bde601Ted Kremenek} 10195e4bc590b0ea010e38372d0b4a0aab578a746fe6Benjamin Kramer 10208f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenekbool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) { 10218f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek return VisitDeclContext(D); 10228f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek} 10238f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek 10246931900f43cea558c6974075256c07728dbfecc6Douglas Gregorbool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { 1025c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1026c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = D->getQualifier()) 1027c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, D->getQualifierRange())) 1028c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 10296931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 10306931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(), 10316931900f43cea558c6974075256c07728dbfecc6Douglas Gregor D->getTargetNameLoc(), TU)); 10326931900f43cea558c6974075256c07728dbfecc6Douglas Gregor} 10336931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 10347e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUsingDecl(UsingDecl *D) { 1035c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1036c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameDecl()) 1037c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, D->getNestedNameRange())) 1038c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 10397e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 10401f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU))) 10411f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return true; 10421f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 10437e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return VisitDeclarationNameInfo(D->getNameInfo()); 10447e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor} 10457e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 10460a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregorbool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { 1047c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1048c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = D->getQualifier()) 1049c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, D->getQualifierRange())) 1050c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 10510a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 10520a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(), 10530a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor D->getIdentLocation(), TU)); 10540a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor} 10550a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 10567e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { 1057c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1058c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier()) 1059c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange())) 1060c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 1061c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 10627e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return VisitDeclarationNameInfo(D->getNameInfo()); 10637e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor} 10647e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 10657e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregorbool CursorVisitor::VisitUnresolvedUsingTypenameDecl( 10667e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor UnresolvedUsingTypenameDecl *D) { 1067c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Visit nested-name-specifier. 1068c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (NestedNameSpecifier *Qualifier = D->getTargetNestedNameSpecifier()) 1069c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, D->getTargetNestedNameRange())) 1070c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return true; 1071c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 10727e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return false; 10737e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor} 10747e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor 107501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) { 107601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor switch (Name.getName().getNameKind()) { 107701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::Identifier: 107801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXLiteralOperatorName: 107901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXOperatorName: 108001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXUsingDirective: 108101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 108201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 108301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXConstructorName: 108401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXDestructorName: 108501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::CXXConversionFunctionName: 108601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo()) 108701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return Visit(TSInfo->getTypeLoc()); 108801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 108901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 109001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::ObjCZeroArgSelector: 109101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::ObjCOneArgSelector: 109201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case clang::DeclarationName::ObjCMultiArgSelector: 109301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor // FIXME: Per-identifier location info? 109401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 109501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor } 109601829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 109701829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return false; 109801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor} 109901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 1100c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregorbool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS, 1101c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor SourceRange Range) { 1102c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // FIXME: This whole routine is a hack to work around the lack of proper 1103c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // source information in nested-name-specifiers (PR5791). Since we do have 1104c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // a beginning source location, we can visit the first component of the 1105c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // nested-name-specifier, if it's a single-token component. 1106c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (!NNS) 1107c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return false; 1108c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1109c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // Get the first component in the nested-name-specifier. 1110c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor while (NestedNameSpecifier *Prefix = NNS->getPrefix()) 1111c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor NNS = Prefix; 1112c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1113c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor switch (NNS->getKind()) { 1114c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::Namespace: 1115c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // FIXME: The token at this source location might actually have been a 1116c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // namespace alias, but we don't model that. Lame! 1117c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), 1118c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor TU)); 1119c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1120c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::TypeSpec: { 1121c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // If the type has a form where we know that the beginning of the source 1122c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // range matches up with a reference cursor. Visit the appropriate reference 1123c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor // cursor. 1124c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor Type *T = NNS->getAsType(); 1125c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (const TypedefType *Typedef = dyn_cast<TypedefType>(T)) 1126c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU)); 1127c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (const TagType *Tag = dyn_cast<TagType>(T)) 1128c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU)); 1129c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor if (const TemplateSpecializationType *TST 1130c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor = dyn_cast<TemplateSpecializationType>(T)) 1131c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return VisitTemplateName(TST->getTemplateName(), Range.getBegin()); 1132c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor break; 1133c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor } 1134c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1135c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::TypeSpecWithTemplate: 1136c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::Global: 1137c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor case NestedNameSpecifier::Identifier: 1138c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor break; 1139c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor } 1140c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1141c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor return false; 1142c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor} 1143c5ade2e3644a5822df63e442788d68c591ccdc97Douglas Gregor 1144fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateParameters( 1145fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor const TemplateParameterList *Params) { 1146fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (!Params) 1147fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1148fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1149fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor for (TemplateParameterList::const_iterator P = Params->begin(), 1150fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor PEnd = Params->end(); 1151fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor P != PEnd; ++P) { 1152fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (Visit(MakeCXCursor(*P, TU))) 1153fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return true; 1154fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor } 1155fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1156fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1157fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1158fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 11590b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregorbool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) { 11600b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor switch (Name.getKind()) { 11610b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::Template: 11620b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU)); 11630b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 11640b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::OverloadedTemplate: 11651f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor // Visit the overloaded template set. 11661f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU))) 11671f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return true; 11681f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 11690b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return false; 11700b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 11710b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::DependentTemplate: 11720b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // FIXME: Visit nested-name-specifier. 11730b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return false; 11740b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 11750b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case TemplateName::QualifiedTemplate: 11760b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // FIXME: Visit nested-name-specifier. 11770b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return Visit(MakeCursorTemplateRef( 11780b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor Name.getAsQualifiedTemplateName()->getDecl(), 11790b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor Loc, TU)); 11800b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor } 11810b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 11820b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return false; 11830b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor} 11840b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 1185fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) { 1186fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor switch (TAL.getArgument().getKind()) { 1187fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Null: 1188fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Integral: 1189fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1190fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1191fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Pack: 1192fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // FIXME: Implement when variadic templates come along. 1193fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1194fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1195fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Type: 1196fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo()) 1197fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return Visit(TSInfo->getTypeLoc()); 1198fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1199fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1200fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Declaration: 1201fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (Expr *E = TAL.getSourceDeclExpression()) 1202fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return Visit(MakeCXCursor(E, StmtParent, TU)); 1203fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1204fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1205fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Expression: 1206fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (Expr *E = TAL.getSourceExpression()) 1207fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return Visit(MakeCXCursor(E, StmtParent, TU)); 1208fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1209fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1210fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case TemplateArgument::Template: 12110b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return VisitTemplateName(TAL.getArgument().getAsTemplate(), 12120b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor TAL.getTemplateNameLoc()); 1213fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor } 1214fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1215fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1216fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1217fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1218a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenekbool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) { 1219a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek return VisitDeclContext(D); 1220a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek} 1221a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek 122201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { 122301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return Visit(TL.getUnqualifiedLoc()); 122401829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor} 122501829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor 1226f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { 1227f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor ASTContext &Context = TU->getASTContext(); 1228f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1229f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor // Some builtin types (such as Objective-C's "id", "sel", and 1230f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor // "Class") have associated declarations. Create cursors for those. 1231f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor QualType VisitType; 1232f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor switch (TL.getType()->getAs<BuiltinType>()->getKind()) { 12336b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Void: 1234f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Bool: 12356b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Char_U: 12366b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UChar: 1237f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Char16: 1238f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Char32: 12396b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UShort: 12406b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UInt: 12416b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::ULong: 12426b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::ULongLong: 12436b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UInt128: 1244f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Char_S: 12456b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::SChar: 12466b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::WChar: 12476b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Short: 1248f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Int: 1249f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Long: 1250c4174cc4b9b657abb77d0825de473ea29cf48297Ted Kremenek case BuiltinType::LongLong: 12516b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Int128: 12526b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Float: 12536b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Double: 12546b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::LongDouble: 1255f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::NullPtr: 1256f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::Overload: 12576b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::Dependent: 1258f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor break; 12596b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek 12606b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::UndeducedAuto: // FIXME: Deserves a cursor? 1261f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor break; 12626b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek 1263f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::ObjCId: 1264f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor VisitType = Context.getObjCIdType(); 1265f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor break; 12666b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek 12676b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek case BuiltinType::ObjCClass: 12686b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek VisitType = Context.getObjCClassType(); 12696b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek break; 12706b3b514e312b4caa403bbffe5673aa31cfbad051Ted Kremenek 1271f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor case BuiltinType::ObjCSel: 1272f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor VisitType = Context.getObjCSelType(); 1273f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor break; 1274f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor } 1275f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1276f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (!VisitType.isNull()) { 1277f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (const TypedefType *Typedef = VisitType->getAs<TypedefType>()) 1278f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), 1279f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor TU)); 1280f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor } 1281f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1282f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1283f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1284f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 12857d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregorbool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) { 12867d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU)); 12877d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor} 12887d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 1289f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { 1290f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 1291f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1292f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1293f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) { 1294f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 1295f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1296f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1297fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { 12981f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor // FIXME: We can't visit the template type parameter, because there's 1299fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // no context information with which we can match up the depth/index in the 1300fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // type to the appropriate 1301fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1302fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1303fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1304f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { 1305f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU))) 1306f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1307f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1308c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall return false; 1309c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall} 1310c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall 1311c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCallbool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { 1312c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc())) 1313c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall return true; 1314c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall 1315f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { 1316f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I), 1317f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor TU))) 1318f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1319f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor } 1320f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1321f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1322f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1323f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1324f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { 1325c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall return Visit(TL.getPointeeLoc()); 1326f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1327f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1328f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) { 1329f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(TL.getPointeeLoc()); 1330f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1331f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1332f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { 1333f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(TL.getPointeeLoc()); 1334f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1335f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1336f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { 1337f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(TL.getPointeeLoc()); 1338f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1339f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1340f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { 1341f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return Visit(TL.getPointeeLoc()); 1342f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1343f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1344f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { 1345f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return Visit(TL.getPointeeLoc()); 1346f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1347f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 134801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregorbool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL, 134901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor bool SkipResultType) { 135001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor if (!SkipResultType && Visit(TL.getResultLoc())) 1351f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1352f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1353f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 13545dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek if (Decl *D = TL.getArg(I)) 13555dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek if (Visit(MakeCXCursor(D, TU))) 13565dbacb4179c759eef36bcaa6466b91518e3b98a9Ted Kremenek return true; 1357f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1358f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1359f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1360f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1361f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregorbool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) { 1362f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Visit(TL.getElementLoc())) 1363f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return true; 1364f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1365f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor if (Expr *Size = TL.getSizeExpr()) 1366f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return Visit(MakeCXCursor(Size, StmtParent, TU)); 1367f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1368f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor return false; 1369f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor} 1370f20dfbcdaaf96757ea67c94376bdca0bd64db02cDouglas Gregor 1371fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregorbool CursorVisitor::VisitTemplateSpecializationTypeLoc( 1372fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor TemplateSpecializationTypeLoc TL) { 13730b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor // Visit the template name. 13740b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor if (VisitTemplateName(TL.getTypePtr()->getTemplateName(), 13750b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor TL.getTemplateNameLoc())) 13760b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return true; 1377fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1378fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor // Visit the template arguments. 1379fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 1380fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor if (VisitTemplateArgumentLoc(TL.getArgLoc(I))) 1381fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return true; 1382fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 1383fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return false; 1384fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor} 1385fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor 13862332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregorbool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { 13872332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU)); 13882332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor} 13892332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor 13902332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregorbool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { 13912332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo()) 13922332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor return Visit(TSInfo->getTypeLoc()); 13932332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor 13942332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor return false; 13952332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor} 13962332c117b1ab498322eb99c238630f28c32c7b14Douglas Gregor 1397a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregorbool CursorVisitor::VisitStmt(Stmt *S) { 1398a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end(); 1399a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor Child != ChildEnd; ++Child) { 14000f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (Stmt *C = *Child) 14010f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (Visit(MakeCXCursor(C, StmtParent, TU))) 14020f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek return true; 1403a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor } 1404f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1405a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return false; 1406a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor} 1407a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor 14080f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenekbool CursorVisitor::VisitCaseStmt(CaseStmt *S) { 14090f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek // Specially handle CaseStmts because they can be nested, e.g.: 14100f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek // 14110f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek // case 1: 14120f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek // case 2: 14130f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek // 14140f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek // In this case the second CaseStmt is the child of the first. Walking 14150f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek // these recursively can blow out the stack. 14160f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek CXCursor Cursor = MakeCXCursor(S, StmtParent, TU); 14170f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek while (true) { 14180f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek // Set the Parent field to Cursor, then back to its old value once we're 14190f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek // done. 14200f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek SetParentRAII SetParent(Parent, StmtParent, Cursor); 14210f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 14220f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (Stmt *LHS = S->getLHS()) 14230f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (Visit(MakeCXCursor(LHS, StmtParent, TU))) 14240f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek return true; 14250f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (Stmt *RHS = S->getRHS()) 14260f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (Visit(MakeCXCursor(RHS, StmtParent, TU))) 14270f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek return true; 14280f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (Stmt *SubStmt = S->getSubStmt()) { 14290f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (!isa<CaseStmt>(SubStmt)) 14300f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek return Visit(MakeCXCursor(SubStmt, StmtParent, TU)); 14310f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 14320f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek // Specially handle 'CaseStmt' so that we don't blow out the stack. 14330f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek CaseStmt *CS = cast<CaseStmt>(SubStmt); 14340f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek Cursor = MakeCXCursor(CS, StmtParent, TU); 14350f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (RegionOfInterest.isValid()) { 14360f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek SourceRange Range = CS->getSourceRange(); 14370f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek if (Range.isInvalid() || CompareRegionOfInterest(Range)) 14380f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek return false; 14390f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek } 14400f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 14410f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek switch (Visitor(Cursor, Parent, ClientData)) { 14420f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek case CXChildVisit_Break: return true; 14430f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek case CXChildVisit_Continue: return false; 14440f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek case CXChildVisit_Recurse: 14450f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek // Perform tail-recursion manually. 14460f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek S = CS; 14470f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek continue; 14480f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek } 14490f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek } 14500f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek return false; 14510f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek } 14520f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek} 14530f91f6a2eacf29fb69b1b0c3131eb0385aad5777Ted Kremenek 1454a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregorbool CursorVisitor::VisitDeclStmt(DeclStmt *S) { 1455007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek bool isFirst = true; 1456a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); 1457a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor D != DEnd; ++D) { 1458007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (*D && Visit(MakeCXCursor(*D, TU, isFirst))) 1459a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return true; 1460007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek isFirst = false; 1461a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor } 1462f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1463a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor return false; 1464a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor} 1465a59e390ed6d722f0eaaa9f7eb106eaaf470df3f1Douglas Gregor 146636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregorbool CursorVisitor::VisitGotoStmt(GotoStmt *S) { 146736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return Visit(MakeCursorLabelRef(S->getLabel(), S->getLabelLoc(), TU)); 146836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor} 146936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 1470f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregorbool CursorVisitor::VisitIfStmt(IfStmt *S) { 1471f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor if (VarDecl *Var = S->getConditionVariable()) { 1472f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor if (Visit(MakeCXCursor(Var, TU))) 1473f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor return true; 1474f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek } 1475f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1476263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) 1477263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor return true; 1478f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor if (S->getThen() && Visit(MakeCXCursor(S->getThen(), StmtParent, TU))) 1479f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor return true; 1480f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor if (S->getElse() && Visit(MakeCXCursor(S->getElse(), StmtParent, TU))) 1481f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor return true; 1482f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor 1483f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor return false; 1484f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor} 1485f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor 1486f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregorbool CursorVisitor::VisitSwitchStmt(SwitchStmt *S) { 1487f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor if (VarDecl *Var = S->getConditionVariable()) { 1488f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor if (Visit(MakeCXCursor(Var, TU))) 1489f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor return true; 1490f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek } 1491f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1492263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) 1493f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor return true; 1494263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) 1495263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor return true; 1496f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1497263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor return false; 1498263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor} 1499f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor 1500263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregorbool CursorVisitor::VisitWhileStmt(WhileStmt *S) { 1501263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (VarDecl *Var = S->getConditionVariable()) { 1502263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (Visit(MakeCXCursor(Var, TU))) 1503263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor return true; 1504f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek } 1505f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1506263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) 1507263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor return true; 1508263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) 1509263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor return true; 1510263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor 1511263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor return false; 1512263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor} 1513263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor 1514263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregorbool CursorVisitor::VisitForStmt(ForStmt *S) { 1515263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (S->getInit() && Visit(MakeCXCursor(S->getInit(), StmtParent, TU))) 1516263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor return true; 1517263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (VarDecl *Var = S->getConditionVariable()) { 1518263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (Visit(MakeCXCursor(Var, TU))) 1519263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor return true; 1520f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek } 1521f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1522263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) 1523263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor return true; 1524263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor if (S->getInc() && Visit(MakeCXCursor(S->getInc(), StmtParent, TU))) 1525263b47b6272bfd3ea1c0e61b7ac404e7b2e0f759Douglas Gregor return true; 1526f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) 1527f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor return true; 1528f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1529f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor return false; 1530f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor} 1531f5bab418aeba427a2f6b8f3e9ce77cbc4a7afa95Douglas Gregor 15328947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregorbool CursorVisitor::VisitDeclRefExpr(DeclRefExpr *E) { 15338947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor // Visit nested-name-specifier, if present. 15348947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor if (NestedNameSpecifier *Qualifier = E->getQualifier()) 15358947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) 15368947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor return true; 15378947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor 15388947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor // Visit declaration name. 15398947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor if (VisitDeclarationNameInfo(E->getNameInfo())) 15408947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor return true; 15418947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor 15428947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor // Visit explicitly-specified template arguments. 15438947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor if (E->hasExplicitTemplateArgs()) { 15448947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs(); 15458947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor for (TemplateArgumentLoc *Arg = Args.getTemplateArgs(), 15468947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor *ArgEnd = Arg + Args.NumTemplateArgs; 15478947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor Arg != ArgEnd; ++Arg) 15488947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor if (VisitTemplateArgumentLoc(*Arg)) 15498947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor return true; 15508947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor } 15518947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor 15528947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor return false; 15538947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor} 15548947a7501ee34577a020591d32f701e4b0656cb7Douglas Gregor 15556cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregorbool CursorVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { 15566cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor if (Visit(MakeCXCursor(E->getArg(0), StmtParent, TU))) 15576cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor return true; 15586cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor 15596cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor if (Visit(MakeCXCursor(E->getCallee(), StmtParent, TU))) 15606cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor return true; 15616cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor 15626cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor for (unsigned I = 1, N = E->getNumArgs(); I != N; ++I) 15636cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor if (Visit(MakeCXCursor(E->getArg(I), StmtParent, TU))) 15646cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor return true; 15656cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor 15666cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor return false; 15676cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor} 15686cd24e28811a2000a8d99604dd64a77c58245d4cDouglas Gregor 15693064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenekbool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) { 15703064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek if (D->isDefinition()) { 15713064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), 15723064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek E = D->bases_end(); I != E; ++I) { 15733064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU))) 15743064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return true; 15753064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 15763064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 15773064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek 15783064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return VisitTagDecl(D); 15793064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek} 15803064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek 15813064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek 15821ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenekbool CursorVisitor::VisitBlockExpr(BlockExpr *B) { 15831ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek return Visit(B->getBlockDecl()); 15841ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek} 15851ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek 15868ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregorbool CursorVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) { 15878ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor // Visit the type into which we're computing an offset. 15888ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (Visit(E->getTypeSourceInfo()->getTypeLoc())) 15898ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor return true; 15908ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor 15918ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor // Visit the components of the offsetof expression. 15928ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) { 15938ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor typedef OffsetOfExpr::OffsetOfNode OffsetOfNode; 15948ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor const OffsetOfNode &Node = E->getComponent(I); 15958ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor switch (Node.getKind()) { 15968ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor case OffsetOfNode::Array: 15978ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor if (Visit(MakeCXCursor(E->getIndexExpr(Node.getArrayExprIndex()), 15988ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor StmtParent, TU))) 15998ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor return true; 16008ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor break; 16018ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor 16028ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor case OffsetOfNode::Field: 16038ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor if (Visit(MakeCursorMemberRef(Node.getField(), Node.getRange().getEnd(), 16048ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor TU))) 16058ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor return true; 16068ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor break; 16078ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor 16088ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor case OffsetOfNode::Identifier: 16098ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor case OffsetOfNode::Base: 16108ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor continue; 16118ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor } 16128ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor } 16138ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 16148ccef2d0322ebf2701cc10f1ab14c9ee49e17bd7Douglas Gregor return false; 16158ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor} 16168ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 1617336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregorbool CursorVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { 1618336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor if (E->isArgumentType()) { 1619336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor if (TypeSourceInfo *TSInfo = E->getArgumentTypeInfo()) 1620336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return Visit(TSInfo->getTypeLoc()); 1621f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1622336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return false; 1623336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor } 1624f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1625336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return VisitExpr(E); 1626336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor} 1627336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor 1628fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregorbool CursorVisitor::VisitMemberExpr(MemberExpr *E) { 1629fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor // Visit the base expression. 1630fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor if (Visit(MakeCXCursor(E->getBase(), StmtParent, TU))) 1631fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor return true; 1632fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor 1633fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor // Visit the nested-name-specifier 1634fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor if (NestedNameSpecifier *Qualifier = E->getQualifier()) 1635fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) 1636fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor return true; 1637fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor 1638fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor // Visit the declaration name. 1639fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor if (VisitDeclarationNameInfo(E->getMemberNameInfo())) 1640fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor return true; 1641fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor 1642fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor // Visit the explicitly-specified template arguments, if any. 1643fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor if (E->hasExplicitTemplateArgs()) { 1644fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor for (const TemplateArgumentLoc *Arg = E->getTemplateArgs(), 1645fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor *ArgEnd = Arg + E->getNumTemplateArgs(); 1646fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor Arg != ArgEnd; 1647fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor ++Arg) { 1648fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor if (VisitTemplateArgumentLoc(*Arg)) 1649fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor return true; 1650fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor } 1651fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor } 1652fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor 1653fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor return false; 1654fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor} 1655fbb4c98a248c54d31063aa41dbfacf4f78c93f10Douglas Gregor 1656336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregorbool CursorVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) { 1657336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeInfoAsWritten()) 1658336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 1659336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return true; 1660f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1661336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return VisitCastExpr(E); 1662336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor} 1663336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor 1664336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregorbool CursorVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 1665336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) 1666336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 1667336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return true; 1668f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 1669336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor return VisitExpr(E); 1670336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor} 1671336fd81e04c01ffbce2825b372aeb127c80d4d97Douglas Gregor 167236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregorbool CursorVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) { 167336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return Visit(MakeCursorLabelRef(E->getLabel(), E->getLabelLoc(), TU)); 167436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor} 167536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 1676648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregorbool CursorVisitor::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) { 1677648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor return Visit(E->getArgTInfo1()->getTypeLoc()) || 1678648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor Visit(E->getArgTInfo2()->getTypeLoc()); 1679648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor} 1680648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor 1681648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregorbool CursorVisitor::VisitVAArgExpr(VAArgExpr *E) { 1682648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor if (Visit(E->getWrittenTypeInfo()->getTypeLoc())) 1683648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor return true; 1684648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor 1685648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor return Visit(MakeCXCursor(E->getSubExpr(), StmtParent, TU)); 1686648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor} 1687648220ed00711a0fb8ea4a1ab6896a4ee63d8fc5Douglas Gregor 1688fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregorbool CursorVisitor::VisitInitListExpr(InitListExpr *E) { 1689fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor // We care about the syntactic form of the initializer list, only. 1690692577cd3005922d9657a85c92e3fd68b50ddea1Douglas Gregor if (InitListExpr *Syntactic = E->getSyntacticForm()) 1691692577cd3005922d9657a85c92e3fd68b50ddea1Douglas Gregor return VisitExpr(Syntactic); 1692692577cd3005922d9657a85c92e3fd68b50ddea1Douglas Gregor 1693692577cd3005922d9657a85c92e3fd68b50ddea1Douglas Gregor return VisitExpr(E); 1694fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor} 1695fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1696fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregorbool CursorVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) { 1697fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor // Visit the designators. 1698fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor typedef DesignatedInitExpr::Designator Designator; 1699fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor for (DesignatedInitExpr::designators_iterator D = E->designators_begin(), 1700fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor DEnd = E->designators_end(); 1701fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor D != DEnd; ++D) { 1702fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (D->isFieldDesignator()) { 1703fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (FieldDecl *Field = D->getField()) 1704fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (Visit(MakeCursorMemberRef(Field, D->getFieldLoc(), TU))) 1705fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor return true; 1706fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1707fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor continue; 1708fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor } 1709fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1710fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (D->isArrayDesignator()) { 1711fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (Visit(MakeCXCursor(E->getArrayIndex(*D), StmtParent, TU))) 1712fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor return true; 1713fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1714fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor continue; 1715fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor } 1716fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1717fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor assert(D->isArrayRangeDesignator() && "Unknown designator kind"); 1718fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor if (Visit(MakeCXCursor(E->getArrayRangeStart(*D), StmtParent, TU)) || 1719fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor Visit(MakeCXCursor(E->getArrayRangeEnd(*D), StmtParent, TU))) 1720fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor return true; 1721fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor } 1722fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1723fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor // Visit the initializer value itself. 1724fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor return Visit(MakeCXCursor(E->getInit(), StmtParent, TU)); 1725fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor} 1726fa2e26f62162d90a3d117e58d6b1f47e40377987Douglas Gregor 1727948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregorbool CursorVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) { 1728948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor if (E->isTypeOperand()) { 1729948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeOperandSourceInfo()) 1730948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor return Visit(TSInfo->getTypeLoc()); 1731948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor 1732948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor return false; 1733948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor } 1734948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor 1735948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor return VisitExpr(E); 1736948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor} 1737948022908d0c16acc3411fdec15aeb1790ffaa86Douglas Gregor 17383d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregorbool CursorVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) { 17393d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor if (E->isTypeOperand()) { 17403d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeOperandSourceInfo()) 17413d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor return Visit(TSInfo->getTypeLoc()); 17423d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor 17433d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor return false; 17443d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor } 17453d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor 17463d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor return VisitExpr(E); 17473d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor} 17483d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor 1749ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregorbool CursorVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { 1750ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) 1751ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor return Visit(TSInfo->getTypeLoc()); 1752ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 1753ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor return VisitExpr(E); 1754ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor} 1755ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 1756ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregorbool CursorVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { 1757ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) 1758ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor return Visit(TSInfo->getTypeLoc()); 1759ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 1760ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor return false; 1761ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor} 1762ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 17631bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregorbool CursorVisitor::VisitCXXNewExpr(CXXNewExpr *E) { 17641bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor // Visit placement arguments. 17651bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) 17661bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor if (Visit(MakeCXCursor(E->getPlacementArg(I), StmtParent, TU))) 17671bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor return true; 17681bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor 17691bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor // Visit the allocated type. 17701bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor if (TypeSourceInfo *TSInfo = E->getAllocatedTypeSourceInfo()) 17711bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 17721bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor return true; 17731bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor 17741bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor // Visit the array size, if any. 17751bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor if (E->isArray() && Visit(MakeCXCursor(E->getArraySize(), StmtParent, TU))) 17761bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor return true; 17771bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor 17781bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor // Visit the initializer or constructor arguments. 17791bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) 17801bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor if (Visit(MakeCXCursor(E->getConstructorArg(I), StmtParent, TU))) 17811bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor return true; 17821bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor 17831bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor return false; 17841bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor} 17851bb2a93ab7b1499dda6f6b58865bd0dce1864228Douglas Gregor 17866f7198f6380581645f416dd48a0079f83d89e884Douglas Gregorbool CursorVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 17876f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor // Visit base expression. 17886f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (Visit(MakeCXCursor(E->getBase(), StmtParent, TU))) 17896f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor return true; 17906f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor 17916f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor // Visit the nested-name-specifier. 17926f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (NestedNameSpecifier *Qualifier = E->getQualifier()) 17936f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) 17946f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor return true; 17956f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor 17966f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor // Visit the scope type that looks disturbingly like the nested-name-specifier 17976f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor // but isn't. 17986f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (TypeSourceInfo *TSInfo = E->getScopeTypeInfo()) 17996f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 18006f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor return true; 18016f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor 18026f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor // Visit the name of the type being destroyed. 18036f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (TypeSourceInfo *TSInfo = E->getDestroyedTypeInfo()) 18046f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 18056f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor return true; 18066f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor 18076f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor return false; 18086f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor} 18096f7198f6380581645f416dd48a0079f83d89e884Douglas Gregor 18103d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregorbool CursorVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { 18113d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor return Visit(E->getQueriedTypeSourceInfo()->getTypeLoc()); 18123d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor} 18133d37c0ada0e46b87be0a10e8d52d990a97d3907aDouglas Gregor 18141f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregorbool CursorVisitor::VisitOverloadExpr(OverloadExpr *E) { 18158ab670ee2b8147da63d1f282d928e754e4e97408Douglas Gregor // Visit the nested-name-specifier. 18168ab670ee2b8147da63d1f282d928e754e4e97408Douglas Gregor if (NestedNameSpecifier *Qualifier = E->getQualifier()) 18178ab670ee2b8147da63d1f282d928e754e4e97408Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) 18188ab670ee2b8147da63d1f282d928e754e4e97408Douglas Gregor return true; 18198ab670ee2b8147da63d1f282d928e754e4e97408Douglas Gregor 18208ab670ee2b8147da63d1f282d928e754e4e97408Douglas Gregor // Visit the declaration name. 18218ab670ee2b8147da63d1f282d928e754e4e97408Douglas Gregor if (VisitDeclarationNameInfo(E->getNameInfo())) 18228ab670ee2b8147da63d1f282d928e754e4e97408Douglas Gregor return true; 18231f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 18241f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor // Visit the overloaded declaration reference. 18251f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Visit(MakeCursorOverloadedDeclRef(E, TU))) 18261f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return true; 18271f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 18281f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor // Visit the explicitly-specified template arguments. 18291f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor if (const ExplicitTemplateArgumentList *ArgList 18301f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor = E->getOptionalExplicitTemplateArgs()) { 18311f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(), 18321f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor *ArgEnd = Arg + ArgList->NumTemplateArgs; 18331f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor Arg != ArgEnd; ++Arg) { 18341f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor if (VisitTemplateArgumentLoc(*Arg)) 18351f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor return true; 18361f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor } 18371f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor } 18381f7b590d120758d0c969a8153c38d2446935d4aaDouglas Gregor 18398ab670ee2b8147da63d1f282d928e754e4e97408Douglas Gregor return false; 18408ab670ee2b8147da63d1f282d928e754e4e97408Douglas Gregor} 18418ab670ee2b8147da63d1f282d928e754e4e97408Douglas Gregor 1842bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregorbool CursorVisitor::VisitDependentScopeDeclRefExpr( 1843bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor DependentScopeDeclRefExpr *E) { 1844bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor // Visit the nested-name-specifier. 1845bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor if (NestedNameSpecifier *Qualifier = E->getQualifier()) 1846bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) 1847bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor return true; 1848bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor 1849bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor // Visit the declaration name. 1850bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor if (VisitDeclarationNameInfo(E->getNameInfo())) 1851bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor return true; 1852bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor 1853bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor // Visit the explicitly-specified template arguments. 1854bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor if (const ExplicitTemplateArgumentList *ArgList 1855bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor = E->getOptionalExplicitTemplateArgs()) { 1856bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(), 1857bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor *ArgEnd = Arg + ArgList->NumTemplateArgs; 1858bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor Arg != ArgEnd; ++Arg) { 1859bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor if (VisitTemplateArgumentLoc(*Arg)) 1860bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor return true; 1861bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor } 1862bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor } 1863bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor 1864bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor return false; 1865bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor} 1866bfebed2a839e12c3e99d635dbd1f4f875ce8b066Douglas Gregor 1867ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregorbool CursorVisitor::VisitCXXUnresolvedConstructExpr( 1868ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor CXXUnresolvedConstructExpr *E) { 1869ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) 1870ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 1871ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor return true; 1872ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 1873ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor return VisitExpr(E); 1874ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor} 1875ab6677ec401cfd2c82b34e4cdfebd55a9dc25778Douglas Gregor 187625d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregorbool CursorVisitor::VisitCXXDependentScopeMemberExpr( 187725d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor CXXDependentScopeMemberExpr *E) { 187825d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor // Visit the base expression, if there is one. 187925d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (!E->isImplicitAccess() && 188025d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor Visit(MakeCXCursor(E->getBase(), StmtParent, TU))) 188125d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor return true; 188225d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor 188325d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor // Visit the nested-name-specifier. 188425d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (NestedNameSpecifier *Qualifier = E->getQualifier()) 188525d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (VisitNestedNameSpecifier(Qualifier, E->getQualifierRange())) 188625d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor return true; 188725d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor 188825d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor // Visit the declaration name. 188925d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (VisitDeclarationNameInfo(E->getMemberNameInfo())) 189025d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor return true; 189125d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor 189225d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor // Visit the explicitly-specified template arguments. 189325d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (const ExplicitTemplateArgumentList *ArgList 189425d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor = E->getOptionalExplicitTemplateArgs()) { 189525d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(), 189625d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor *ArgEnd = Arg + ArgList->NumTemplateArgs; 189725d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor Arg != ArgEnd; ++Arg) { 189825d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor if (VisitTemplateArgumentLoc(*Arg)) 189925d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor return true; 190025d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor } 190125d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor } 190225d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor 190325d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor return false; 190425d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor} 190525d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor 1906aaa80b208de3e2c706badf45060bd126fa747b84Douglas Gregorbool CursorVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { 1907aaa80b208de3e2c706badf45060bd126fa747b84Douglas Gregor // Visit the base expression, if there is one. 1908aaa80b208de3e2c706badf45060bd126fa747b84Douglas Gregor if (!E->isImplicitAccess() && 1909aaa80b208de3e2c706badf45060bd126fa747b84Douglas Gregor Visit(MakeCXCursor(E->getBase(), StmtParent, TU))) 1910aaa80b208de3e2c706badf45060bd126fa747b84Douglas Gregor return true; 1911aaa80b208de3e2c706badf45060bd126fa747b84Douglas Gregor 1912aaa80b208de3e2c706badf45060bd126fa747b84Douglas Gregor return VisitOverloadExpr(E); 1913aaa80b208de3e2c706badf45060bd126fa747b84Douglas Gregor} 191425d63629cc37a9737c6d8d5c6aa08b356649212fDouglas Gregor 1915c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregorbool CursorVisitor::VisitObjCMessageExpr(ObjCMessageExpr *E) { 191604badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor if (TypeSourceInfo *TSInfo = E->getClassReceiverTypeInfo()) 191704badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor if (Visit(TSInfo->getTypeLoc())) 191804badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor return true; 1919c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregor 1920c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregor return VisitExpr(E); 1921c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregor} 1922c2350e553b853ad00914faf23fa731e5fc4a8a5cDouglas Gregor 192381d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregorbool CursorVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { 192481d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor return Visit(E->getEncodedTypeSourceInfo()->getTypeLoc()); 192581d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor} 192681d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor 192781d3466d037dc5844234c7a93dab21a6ad986e7dDouglas Gregor 192809dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenekbool CursorVisitor::VisitAttributes(Decl *D) { 1929cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end(); 1930cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt i != e; ++i) 1931cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (Visit(MakeCXCursor(*i, D, TU))) 193209dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek return true; 193309dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek 193409dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek return false; 193509dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek} 193609dfa37dda8e430fb6129bfd70365a51b4e12243Ted Kremenek 19378c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregorstatic llvm::sys::Mutex EnableMultithreadingMutex; 19388c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregorstatic bool EnabledMultithreading; 19398c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor 19405e4bc590b0ea010e38372d0b4a0aab578a746fe6Benjamin Kramerextern "C" { 19410a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas GregorCXIndex clang_createIndex(int excludeDeclarationsFromPCH, 19420a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor int displayDiagnostics) { 194348615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar // Disable pretty stack trace functionality, which will otherwise be a very 194448615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar // poor citizen of the world and set up all sorts of signal handlers. 194548615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar llvm::DisablePrettyStackTrace = true; 194648615ffe41e41e0cc232dfb61289b707ece37ea1Daniel Dunbar 1947c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar // We use crash recovery to make some of our APIs more reliable, implicitly 1948c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar // enable it. 1949c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar llvm::CrashRecoveryContext::Enable(); 1950c7df4f344d78fe0d7591be3756712e777b3d2e8dDaniel Dunbar 19518c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor // Enable support for multithreading in LLVM. 19528c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor { 19538c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor llvm::sys::ScopedLock L(EnableMultithreadingMutex); 19548c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor if (!EnabledMultithreading) { 19558c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor llvm::llvm_start_multithreaded(); 19568c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor EnabledMultithreading = true; 19578c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor } 19588c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor } 19598c8d5412cddcc1c45beb0353d91d7894db74e585Douglas Gregor 1960a030b7cf5e6aad5889b1b662b6979840bc75f87fDouglas Gregor CIndexer *CIdxr = new CIndexer(); 1961e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff if (excludeDeclarationsFromPCH) 1962e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff CIdxr->setOnlyLocalDecls(); 19630a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor if (displayDiagnostics) 19640a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor CIdxr->setDisplayDiagnostics(); 1965e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff return CIdxr; 1966600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff} 1967600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff 19689ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarvoid clang_disposeIndex(CXIndex CIdx) { 19692b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (CIdx) 19702b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor delete static_cast<CIndexer *>(CIdx); 19712bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff} 19722bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff 19739ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXTranslationUnit clang_createTranslationUnit(CXIndex CIdx, 1974a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor const char *ast_filename) { 19752b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (!CIdx) 19762b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor return 0; 1977f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 19787d1d49d2971b20a97b3c2a301470b9eaaa130137Douglas Gregor CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); 19790d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 198028019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags; 19813c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl return ASTUnit::LoadFromASTFile(ast_filename, Diags, 1982a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor CXXIdx->getOnlyLocalDecls(), 1983a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor 0, 0, true); 1984600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff} 1985600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff 1986b1c031be513705d924038f497279b9b599868ba1Douglas Gregorunsigned clang_defaultEditingTranslationUnitOptions() { 19872a2c50b330e7754499f42173616a36865b5f313bDouglas Gregor return CXTranslationUnit_PrecompiledPreamble | 198899ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor CXTranslationUnit_CacheCompletionResults | 198999ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor CXTranslationUnit_CXXPrecompiledPreamble; 1990b1c031be513705d924038f497279b9b599868ba1Douglas Gregor} 1991b1c031be513705d924038f497279b9b599868ba1Douglas Gregor 19929ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXTranslationUnit 19939ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarclang_createTranslationUnitFromSourceFile(CXIndex CIdx, 19949ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar const char *source_filename, 19959ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar int num_command_line_args, 19962ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char * const *command_line_args, 19974db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor unsigned num_unsaved_files, 1998a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor struct CXUnsavedFile *unsaved_files) { 19995a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor return clang_parseTranslationUnit(CIdx, source_filename, 20005a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor command_line_args, num_command_line_args, 20015a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor unsaved_files, num_unsaved_files, 20025a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor CXTranslationUnit_DetailedPreprocessingRecord); 20035a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor} 200419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar 200519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbarstruct ParseTranslationUnitInfo { 200619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar CXIndex CIdx; 200719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar const char *source_filename; 20082ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char *const *command_line_args; 200919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar int num_command_line_args; 201019ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar struct CXUnsavedFile *unsaved_files; 201119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned num_unsaved_files; 201219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned options; 201319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar CXTranslationUnit result; 201419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar}; 2015b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarstatic void clang_parseTranslationUnit_Impl(void *UserData) { 201619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar ParseTranslationUnitInfo *PTUI = 201719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar static_cast<ParseTranslationUnitInfo*>(UserData); 201819ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar CXIndex CIdx = PTUI->CIdx; 201919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar const char *source_filename = PTUI->source_filename; 20202ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char * const *command_line_args = PTUI->command_line_args; 202119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar int num_command_line_args = PTUI->num_command_line_args; 202219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files; 202319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned num_unsaved_files = PTUI->num_unsaved_files; 202419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned options = PTUI->options; 202519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar PTUI->result = 0; 20265a43021ac491bf091494167127772a20d9a9bb48Douglas Gregor 20272b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (!CIdx) 202819ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar return; 2029f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2030e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); 2031e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff 203244c181aec37789f25f6c15543c164416f72e562aDouglas Gregor bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble; 2033df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor bool CompleteTranslationUnit 2034df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor = ((options & CXTranslationUnit_Incomplete) == 0); 203587c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor bool CacheCodeCompetionResults 203687c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor = options & CXTranslationUnit_CacheCompletionResults; 203799ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor bool CXXPrecompilePreamble 203899ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor = options & CXTranslationUnit_CXXPrecompiledPreamble; 203999ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor bool CXXChainedPCH 204099ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor = options & CXTranslationUnit_CXXChainedPCH; 204187c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor 20425352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor // Configure the diagnostics. 20435352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor DiagnosticOptions DiagOpts; 204428019772db70d4547be05a042eb950bc910f134fDouglas Gregor llvm::IntrusiveRefCntPtr<Diagnostic> Diags; 204528019772db70d4547be05a042eb950bc910f134fDouglas Gregor Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); 2046f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 20474db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; 20484db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor for (unsigned I = 0; I != num_unsaved_files; ++I) { 2049a0a270c0f1c0a4e3482438bdc5f4a7bd3d25f0a6Chris Lattner llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); 2050f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek const llvm::MemoryBuffer *Buffer 2051a0a270c0f1c0a4e3482438bdc5f4a7bd3d25f0a6Chris Lattner = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); 20524db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, 20534db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor Buffer)); 20544db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor } 2055f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2056b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor llvm::SmallVector<const char *, 16> Args; 20570d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 2058139ba86a362593da2e350f881e5c7003917aa5a7Ted Kremenek // The 'source_filename' argument is optional. If the caller does not 2059139ba86a362593da2e350f881e5c7003917aa5a7Ted Kremenek // specify it then it is assumed that the source file is specified 2060139ba86a362593da2e350f881e5c7003917aa5a7Ted Kremenek // in the actual argument list. 20610d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar if (source_filename) 2062b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Args.push_back(source_filename); 206352ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor 206452ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // Since the Clang C library is primarily used by batch tools dealing with 206552ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // (often very broken) source code, where spell-checking can have a 206652ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // significant negative impact on performance (particularly when 206752ddc5df59a26570fbca47d269f82954ae3397d1Douglas Gregor // precompiled headers are involved), we disable it by default. 2068b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // Only do this if we haven't found a spell-checking-related argument. 2069b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor bool FoundSpellCheckingArgument = false; 2070b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor for (int I = 0; I != num_command_line_args; ++I) { 2071b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 || 2072b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor strcmp(command_line_args[I], "-fspell-checking") == 0) { 2073b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor FoundSpellCheckingArgument = true; 2074b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor break; 2075e56b4baeba5097852e04bc41ca2e0396cf729955Steve Naroff } 2076b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor } 2077b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor if (!FoundSpellCheckingArgument) 2078b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Args.push_back("-fno-spell-checking"); 2079b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor 2080b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Args.insert(Args.end(), command_line_args, 2081b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor command_line_args + num_command_line_args); 2082d93256e55673a17d18543397ec462416acb13792Douglas Gregor 208344c181aec37789f25f6c15543c164416f72e562aDouglas Gregor // Do we need the detailed preprocessing record? 208444c181aec37789f25f6c15543c164416f72e562aDouglas Gregor if (options & CXTranslationUnit_DetailedPreprocessingRecord) { 2085b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Args.push_back("-Xclang"); 2086b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Args.push_back("-detailed-preprocessing-record"); 208744c181aec37789f25f6c15543c164416f72e562aDouglas Gregor } 208844c181aec37789f25f6c15543c164416f72e562aDouglas Gregor 2089b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor unsigned NumErrors = Diags->getNumErrors(); 2090b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor llvm::OwningPtr<ASTUnit> Unit( 2091b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(), 2092b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor Diags, 2093b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXXIdx->getClangResourcesPath(), 2094b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXXIdx->getOnlyLocalDecls(), 2095b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor RemappedFiles.data(), 2096b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor RemappedFiles.size(), 2097b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor /*CaptureDiagnostics=*/true, 2098b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor PrecompilePreamble, 2099b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CompleteTranslationUnit, 210099ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor CacheCodeCompetionResults, 210199ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor CXXPrecompilePreamble, 210299ba202f659e1885fa5ee114f97c97cf6a857491Douglas Gregor CXXChainedPCH)); 2103b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor 2104b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor if (NumErrors != Diags->getNumErrors()) { 2105b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // Make sure to check that 'Unit' is non-NULL. 2106b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor if (CXXIdx->getDisplayDiagnostics() && Unit.get()) { 2107b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), 2108b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor DEnd = Unit->stored_diag_end(); 2109b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor D != DEnd; ++D) { 2110b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions()); 2111b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor CXString Msg = clang_formatDiagnostic(&Diag, 2112b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor clang_defaultDiagnosticDisplayOptions()); 2113b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor fprintf(stderr, "%s\n", clang_getCString(Msg)); 2114b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor clang_disposeString(Msg); 2115b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor } 2116274f1906f12ebf8fcc179701deeda6d3271120c1Douglas Gregor#ifdef LLVM_ON_WIN32 2117b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // On Windows, force a flush, since there may be multiple copies of 2118b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // stderr and stdout in the file system, all with different buffers 2119b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor // but writing to the same device. 2120b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor fflush(stderr); 2121b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor#endif 2122b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor } 2123a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor } 2124d93256e55673a17d18543397ec462416acb13792Douglas Gregor 2125b10daedb8fc4c6f70a66dbc1a6eea01684bb4e77Douglas Gregor PTUI->result = Unit.take(); 212619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar} 212719ffd492a31a25fb691098bf79f317e5f3edf177Daniel DunbarCXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, 212819ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar const char *source_filename, 21292ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor const char * const *command_line_args, 213019ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar int num_command_line_args, 213119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar struct CXUnsavedFile *unsaved_files, 213219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned num_unsaved_files, 213319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar unsigned options) { 213419ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args, 213519ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar num_command_line_args, unsaved_files, num_unsaved_files, 213619ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar options, 0 }; 213719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar llvm::CrashRecoveryContext CRC; 213819ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar 213919ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar if (!CRC.RunSafely(clang_parseTranslationUnit_Impl, &PTUI)) { 214060a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "libclang: crash detected during parsing: {\n"); 214160a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'source_filename' : '%s'\n", source_filename); 214260a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'command_line_args' : ["); 214360a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar for (int i = 0; i != num_command_line_args; ++i) { 214460a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar if (i) 214560a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, ", "); 214660a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "'%s'", command_line_args[i]); 214760a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar } 214860a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "],\n"); 214960a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'unsaved_files' : ["); 215060a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar for (unsigned i = 0; i != num_unsaved_files; ++i) { 215160a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar if (i) 215260a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, ", "); 215360a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename, 215460a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar unsaved_files[i].Length); 215560a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar } 215660a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "],\n"); 215760a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, " 'options' : %d,\n", options); 215860a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar fprintf(stderr, "}\n"); 215960a4543d42b6b8564a5650345de7beb7e99c60f3Daniel Dunbar 216019ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar return 0; 216119ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar } 216219ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar 216319ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar return PTUI.result; 21645b7d8e254f6c2855b37b5521c0aee0a560dab237Steve Naroff} 21655b7d8e254f6c2855b37b5521c0aee0a560dab237Steve Naroff 21661999844e7a18786e61e619e1dc6c789827541863Douglas Gregorunsigned clang_defaultSaveOptions(CXTranslationUnit TU) { 21671999844e7a18786e61e619e1dc6c789827541863Douglas Gregor return CXSaveTranslationUnit_None; 21681999844e7a18786e61e619e1dc6c789827541863Douglas Gregor} 21691999844e7a18786e61e619e1dc6c789827541863Douglas Gregor 21701999844e7a18786e61e619e1dc6c789827541863Douglas Gregorint clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName, 21711999844e7a18786e61e619e1dc6c789827541863Douglas Gregor unsigned options) { 21727ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor if (!TU) 21737ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor return 1; 21747ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor 21757ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor return static_cast<ASTUnit *>(TU)->Save(FileName); 21767ae2faafd30524ef5f863bb3b8701977888839bbDouglas Gregor} 217719ffd492a31a25fb691098bf79f317e5f3edf177Daniel Dunbar 21789ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarvoid clang_disposeTranslationUnit(CXTranslationUnit CTUnit) { 2179ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar if (CTUnit) { 2180ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar // If the translation unit has been marked as unsafe to free, just discard 2181ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar // it. 2182ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar if (static_cast<ASTUnit *>(CTUnit)->isUnsafeToFree()) 2183ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return; 2184ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 21852b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor delete static_cast<ASTUnit *>(CTUnit); 2186ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar } 21872bd6b9f298afb16a2aec035ebd7b29af7c5c3da8Steve Naroff} 21880d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 2189e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregorunsigned clang_defaultReparseOptions(CXTranslationUnit TU) { 2190e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor return CXReparse_None; 2191e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor} 2192e1e13bf568a7e37c95eda6fcfa626659a06e67b1Douglas Gregor 2193ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbarstruct ReparseTranslationUnitInfo { 2194ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar CXTranslationUnit TU; 2195ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned num_unsaved_files; 2196ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar struct CXUnsavedFile *unsaved_files; 2197ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned options; 2198ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar int result; 2199ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar}; 2200593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor 2201b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarstatic void clang_reparseTranslationUnit_Impl(void *UserData) { 2202ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar ReparseTranslationUnitInfo *RTUI = 2203ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar static_cast<ReparseTranslationUnitInfo*>(UserData); 2204ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar CXTranslationUnit TU = RTUI->TU; 2205ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned num_unsaved_files = RTUI->num_unsaved_files; 2206ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files; 2207ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned options = RTUI->options; 2208ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar (void) options; 2209ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar RTUI->result = 1; 2210ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 2211abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor if (!TU) 2212ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return; 2213593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor 2214593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 2215593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor ASTUnit::ConcurrencyCheck Check(*CXXUnit); 2216abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 2217abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; 2218abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor for (unsigned I = 0; I != num_unsaved_files; ++I) { 2219abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); 2220abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor const llvm::MemoryBuffer *Buffer 22211abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); 2222abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, 2223abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor Buffer)); 2224abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor } 2225abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor 2226593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor if (!CXXUnit->Reparse(RemappedFiles.data(), RemappedFiles.size())) 2227593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor RTUI->result = 0; 2228abc563f554951259bbe0315055cad92ee14d87e4Douglas Gregor} 2229593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor 2230ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbarint clang_reparseTranslationUnit(CXTranslationUnit TU, 2231ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned num_unsaved_files, 2232ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar struct CXUnsavedFile *unsaved_files, 2233ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar unsigned options) { 2234ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files, 2235ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar options, 0 }; 2236ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar llvm::CrashRecoveryContext CRC; 2237ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 2238ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar if (!CRC.RunSafely(clang_reparseTranslationUnit_Impl, &RTUI)) { 2239b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar fprintf(stderr, "libclang: crash detected during reparsing\n"); 2240ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar static_cast<ASTUnit *>(TU)->setUnsafeToFree(true); 2241ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return 1; 2242ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar } 2243ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 22441dfb26af4d6aa4f7818e256659a79f1ec2cba784Ted Kremenek 2245ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar return RTUI.result; 2246ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar} 2247ea94bbc4769697143e717df9b0310f874102b6c1Daniel Dunbar 2248df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor 22499ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) { 22502b37c9e6cabaf3317922af13e6d12061242f04efDouglas Gregor if (!CTUnit) 2251ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 2252f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 225377accc11f04ed4ff9afd4e27d430144d4714be56Steve Naroff ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit); 2254ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(CXXUnit->getOriginalSourceFileName(), true); 2255af08ddc8f1c53fed8d8d0ad82aa2a0bb7d654bd1Steve Naroff} 22561eb79b58e56b99cf557d5d353586a10c5360364dDaniel Dunbar 22577eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas GregorCXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) { 2258b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } }; 22597eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor return Result; 22607eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor} 22617eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor 2262fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C" 2263600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff 2264fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 22651db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor// CXSourceLocation and CXSourceRange Operations. 22661db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor//===----------------------------------------------------------------------===// 22671db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 2268b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregorextern "C" { 2269b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceLocation clang_getNullLocation() { 22705352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor CXSourceLocation Result = { { 0, 0 }, 0 }; 2271b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return Result; 2272b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2273b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 2274b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregorunsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) { 227590a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar return (loc1.ptr_data[0] == loc2.ptr_data[0] && 227690a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar loc1.ptr_data[1] == loc2.ptr_data[1] && 227790a6b9e1e4d4d1995ada044e319d6e722b07a6b4Daniel Dunbar loc1.int_data == loc2.int_data); 2278b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2279b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 2280b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceLocation clang_getLocation(CXTranslationUnit tu, 2281b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor CXFile file, 2282b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor unsigned line, 2283b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor unsigned column) { 228442748ec5cb2d75fe0dbb3a6db5aee6c11b5dc190Douglas Gregor if (!tu || !file) 2285b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return clang_getNullLocation(); 228642748ec5cb2d75fe0dbb3a6db5aee6c11b5dc190Douglas Gregor 2287b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); 2288b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor SourceLocation SLoc 2289b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor = CXXUnit->getSourceManager().getLocation( 2290f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek static_cast<const FileEntry *>(file), 2291b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor line, column); 229283889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall if (SLoc.isInvalid()) return clang_getNullLocation(); 229383889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 229483889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc); 229583889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall} 229683889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 229783889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid ChisnallCXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu, 229883889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall CXFile file, 229983889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall unsigned offset) { 230083889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall if (!tu || !file) 230183889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall return clang_getNullLocation(); 230283889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 230383889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); 230483889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall SourceLocation Start 230583889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall = CXXUnit->getSourceManager().getLocation( 230683889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall static_cast<const FileEntry *>(file), 230783889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 1, 1); 230883889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall if (Start.isInvalid()) return clang_getNullLocation(); 230983889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 231083889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall SourceLocation SLoc = Start.getFileLocWithOffset(offset); 231183889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall 231283889a7f1f338e343ef72aeeef9c27f7b62c0f0fDavid Chisnall if (SLoc.isInvalid()) return clang_getNullLocation(); 2313f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 23141a9a0bc472ee4fec72ee8be8b575fb66ca600d1bTed Kremenek return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc); 2315b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2316b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 23175352ac06d8f6194825bb2a99ffa009b61bafb503Douglas GregorCXSourceRange clang_getNullRange() { 23185352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor CXSourceRange Result = { { 0, 0 }, 0, 0 }; 23195352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return Result; 23205352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor} 2321d52864bd33c66aacc84133460d8c9c0dfcdd5c18Daniel Dunbar 2322b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) { 23235352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor if (begin.ptr_data[0] != end.ptr_data[0] || 23245352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor begin.ptr_data[1] != end.ptr_data[1]) 23255352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullRange(); 2326f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2327f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] }, 23285352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor begin.int_data, end.int_data }; 2329b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return Result; 2330b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2331b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 233246766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregorvoid clang_getInstantiationLocation(CXSourceLocation location, 233346766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor CXFile *file, 233446766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor unsigned *line, 233546766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor unsigned *column, 233646766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor unsigned *offset) { 23371db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data); 23381db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 2339bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar if (!location.ptr_data[0] || Loc.isInvalid()) { 234046766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor if (file) 234146766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor *file = 0; 234246766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor if (line) 234346766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor *line = 0; 234446766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor if (column) 234546766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor *column = 0; 234646766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor if (offset) 234746766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor *offset = 0; 234846766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor return; 234946766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor } 235046766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor 2351bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar const SourceManager &SM = 2352bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar *static_cast<const SourceManager*>(location.ptr_data[0]); 23531db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor SourceLocation InstLoc = SM.getInstantiationLoc(Loc); 23541db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 23551db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor if (file) 23561db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc)); 23571db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor if (line) 23581db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor *line = SM.getInstantiationLineNumber(InstLoc); 23591db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor if (column) 23601db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor *column = SM.getInstantiationColumnNumber(InstLoc); 2361e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor if (offset) 236246766dc31c09d89024de5aba9e22112a56eadbdfDouglas Gregor *offset = SM.getDecomposedLoc(InstLoc).second; 2363e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor} 2364e69517ce61638f12c9abe4605753a45275ac4e37Douglas Gregor 23651db19dea8d221f27be46332d668d1e2decb7f1abDouglas GregorCXSourceLocation clang_getRangeStart(CXSourceRange range) { 2366f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, 23675352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor range.begin_int_data }; 23681db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor return Result; 23691db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor} 23701db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 23711db19dea8d221f27be46332d668d1e2decb7f1abDouglas GregorCXSourceLocation clang_getRangeEnd(CXSourceRange range) { 2372bb4a61a121ba1ee91eb5725881d98249704bb0aaDaniel Dunbar CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, 23735352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor range.end_int_data }; 23741db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor return Result; 23751db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor} 23761db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor 2377b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} // end: extern "C" 2378b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor 23791db19dea8d221f27be46332d668d1e2decb7f1abDouglas Gregor//===----------------------------------------------------------------------===// 2380fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek// CXFile Operations. 2381fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 2382fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 2383fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekextern "C" { 238474844072411bae91d5dbb89955d200cbe1e0a1c8Ted KremenekCXString clang_getFileName(CXFile SFile) { 238598258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor if (!SFile) 238674844072411bae91d5dbb89955d200cbe1e0a1c8Ted Kremenek return createCXString(NULL); 2387f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 238888145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff FileEntry *FEnt = static_cast<FileEntry *>(SFile); 238974844072411bae91d5dbb89955d200cbe1e0a1c8Ted Kremenek return createCXString(FEnt->getName()); 239088145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff} 239188145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff 239288145034694ed5267fa6fa5febc54fadc02bd479Steve Narofftime_t clang_getFileTime(CXFile SFile) { 239398258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor if (!SFile) 239498258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor return 0; 2395f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 239688145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff FileEntry *FEnt = static_cast<FileEntry *>(SFile); 239788145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff return FEnt->getModificationTime(); 2398ee9405e807d7c447c0143c2bd865b759192e97b3Steve Naroff} 2399f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2400b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXFile clang_getFile(CXTranslationUnit tu, const char *file_name) { 2401b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor if (!tu) 2402b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return 0; 2403f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2404b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); 2405f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2406b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor FileManager &FMgr = CXXUnit->getFileManager(); 2407b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor const FileEntry *File = FMgr.getFile(file_name, file_name+strlen(file_name)); 2408b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor return const_cast<FileEntry *>(File); 2409b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor} 2410f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2411fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C" 2412fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 2413fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 2414fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek// CXCursor Operations. 2415fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 2416fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 2417fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekstatic Decl *getDeclFromExpr(Stmt *E) { 2418db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor if (CastExpr *CE = dyn_cast<CastExpr>(E)) 2419db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor return getDeclFromExpr(CE->getSubExpr()); 2420db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor 2421fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E)) 2422fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return RefExpr->getDecl(); 242338f28c1189142429384996409fffbc57f67b5c60Douglas Gregor if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E)) 242438f28c1189142429384996409fffbc57f67b5c60Douglas Gregor return RefExpr->getDecl(); 2425fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) 2426fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return ME->getMemberDecl(); 2427fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E)) 2428fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return RE->getDecl(); 2429db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) 2430db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor return PRE->getProperty(); 2431db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor 2432fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (CallExpr *CE = dyn_cast<CallExpr>(E)) 2433fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return getDeclFromExpr(CE->getCallee()); 2434fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E)) 2435fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return OME->getMethodDecl(); 2436f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2437db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E)) 2438db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor return PE->getProtocol(); 2439db1314e3ef76f38de07f1b3c7cdc1100a0678931Douglas Gregor 2440fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return 0; 2441fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} 2442ee9405e807d7c447c0143c2bd865b759192e97b3Steve Naroff 2443c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbarstatic SourceLocation getLocationFromExpr(Expr *E) { 2444c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) 2445c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return /*FIXME:*/Msg->getLeftLoc(); 2446c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 2447c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return DRE->getLocation(); 244838f28c1189142429384996409fffbc57f67b5c60Douglas Gregor if (BlockDeclRefExpr *RefExpr = dyn_cast<BlockDeclRefExpr>(E)) 244938f28c1189142429384996409fffbc57f67b5c60Douglas Gregor return RefExpr->getLocation(); 2450c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (MemberExpr *Member = dyn_cast<MemberExpr>(E)) 2451c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return Member->getMemberLoc(); 2452c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E)) 2453c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return Ivar->getLocation(); 2454c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar return E->getLocStart(); 2455c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar} 2456c29f4c396019f51e09511e385d6c07c4ea2a1464Daniel Dunbar 2457fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekextern "C" { 2458f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 2459f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenekunsigned clang_visitChildren(CXCursor parent, 2460b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXCursorVisitor visitor, 2461b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor CXClientData client_data) { 2462b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor ASTUnit *CXXUnit = getCursorASTUnit(parent); 2463b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor 2464eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor CursorVisitor CursorVis(CXXUnit, visitor, client_data, 2465eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor CXXUnit->getMaxPCHLevel()); 2466b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor return CursorVis.VisitChildren(parent); 2467b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor} 2468b1373d03e4e38620647311bb87e56c0cf7cffeb7Douglas Gregor 246978205d4bada39d95097e766af9eb30cdd0159461Douglas Gregorstatic CXString getDeclSpelling(Decl *D) { 247078205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D); 247178205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor if (!ND) 2472ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 2473f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 247478205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) 2475ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(OMD->getSelector().getAsString()); 2476f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 247778205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND)) 247878205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor // No, this isn't the same as the code below. getIdentifier() is non-virtual 247978205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor // and returns different names. NamedDecl returns the class name and 248078205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor // ObjCCategoryImplDecl returns the category name. 2481ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(CIMP->getIdentifier()->getNameStart()); 2482f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 24830a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor if (isa<UsingDirectiveDecl>(D)) 24840a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor return createCXString(""); 24850a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor 248650aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek llvm::SmallString<1024> S; 248750aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek llvm::raw_svector_ostream os(S); 248850aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek ND->printName(os); 248950aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek 249050aa6acd0b8d40c8956372a69e0a73f0802a5494Ted Kremenek return createCXString(os.str()); 249178205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor} 2492f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 24939ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXString clang_getCursorSpelling(CXCursor C) { 24947eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor if (clang_isTranslationUnit(C.kind)) 2495b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getTranslationUnitSpelling(C.data[2]); 24967eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor 2497f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff if (clang_isReference(C.kind)) { 2498f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff switch (C.kind) { 2499acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar case CXCursor_ObjCSuperClassRef: { 25002e331b938b38057e333fab0ba841130ea8467794Douglas Gregor ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first; 2501ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(Super->getIdentifier()->getNameStart()); 2502acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar } 2503acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar case CXCursor_ObjCClassRef: { 25041adb082a709f7b588f03672999294e061234b2cfDouglas Gregor ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; 2505ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(Class->getIdentifier()->getNameStart()); 2506acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar } 2507acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar case CXCursor_ObjCProtocolRef: { 250878db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first; 2509f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor assert(OID && "getCursorSpelling(): Missing protocol decl"); 2510ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(OID->getIdentifier()->getNameStart()); 2511acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar } 25123064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: { 25133064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); 25143064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return createCXString(B->getType().getAsString()); 25153064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 25167d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor case CXCursor_TypeRef: { 25177d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor TypeDecl *Type = getCursorTypeRef(C).first; 25187d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor assert(Type && "Missing type decl"); 25197d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 2520ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(getCursorContext(C).getTypeDeclType(Type). 2521ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek getAsString()); 25227d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor } 25230b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: { 25240b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor TemplateDecl *Template = getCursorTemplateRef(C).first; 25256931900f43cea558c6974075256c07728dbfecc6Douglas Gregor assert(Template && "Missing template decl"); 25260b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 25270b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return createCXString(Template->getNameAsString()); 25280b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor } 25296931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 25306931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: { 25316931900f43cea558c6974075256c07728dbfecc6Douglas Gregor NamedDecl *NS = getCursorNamespaceRef(C).first; 25326931900f43cea558c6974075256c07728dbfecc6Douglas Gregor assert(NS && "Missing namespace decl"); 25336931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 25346931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return createCXString(NS->getNameAsString()); 25356931900f43cea558c6974075256c07728dbfecc6Douglas Gregor } 25367d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 2537a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: { 2538a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor FieldDecl *Field = getCursorMemberRef(C).first; 2539a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor assert(Field && "Missing member decl"); 2540a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 2541a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return createCXString(Field->getNameAsString()); 2542a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 2543a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 254436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: { 254536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor LabelStmt *Label = getCursorLabelRef(C).first; 254636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor assert(Label && "Missing label"); 254736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 254836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString(Label->getID()->getName()); 254936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 255036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 25511f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: { 25521f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first; 25531f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Decl *D = Storage.dyn_cast<Decl *>()) { 25541f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) 25551f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(ND->getNameAsString()); 25561f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(""); 25571f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 25581f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) 25591f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(E->getName().getAsString()); 25601f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedTemplateStorage *Ovl 25611f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = Storage.get<OverloadedTemplateStorage*>(); 25621f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (Ovl->size() == 0) 25631f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString(""); 25641f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString((*Ovl->begin())->getNameAsString()); 25651f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 25661f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 2567acca725aeff400274fab552fc83d87af8a11995dDaniel Dunbar default: 2568ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString("<not implemented>"); 2569f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff } 2570f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff } 257197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 257297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) { 257397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor Decl *D = getDeclFromExpr(getCursorExpr(C)); 257497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (D) 257578205d4bada39d95097e766af9eb30cdd0159461Douglas Gregor return getDeclSpelling(D); 2576ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 257797b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor } 257897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 257936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (clang_isStatement(C.kind)) { 258036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor Stmt *S = getCursorStmt(C); 258136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) 258236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString(Label->getID()->getName()); 258336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 258436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString(""); 258536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 258636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 25874ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor if (C.kind == CXCursor_MacroInstantiation) 25884ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor return createCXString(getCursorMacroInstantiation(C)->getName() 25894ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor ->getNameStart()); 25904ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor 2591572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor if (C.kind == CXCursor_MacroDefinition) 2592572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor return createCXString(getCursorMacroDefinition(C)->getName() 2593572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor ->getNameStart()); 2594572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor 2595ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (C.kind == CXCursor_InclusionDirective) 2596ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return createCXString(getCursorInclusionDirective(C)->getFileName()); 2597ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 259860cbfacd947590f83257a4191566dda92fbbde69Douglas Gregor if (clang_isDeclaration(C.kind)) 259960cbfacd947590f83257a4191566dda92fbbde69Douglas Gregor return getDeclSpelling(getCursorDecl(C)); 2600e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 2601ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 2602f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff} 2603f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff 2604358559d8d7b458c5f64941842383a16e61f0828dDouglas GregorCXString clang_getCursorDisplayName(CXCursor C) { 2605358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (!clang_isDeclaration(C.kind)) 2606358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return clang_getCursorSpelling(C); 2607358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2608358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor Decl *D = getCursorDecl(C); 2609358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (!D) 2610358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(""); 2611358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2612358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy; 2613358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) 2614358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor D = FunTmpl->getTemplatedDecl(); 2615358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2616358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { 2617358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::SmallString<64> Str; 2618358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::raw_svector_ostream OS(Str); 2619358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << Function->getNameAsString(); 2620358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Function->getPrimaryTemplate()) 2621358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "<>"; 2622358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "("; 2623358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) { 2624358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (I) 2625358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ", "; 2626358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << Function->getParamDecl(I)->getType().getAsString(Policy); 2627358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2628358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2629358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Function->isVariadic()) { 2630358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Function->getNumParams()) 2631358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ", "; 2632358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "..."; 2633358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2634358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ")"; 2635358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(OS.str()); 2636358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2637358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2638358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) { 2639358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::SmallString<64> Str; 2640358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::raw_svector_ostream OS(Str); 2641358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ClassTemplate->getNameAsString(); 2642358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "<"; 2643358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor TemplateParameterList *Params = ClassTemplate->getTemplateParameters(); 2644358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor for (unsigned I = 0, N = Params->size(); I != N; ++I) { 2645358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (I) 2646358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ", "; 2647358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2648358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor NamedDecl *Param = Params->getParam(I); 2649358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (Param->getIdentifier()) { 2650358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << Param->getIdentifier()->getName(); 2651358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor continue; 2652358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2653358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2654358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor // There is no parameter name, which makes this tricky. Try to come up 2655358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor // with something useful that isn't too long. 2656358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) 2657358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << (TTP->wasDeclaredWithTypename()? "typename" : "class"); 2658358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor else if (NonTypeTemplateParmDecl *NTTP 2659358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor = dyn_cast<NonTypeTemplateParmDecl>(Param)) 2660358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << NTTP->getType().getAsString(Policy); 2661358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor else 2662358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << "template<...> class"; 2663358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2664358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2665358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ">"; 2666358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(OS.str()); 2667358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2668358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2669358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (ClassTemplateSpecializationDecl *ClassSpec 2670358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 2671358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor // If the type was explicitly written, use that. 2672358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten()) 2673358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(TSInfo->getType().getAsString(Policy)); 2674358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2675358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::SmallString<64> Str; 2676358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor llvm::raw_svector_ostream OS(Str); 2677358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << ClassSpec->getNameAsString(); 2678358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor OS << TemplateSpecializationType::PrintTemplateArgumentList( 2679358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor ClassSpec->getTemplateArgs().getFlatArgumentList(), 2680358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor ClassSpec->getTemplateArgs().flat_size(), 2681358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor Policy); 2682358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return createCXString(OS.str()); 2683358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor } 2684358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2685358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor return clang_getCursorSpelling(C); 2686358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor} 2687358559d8d7b458c5f64941842383a16e61f0828dDouglas Gregor 2688e68fff6fc083c6270d835216a3de0b82c6ef0310Ted KremenekCXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { 268989922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff switch (Kind) { 2690e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_FunctionDecl: 2691e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("FunctionDecl"); 2692e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_TypedefDecl: 2693e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("TypedefDecl"); 2694e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_EnumDecl: 2695e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("EnumDecl"); 2696e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_EnumConstantDecl: 2697e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("EnumConstantDecl"); 2698e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_StructDecl: 2699e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("StructDecl"); 2700e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnionDecl: 2701e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnionDecl"); 2702e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ClassDecl: 2703e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ClassDecl"); 2704e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_FieldDecl: 2705e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("FieldDecl"); 2706e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_VarDecl: 2707e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("VarDecl"); 2708e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ParmDecl: 2709e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ParmDecl"); 2710e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCInterfaceDecl: 2711e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCInterfaceDecl"); 2712e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCCategoryDecl: 2713e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCCategoryDecl"); 2714e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCProtocolDecl: 2715e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCProtocolDecl"); 2716e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCPropertyDecl: 2717e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCPropertyDecl"); 2718e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCIvarDecl: 2719e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCIvarDecl"); 2720e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCInstanceMethodDecl: 2721e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCInstanceMethodDecl"); 2722e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCClassMethodDecl: 2723e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCClassMethodDecl"); 2724e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCImplementationDecl: 2725e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCImplementationDecl"); 2726e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCCategoryImplDecl: 2727e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCCategoryImplDecl"); 27288bd5a69999cfd06b6b5a58fdd04e4f802b2df5a4Ted Kremenek case CXCursor_CXXMethod: 27298bd5a69999cfd06b6b5a58fdd04e4f802b2df5a4Ted Kremenek return createCXString("CXXMethod"); 2730e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnexposedDecl: 2731e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnexposedDecl"); 2732e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCSuperClassRef: 2733e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCSuperClassRef"); 2734e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCProtocolRef: 2735e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCProtocolRef"); 2736e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCClassRef: 2737e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCClassRef"); 2738e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_TypeRef: 2739e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("TypeRef"); 27400b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: 27410b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return createCXString("TemplateRef"); 27426931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: 27436931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return createCXString("NamespaceRef"); 2744a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: 2745a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return createCXString("MemberRef"); 274636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: 274736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString("LabelRef"); 27481f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 27491f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return createCXString("OverloadedDeclRef"); 2750e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnexposedExpr: 2751e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnexposedExpr"); 27521ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek case CXCursor_BlockExpr: 27531ee6cad59f017601ea54fbb4f62a6e8d69897e3eTed Kremenek return createCXString("BlockExpr"); 2754e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_DeclRefExpr: 2755e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("DeclRefExpr"); 2756e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_MemberRefExpr: 2757e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("MemberRefExpr"); 2758e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_CallExpr: 2759e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("CallExpr"); 2760e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_ObjCMessageExpr: 2761e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("ObjCMessageExpr"); 2762e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_UnexposedStmt: 2763e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("UnexposedStmt"); 276436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelStmt: 276536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return createCXString("LabelStmt"); 2766e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_InvalidFile: 2767e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("InvalidFile"); 2768292db6401f040795db3ea4e00fc02622d6c3ba1dTed Kremenek case CXCursor_InvalidCode: 2769292db6401f040795db3ea4e00fc02622d6c3ba1dTed Kremenek return createCXString("InvalidCode"); 2770e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_NoDeclFound: 2771e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("NoDeclFound"); 2772e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_NotImplemented: 2773e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("NotImplemented"); 2774e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek case CXCursor_TranslationUnit: 2775e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString("TranslationUnit"); 2776e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek case CXCursor_UnexposedAttr: 2777e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek return createCXString("UnexposedAttr"); 2778e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek case CXCursor_IBActionAttr: 2779e77f443dbca8cdc23e5aa94a2653367e4a7cbe47Ted Kremenek return createCXString("attribute(ibaction)"); 27809f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor case CXCursor_IBOutletAttr: 27819f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return createCXString("attribute(iboutlet)"); 2782857e918a8a40deb128840308a318bf623d68295fTed Kremenek case CXCursor_IBOutletCollectionAttr: 2783857e918a8a40deb128840308a318bf623d68295fTed Kremenek return createCXString("attribute(iboutletcollection)"); 27849f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor case CXCursor_PreprocessingDirective: 27859f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return createCXString("preprocessing directive"); 2786572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor case CXCursor_MacroDefinition: 2787572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor return createCXString("macro definition"); 27884807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor case CXCursor_MacroInstantiation: 27894807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor return createCXString("macro instantiation"); 2790ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor case CXCursor_InclusionDirective: 2791ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return createCXString("inclusion directive"); 27928f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek case CXCursor_Namespace: 27938f06e0e9fec3ca501e5fb129f413adbfc88e82f8Ted Kremenek return createCXString("Namespace"); 2794a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek case CXCursor_LinkageSpec: 2795a0536d8dd900bb48ea886bd68d777b03b061c068Ted Kremenek return createCXString("LinkageSpec"); 27963064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: 27973064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return createCXString("C++ base class specifier"); 279801829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case CXCursor_Constructor: 279901829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return createCXString("CXXConstructor"); 280001829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case CXCursor_Destructor: 280101829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return createCXString("CXXDestructor"); 280201829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor case CXCursor_ConversionFunction: 280301829d3afafdfd355cbe93537bc408aeeed964c6Douglas Gregor return createCXString("CXXConversion"); 2804fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_TemplateTypeParameter: 2805fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("TemplateTypeParameter"); 2806fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_NonTypeTemplateParameter: 2807fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("NonTypeTemplateParameter"); 2808fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_TemplateTemplateParameter: 2809fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("TemplateTemplateParameter"); 2810fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor case CXCursor_FunctionTemplate: 2811fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor return createCXString("FunctionTemplate"); 281239d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor case CXCursor_ClassTemplate: 281339d6f07b056c31e1e6b5946165ed4b23e7887f22Douglas Gregor return createCXString("ClassTemplate"); 281474dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor case CXCursor_ClassTemplatePartialSpecialization: 281574dbe640021d96a8dbb85c592471c04449ade81cDouglas Gregor return createCXString("ClassTemplatePartialSpecialization"); 28166931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceAlias: 28176931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return createCXString("NamespaceAlias"); 28180a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor case CXCursor_UsingDirective: 28190a35bceb7768fc0be62cb644a4e31d8bfd9fb44aDouglas Gregor return createCXString("UsingDirective"); 28207e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor case CXCursor_UsingDeclaration: 28217e24256c95afb64b4d5abf201a0f9f0527cb4cf3Douglas Gregor return createCXString("UsingDeclaration"); 282289922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff } 2823e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 2824deb06bd3566e18f677e76bc435d478b033fe328bTed Kremenek llvm_unreachable("Unhandled CXCursorKind"); 2825e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return createCXString(NULL); 2826600866cc7d6d9ec2e27d4b6d6ec461f6463b5ab6Steve Naroff} 282789922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff 2828e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenekenum CXChildVisitResult GetCursorVisitor(CXCursor cursor, 2829e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek CXCursor parent, 283033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CXClientData client_data) { 283133e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CXCursor *BestCursor = static_cast<CXCursor *>(client_data); 283233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor *BestCursor = cursor; 283333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor return CXChildVisit_Recurse; 283433e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor} 2835e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 2836b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas GregorCXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { 2837b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor if (!TU) 2838f462989fe8d6f59ab2d7d0fe2b4b96292ce706eaTed Kremenek return clang_getNullCursor(); 2839e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek 2840b979034b100be14de2223f2b8f6cc7a3275cbe4fDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 2841bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor ASTUnit::ConcurrencyCheck Check(*CXXUnit); 2842bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor 2843a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor // Translate the given source location to make it point at the beginning of 2844a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor // the token under the cursor. 2845a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek SourceLocation SLoc = cxloc::translateSourceLocation(Loc); 2846a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek 2847a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek // Guard against an invalid SourceLocation, or we may assert in one 2848a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek // of the following calls. 2849a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek if (SLoc.isInvalid()) 2850a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek return clang_getNullCursor(); 2851a629ea42f6bc095190db2f3932b60a0be14f3d34Ted Kremenek 2852a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(), 2853a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor CXXUnit->getASTContext().getLangOptions()); 2854a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 285533e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound); 285633e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor if (SLoc.isValid()) { 285733e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // FIXME: Would be great to have a "hint" cursor, then walk from that 285833e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // hint cursor upward until we find a cursor whose source range encloses 285933e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor // the region of interest, rather than starting from the translation unit. 286033e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit); 2861e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek CursorVisitor CursorVis(CXXUnit, GetCursorVisitor, &Result, 2862a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor Decl::MaxPCHLevel, SourceLocation(SLoc)); 286333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor CursorVis.VisitChildren(Parent); 286477128ddd3077fc045751a55bb3226802b15d5510Steve Naroff } 2865e68fff6fc083c6270d835216a3de0b82c6ef0310Ted Kremenek return Result; 286677128ddd3077fc045751a55bb3226802b15d5510Steve Naroff} 286777128ddd3077fc045751a55bb3226802b15d5510Steve Naroff 2868738855554394a6afcf39cc8345fd22c3756b8dd0Ted KremenekCXCursor clang_getNullCursor(void) { 28695bfb8c128c2ac8eb4032afc180cdc400a0f953caDouglas Gregor return MakeCXCursorInvalid(CXCursor_InvalidFile); 2870738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek} 2871738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek 2872738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenekunsigned clang_equalCursors(CXCursor X, CXCursor Y) { 2873283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor return X == Y; 2874738855554394a6afcf39cc8345fd22c3756b8dd0Ted Kremenek} 28750d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbar 28769ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isInvalid(enum CXCursorKind K) { 287777128ddd3077fc045751a55bb3226802b15d5510Steve Naroff return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid; 287877128ddd3077fc045751a55bb3226802b15d5510Steve Naroff} 287977128ddd3077fc045751a55bb3226802b15d5510Steve Naroff 28809ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isDeclaration(enum CXCursorKind K) { 288189922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl; 288289922f86f4e7da383af2a62ef04ad8b93b941220Steve Naroff} 28832d4d629d8a0de5112c7ae9d05c03ddbf6dcd956aSteve Naroff 28849ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbarunsigned clang_isReference(enum CXCursorKind K) { 2885f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff return K >= CXCursor_FirstRef && K <= CXCursor_LastRef; 2886f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff} 2887f334b4e3eda5a39f041fe13f805dbb53535daa2fSteve Naroff 288897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregorunsigned clang_isExpression(enum CXCursorKind K) { 288997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr; 289097b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor} 289197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 289297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregorunsigned clang_isStatement(enum CXCursorKind K) { 289397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt; 289497b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor} 289597b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 28967eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregorunsigned clang_isTranslationUnit(enum CXCursorKind K) { 28977eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor return K == CXCursor_TranslationUnit; 28987eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor} 28997eaa8ae8692c5cd3eed8cb334fe5346470522091Douglas Gregor 29009f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregorunsigned clang_isPreprocessing(enum CXCursorKind K) { 29019f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing; 29029f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor} 29039f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor 2904ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenekunsigned clang_isUnexposed(enum CXCursorKind K) { 2905ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek switch (K) { 2906ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedDecl: 2907ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedExpr: 2908ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedStmt: 2909ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek case CXCursor_UnexposedAttr: 2910ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek return true; 2911ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek default: 2912ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek return false; 2913ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek } 2914ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek} 2915ad6eff611a4391f89fd6c458db16993f76e7f5d0Ted Kremenek 29169ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel DunbarCXCursorKind clang_getCursorKind(CXCursor C) { 29179efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff return C.kind; 29189efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff} 29199efa767be8e9f2dae509d3a0be93ade01bfa1560Steve Naroff 292098258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas GregorCXSourceLocation clang_getCursorLocation(CXCursor C) { 292198258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor if (clang_isReference(C.kind)) { 2922f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor switch (C.kind) { 2923f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCSuperClassRef: { 2924f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor std::pair<ObjCInterfaceDecl *, SourceLocation> P 2925f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor = getCursorObjCSuperClassRef(C); 2926a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 2927f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 2928f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor 2929f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCProtocolRef: { 2930f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor std::pair<ObjCProtocolDecl *, SourceLocation> P 2931f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor = getCursorObjCProtocolRef(C); 2932a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 2933f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 2934f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor 2935f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCClassRef: { 2936f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor std::pair<ObjCInterfaceDecl *, SourceLocation> P 2937f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor = getCursorObjCClassRef(C); 2938a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 2939f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 29407d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 2941f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_TypeRef: { 29427d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C); 2943a297de20bde673b1a2ad67fa5eafd37fea4227fcTed Kremenek return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 29447d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor } 29450b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 29460b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: { 29470b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C); 29480b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 29490b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor } 29500b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 29516931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: { 29526931900f43cea558c6974075256c07728dbfecc6Douglas Gregor std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C); 29536931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 29546931900f43cea558c6974075256c07728dbfecc6Douglas Gregor } 29556931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 2956a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: { 2957a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C); 2958a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 2959a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor } 2960a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 29613064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: { 29621b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C); 29631b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor if (!BaseSpec) 29641b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return clang_getNullLocation(); 29651b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor 29661b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo()) 29671b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 29681b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor TSInfo->getTypeLoc().getBeginLoc()); 29691b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor 29701b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 29711b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor BaseSpec->getSourceRange().getBegin()); 29723064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 2973f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 297436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: { 297536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C); 297636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), P.second); 297736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 297836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 29791f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 29801f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 29811f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor getCursorOverloadedDeclRef(C).second); 29821f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 2983f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor default: 2984f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor // FIXME: Need a way to enumerate all non-reference cases. 2985f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor llvm_unreachable("Missed a reference kind"); 2986f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor } 298798258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor } 298897b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 298997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) 2990f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return cxloc::translateSourceLocation(getCursorContext(C), 299197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor getLocationFromExpr(getCursorExpr(C))); 299297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 299336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (clang_isStatement(C.kind)) 299436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), 299536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor getCursorStmt(C)->getLocStart()); 299636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 29979f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor if (C.kind == CXCursor_PreprocessingDirective) { 29989f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin(); 29999f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 30009f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 30014807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor 30024807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor if (C.kind == CXCursor_MacroInstantiation) { 30034ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor SourceLocation L 30044ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin(); 30054807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 30064807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor } 3007572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor 3008572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor if (C.kind == CXCursor_MacroDefinition) { 3009572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation(); 3010572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 3011572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor } 3012ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 3013ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (C.kind == CXCursor_InclusionDirective) { 3014ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor SourceLocation L 3015ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin(); 3016ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), L); 3017ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor } 3018ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 30199a700d277c38d9afaa7cb3fe93a714bfe9b62eecTed Kremenek if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl) 30205352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullLocation(); 302198258afae66bab39b0c57a3efb6b20d4fbb5746cDouglas Gregor 3022f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor Decl *D = getCursorDecl(C); 3023f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor SourceLocation Loc = D->getLocation(); 3024f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D)) 3025f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor Loc = Class->getClassLoc(); 3026007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // FIXME: Multiple variables declared in a single declaration 3027007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // currently lack the information needed to correctly determine their 3028007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // ranges when accounting for the type-specifier. We use context 3029007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, 3030007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // and if so, whether it is the first decl. 3031007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 3032007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (!cxcursor::isFirstInDeclGroup(C)) 3033007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek Loc = VD->getLocation(); 3034007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek } 3035007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek 30362ca54feee89d7277fb967e3247a64f40ef155a82Douglas Gregor return cxloc::translateSourceLocation(getCursorContext(C), Loc); 303788145034694ed5267fa6fa5febc54fadc02bd479Steve Naroff} 3038a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor 3039a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor} // end extern "C" 3040a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 3041a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorstatic SourceRange getRawCursorExtent(CXCursor C) { 3042a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor if (clang_isReference(C.kind)) { 3043a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor switch (C.kind) { 3044a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_ObjCSuperClassRef: 3045a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorObjCSuperClassRef(C).second; 3046f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3047a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_ObjCProtocolRef: 3048a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorObjCProtocolRef(C).second; 3049f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3050a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_ObjCClassRef: 3051a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorObjCClassRef(C).second; 30527d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 3053a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor case CXCursor_TypeRef: 3054a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorTypeRef(C).second; 30550b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 30560b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: 30570b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return getCursorTemplateRef(C).second; 30580b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 30596931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: 30606931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return getCursorNamespaceRef(C).second; 3061a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 3062a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: 3063a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return getCursorMemberRef(C).second; 3064a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 30653064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: 30661b0f7af64113b63253ced088a2bc64eb98e6f388Douglas Gregor return getCursorCXXBaseSpecifier(C)->getSourceRange(); 3067f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 306836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: 306936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return getCursorLabelRef(C).second; 307036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 30711f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 30721f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return getCursorOverloadedDeclRef(C).second; 30731f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 3074a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor default: 3075a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor // FIXME: Need a way to enumerate all non-reference cases. 3076a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor llvm_unreachable("Missed a reference kind"); 3077a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor } 3078a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor } 307997b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 308097b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) 3081a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorExpr(C)->getSourceRange(); 308233e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor 308333e9abd21083a0191a7676a04b497006d2da184dDouglas Gregor if (clang_isStatement(C.kind)) 3084a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return getCursorStmt(C)->getSourceRange(); 3085f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3086a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (C.kind == CXCursor_PreprocessingDirective) 3087a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return cxcursor::getCursorPreprocessingDirective(C); 30884807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor 3089a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (C.kind == CXCursor_MacroInstantiation) 3090a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return cxcursor::getCursorMacroInstantiation(C)->getSourceRange(); 3091572feb2a190b5e8b04fb06c4ac50ee0f61e93ff0Douglas Gregor 3092a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (C.kind == CXCursor_MacroDefinition) 3093a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return cxcursor::getCursorMacroDefinition(C)->getSourceRange(); 3094ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 3095ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (C.kind == CXCursor_InclusionDirective) 3096ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return cxcursor::getCursorInclusionDirective(C)->getSourceRange(); 3097ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 3098007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) { 3099007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek Decl *D = cxcursor::getCursorDecl(C); 3100007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek SourceRange R = D->getSourceRange(); 3101007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // FIXME: Multiple variables declared in a single declaration 3102007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // currently lack the information needed to correctly determine their 3103007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // ranges when accounting for the type-specifier. We use context 3104007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, 3105007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek // and if so, whether it is the first decl. 3106007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 3107007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek if (!cxcursor::isFirstInDeclGroup(C)) 3108007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek R.setBegin(VD->getLocation()); 3109007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek } 3110007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek return R; 3111007a7c9d8dcdb2e9cd94b6075108bfc4c90e6ccdTed Kremenek } 3112ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return SourceRange();} 3113a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 3114a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregorextern "C" { 3115a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor 3116a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas GregorCXSourceRange clang_getCursorExtent(CXCursor C) { 3117a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor SourceRange R = getRawCursorExtent(C); 3118a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor if (R.isInvalid()) 31195352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullRange(); 3120f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3121a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor return cxloc::translateSourceRange(getCursorContext(C), R); 3122a7bde20f8c6334ccc3a7ef4dd77243d0921a8497Douglas Gregor} 3123c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor 3124c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas GregorCXCursor clang_getCursorReferenced(CXCursor C) { 3125b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (clang_isInvalid(C.kind)) 3126b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getNullCursor(); 3127f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3128b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor ASTUnit *CXXUnit = getCursorASTUnit(C); 31291f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (clang_isDeclaration(C.kind)) { 31301f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = getCursorDecl(C); 31311f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) 31321f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(Using, D->getLocation(), CXXUnit); 31331f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D)) 31341f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), CXXUnit); 31351f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCForwardProtocolDecl *Protocols 31361f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = dyn_cast<ObjCForwardProtocolDecl>(D)) 31371f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), CXXUnit); 31381f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 3139c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor return C; 31401f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 31411f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 314297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isExpression(C.kind)) { 31431f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Expr *E = getCursorExpr(C); 31441f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = getDeclFromExpr(E); 314597b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (D) 3146b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(D, CXXUnit); 31471f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 31481f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E)) 31491f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(Ovl, CXXUnit); 31501f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 315197b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor return clang_getNullCursor(); 315297b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor } 315397b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor 315436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (clang_isStatement(C.kind)) { 315536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor Stmt *S = getCursorStmt(C); 315636897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S)) 315736897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return MakeCXCursor(Goto->getLabel(), getCursorDecl(C), 315836897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor getCursorASTUnit(C)); 315936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 316036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return clang_getNullCursor(); 316136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor } 316236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 3163bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor if (C.kind == CXCursor_MacroInstantiation) { 3164bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition()) 3165bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor return MakeMacroDefinitionCursor(Def, CXXUnit); 3166bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor } 3167bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor 3168c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor if (!clang_isReference(C.kind)) 3169c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor return clang_getNullCursor(); 3170f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3171c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor switch (C.kind) { 3172c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor case CXCursor_ObjCSuperClassRef: 3173b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(getCursorObjCSuperClassRef(C).first, CXXUnit); 3174f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3175f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCProtocolRef: { 3176b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(getCursorObjCProtocolRef(C).first, CXXUnit); 3177f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3178f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_ObjCClassRef: 3179b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(getCursorObjCClassRef(C).first, CXXUnit); 31807d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor 3181f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek case CXCursor_TypeRef: 31827d0d40e58807f73e06ff5eb637a48e9f978b0e2aDouglas Gregor return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit); 31830b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 31840b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor case CXCursor_TemplateRef: 31850b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return MakeCXCursor(getCursorTemplateRef(C).first, CXXUnit); 31860b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor 31876931900f43cea558c6974075256c07728dbfecc6Douglas Gregor case CXCursor_NamespaceRef: 31886931900f43cea558c6974075256c07728dbfecc6Douglas Gregor return MakeCXCursor(getCursorNamespaceRef(C).first, CXXUnit); 31896931900f43cea558c6974075256c07728dbfecc6Douglas Gregor 3190a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor case CXCursor_MemberRef: 3191a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor return MakeCXCursor(getCursorMemberRef(C).first, CXXUnit); 3192a67e03fdf1ae8a1f92463a307d0b6281f1161f40Douglas Gregor 31933064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek case CXCursor_CXXBaseSpecifier: { 31943064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); 31953064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), 31963064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek CXXUnit)); 31973064ef9e604d19a0cfd0d8e3ed3055bfd83f88fdTed Kremenek } 3198f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 319936897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor case CXCursor_LabelRef: 320036897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor // FIXME: We end up faking the "parent" declaration here because we 320136897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor // don't want to make CXCursor larger. 320236897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor return MakeCXCursor(getCursorLabelRef(C).first, 320336897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor CXXUnit->getASTContext().getTranslationUnitDecl(), 320436897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor CXXUnit); 320536897b05ca2886e287f01802614bc10cbadcec22Douglas Gregor 32061f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case CXCursor_OverloadedDeclRef: 32071f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return C; 32081f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 3209c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor default: 3210c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor // We would prefer to enumerate all non-reference cursor kinds here. 3211c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor llvm_unreachable("Unhandled reference cursor kind"); 3212c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor break; 3213c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor } 3214c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor } 3215f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3216c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor return clang_getNullCursor(); 3217c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor} 3218c5d1e9375d71e66d22456e7cc52cc7c0a5c65c3fDouglas Gregor 3219b699866820102a69d83d6ac6941985c5ef4e8c40Douglas GregorCXCursor clang_getCursorDefinition(CXCursor C) { 3220b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor if (clang_isInvalid(C.kind)) 3221b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getNullCursor(); 3222f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3223b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor ASTUnit *CXXUnit = getCursorASTUnit(C); 3224f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3225b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor bool WasReference = false; 322697b9872d5775446cb8aca1380e437649fe848d91Douglas Gregor if (clang_isReference(C.kind) || clang_isExpression(C.kind)) { 3227b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor C = clang_getCursorReferenced(C); 3228b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor WasReference = true; 3229b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3230b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3231bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor if (C.kind == CXCursor_MacroInstantiation) 3232bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor return clang_getCursorReferenced(C); 3233bf7efa2742dc94363d3561d284c9d634fc5a780fDouglas Gregor 3234b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!clang_isDeclaration(C.kind)) 3235b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3236b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3237b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor Decl *D = getCursorDecl(C); 3238b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!D) 3239b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3240f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3241b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor switch (D->getKind()) { 3242b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Declaration kinds that don't really separate the notions of 3243b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // declaration and definition. 3244b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Namespace: 3245b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Typedef: 3246b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::TemplateTypeParm: 3247b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::EnumConstant: 3248b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Field: 3249b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCIvar: 3250b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCAtDefsField: 3251b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ImplicitParam: 3252b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ParmVar: 3253b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::NonTypeTemplateParm: 3254b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::TemplateTemplateParm: 3255b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCCategoryImpl: 3256b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCImplementation: 32576206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara case Decl::AccessSpec: 3258b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::LinkageSpec: 3259b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCPropertyImpl: 3260b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::FileScopeAsm: 3261b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::StaticAssert: 3262b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Block: 3263b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 3264b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3265b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Declaration kinds that don't make any sense here, but are 3266b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // nonetheless harmless. 3267b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::TranslationUnit: 3268b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor break; 3269b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3270b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Declaration kinds for which the definition is not resolvable. 3271b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UnresolvedUsingTypename: 3272b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UnresolvedUsingValue: 3273b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor break; 3274b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3275b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UsingDirective: 3276b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(), 3277b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor CXXUnit); 3278b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3279b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::NamespaceAlias: 3280b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), CXXUnit); 3281b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3282b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Enum: 3283b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Record: 3284b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXRecord: 3285b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ClassTemplateSpecialization: 3286b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ClassTemplatePartialSpecialization: 3287952b017601f9c82b51119c3a1600f1312a833db9Douglas Gregor if (TagDecl *Def = cast<TagDecl>(D)->getDefinition()) 3288b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Def, CXXUnit); 3289b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3290b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3291b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Function: 3292b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXMethod: 3293b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXConstructor: 3294b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXDestructor: 3295b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::CXXConversion: { 3296b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor const FunctionDecl *Def = 0; 3297b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (cast<FunctionDecl>(D)->getBody(Def)) 3298b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(const_cast<FunctionDecl *>(Def), CXXUnit); 3299b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3300b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3301b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3302b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Var: { 330331310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl // Ask the variable if it has a definition. 330431310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl if (VarDecl *Def = cast<VarDecl>(D)->getDefinition()) 330531310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl return MakeCXCursor(Def, CXXUnit); 330631310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl return clang_getNullCursor(); 3307b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3308f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3309b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::FunctionTemplate: { 3310b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor const FunctionDecl *Def = 0; 3311b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def)) 3312b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Def->getDescribedFunctionTemplate(), CXXUnit); 3313b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3314b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3315f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3316b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ClassTemplate: { 3317b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl() 3318952b017601f9c82b51119c3a1600f1312a833db9Douglas Gregor ->getDefinition()) 33190b36e614aa19df72885d5e0de996f7fbb9874ec3Douglas Gregor return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(), 3320b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor CXXUnit); 3321b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3322b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3323b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 33241f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case Decl::Using: 33251f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), 33261f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor D->getLocation(), CXXUnit); 3327b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3328b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::UsingShadow: 3329b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getCursorDefinition( 3330f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), 3331b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor CXXUnit)); 3332b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3333b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCMethod: { 3334b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D); 3335b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (Method->isThisDeclarationADefinition()) 3336b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 3337b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3338b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // Dig out the method definition in the associated 3339b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // @implementation, if we have it. 3340b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // FIXME: The ASTs should make finding the definition easier. 3341b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCInterfaceDecl *Class 3342b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) 3343b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCImplementationDecl *ClassImpl = Class->getImplementation()) 3344b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(), 3345b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor Method->isInstanceMethod())) 3346b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (Def->isThisDeclarationADefinition()) 3347b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Def, CXXUnit); 3348b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3349b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3350b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3351b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3352b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCCategory: 3353b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCCategoryImplDecl *Impl 3354b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = cast<ObjCCategoryDecl>(D)->getImplementation()) 3355b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Impl, CXXUnit); 3356b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3357b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3358b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCProtocol: 3359b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!cast<ObjCProtocolDecl>(D)->isForwardDecl()) 3360b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 3361b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3362b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3363b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCInterface: 3364b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // There are two notions of a "definition" for an Objective-C 3365b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // class: the interface and its implementation. When we resolved a 3366b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // reference to an Objective-C class, produce the @interface as 3367b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // the definition; when we were provided with the interface, 3368b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // produce the @implementation as the definition. 3369b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (WasReference) { 3370b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl()) 3371b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return C; 3372b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } else if (ObjCImplementationDecl *Impl 3373b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = cast<ObjCInterfaceDecl>(D)->getImplementation()) 3374b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Impl, CXXUnit); 3375b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3376f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3377b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCProperty: 3378b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // FIXME: We don't really know where to find the 3379b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor // ObjCPropertyImplDecls that implement this property. 3380b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3381b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3382b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::ObjCCompatibleAlias: 3383b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (ObjCInterfaceDecl *Class 3384b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface()) 3385b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!Class->isForwardDecl()) 3386b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return MakeCXCursor(Class, CXXUnit); 3387f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3388b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3389b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 33901f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case Decl::ObjCForwardProtocol: 33911f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D), 33921f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor D->getLocation(), CXXUnit); 3393b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 33941f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor case Decl::ObjCClass: 33951f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(), 33961f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor CXXUnit); 3397b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3398b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::Friend: 3399b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl()) 3400b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit)); 3401b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3402b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3403b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor case Decl::FriendTemplate: 3404b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl()) 3405b2cd48756119f4d8d2a865b4b3e0e8efd02e26a0Douglas Gregor return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit)); 3406b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3407b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor } 3408b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3409b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getNullCursor(); 3410b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor} 3411b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3412b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregorunsigned clang_isCursorDefinition(CXCursor C) { 3413b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor if (!clang_isDeclaration(C.kind)) 3414b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return 0; 3415b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 3416b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor return clang_getCursorDefinition(C) == C; 3417b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor} 3418b699866820102a69d83d6ac6941985c5ef4e8c40Douglas Gregor 34191f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregorunsigned clang_getNumOverloadedDecls(CXCursor C) { 34207c432dd959609a3689c2e4406450c092e6d76d6dDouglas Gregor if (C.kind != CXCursor_OverloadedDeclRef) 34211f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return 0; 34221f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34231f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first; 34241f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) 34251f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return E->getNumDecls(); 34261f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34271f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadedTemplateStorage *S 34281f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = Storage.dyn_cast<OverloadedTemplateStorage*>()) 34291f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return S->size(); 34301f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34311f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = Storage.get<Decl*>(); 34321f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) 34331f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return Using->getNumShadowDecls(); 34341f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D)) 34351f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return Classes->size(); 34361f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D)) 34371f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return Protocols->protocol_size(); 34381f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34391f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return 0; 34401f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 34411f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34421f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas GregorCXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) { 34437c432dd959609a3689c2e4406450c092e6d76d6dDouglas Gregor if (cursor.kind != CXCursor_OverloadedDeclRef) 34441f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return clang_getNullCursor(); 34451f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34461f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (index >= clang_getNumOverloadedDecls(cursor)) 34471f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return clang_getNullCursor(); 34481f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34491f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor ASTUnit *Unit = getCursorASTUnit(cursor); 34501f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first; 34511f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) 34521f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCXCursor(E->decls_begin()[index], Unit); 34531f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34541f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (OverloadedTemplateStorage *S 34551f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor = Storage.dyn_cast<OverloadedTemplateStorage*>()) 34561f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCXCursor(S->begin()[index], Unit); 34571f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34581f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor Decl *D = Storage.get<Decl*>(); 34591f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) { 34601f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor // FIXME: This is, unfortunately, linear time. 34611f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor UsingDecl::shadow_iterator Pos = Using->shadow_begin(); 34621f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor std::advance(Pos, index); 34631f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), Unit); 34641f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor } 34651f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34661f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D)) 34671f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCXCursor(Classes->begin()[index].getInterface(), Unit); 34681f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34691f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D)) 34701f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return MakeCXCursor(Protocols->protocol_begin()[index], Unit); 34711f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34721f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor return clang_getNullCursor(); 34731f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor} 34741f60d9ea523fc321d811fe880ba9a1ec74fa8f9bDouglas Gregor 34750d7dd222381390731151455ff06358b93d04d6d1Daniel Dunbarvoid clang_getDefinitionSpellingAndExtent(CXCursor C, 34764ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff const char **startBuf, 34774ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff const char **endBuf, 34784ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff unsigned *startLine, 34794ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff unsigned *startColumn, 34804ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff unsigned *endLine, 34819ebfa31222a704690e9b6b30b7a135fe44364bc2Daniel Dunbar unsigned *endColumn) { 3482283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor assert(getCursorDecl(C) && "CXCursor has null decl"); 3483283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C)); 34844ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff FunctionDecl *FD = dyn_cast<FunctionDecl>(ND); 34854ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody()); 3486f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 34874ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff SourceManager &SM = FD->getASTContext().getSourceManager(); 34884ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *startBuf = SM.getCharacterData(Body->getLBracLoc()); 34894ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *endBuf = SM.getCharacterData(Body->getRBracLoc()); 34904ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *startLine = SM.getSpellingLineNumber(Body->getLBracLoc()); 34914ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc()); 34924ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *endLine = SM.getSpellingLineNumber(Body->getRBracLoc()); 34934ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc()); 34944ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff} 3495f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 34960a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregorvoid clang_enableStackTraces(void) { 34970a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor llvm::sys::PrintStackTraceOnErrorSignal(); 34980a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor} 34990a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor 3500fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C" 3501fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 3502fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 3503fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor// Token-based Operations. 3504fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor//===----------------------------------------------------------------------===// 3505fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3506fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor/* CXToken layout: 3507fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[0]: a CXTokenKind 3508fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[1]: starting token location 3509fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[2]: token length 3510fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * int_data[3]: reserved 3511f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek * ptr_data: for identifiers and keywords, an IdentifierInfo*. 3512fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor * otherwise unused. 3513fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor */ 3514fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregorextern "C" { 3515fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3516fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXTokenKind clang_getTokenKind(CXToken CXTok) { 3517fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return static_cast<CXTokenKind>(CXTok.int_data[0]); 3518fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 3519fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3520fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) { 3521fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor switch (clang_getTokenKind(CXTok)) { 3522fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Identifier: 3523fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Keyword: 3524fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // We know we have an IdentifierInfo*, so use that. 3525ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data) 3526ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek ->getNameStart()); 3527fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3528fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Literal: { 3529fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // We have stashed the starting pointer in the ptr_data field. Use it. 3530fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor const char *Text = static_cast<const char *>(CXTok.ptr_data); 3531ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(llvm::StringRef(Text, CXTok.int_data[2])); 3532fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } 3533f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3534fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Punctuation: 3535fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor case CXToken_Comment: 3536fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor break; 3537fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } 3538f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3539f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek // We have to find the starting buffer pointer the hard way, by 3540fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // deconstructing the source location. 3541fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 3542fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (!CXXUnit) 3543ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(""); 3544f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3545fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]); 3546fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor std::pair<FileID, unsigned> LocInfo 3547fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = CXXUnit->getSourceManager().getDecomposedLoc(Loc); 3548f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor bool Invalid = false; 3549f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer llvm::StringRef Buffer 3550f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); 3551f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor if (Invalid) 3552aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor return createCXString(""); 3553fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3554f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2])); 3555fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 3556f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3557fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) { 3558fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 3559fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (!CXXUnit) 3560fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return clang_getNullLocation(); 3561f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3562fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return cxloc::translateSourceLocation(CXXUnit->getASTContext(), 3563fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceLocation::getFromRawEncoding(CXTok.int_data[1])); 3564fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 3565fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 3566fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas GregorCXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) { 3567fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 35685352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor if (!CXXUnit) 35695352ac06d8f6194825bb2a99ffa009b61bafb503Douglas Gregor return clang_getNullRange(); 3570f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3571f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek return cxloc::translateSourceRange(CXXUnit->getASTContext(), 3572fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceLocation::getFromRawEncoding(CXTok.int_data[1])); 3573fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 3574f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3575fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregorvoid clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, 3576fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXToken **Tokens, unsigned *NumTokens) { 3577fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (Tokens) 3578fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *Tokens = 0; 3579fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (NumTokens) 3580fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *NumTokens = 0; 3581f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3582fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 3583fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (!CXXUnit || !Tokens || !NumTokens) 3584fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 3585f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3586bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor ASTUnit::ConcurrencyCheck Check(*CXXUnit); 3587bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor 358885b988fdfa6adab6d43e16efd19ad4f3f7e2b49bDaniel Dunbar SourceRange R = cxloc::translateCXSourceRange(Range); 3589fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (R.isInvalid()) 3590fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 3591f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3592fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor SourceManager &SourceMgr = CXXUnit->getSourceManager(); 3593fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor std::pair<FileID, unsigned> BeginLocInfo 3594fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = SourceMgr.getDecomposedLoc(R.getBegin()); 3595fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor std::pair<FileID, unsigned> EndLocInfo 3596fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = SourceMgr.getDecomposedLoc(R.getEnd()); 3597f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3598fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Cannot tokenize across files. 3599fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (BeginLocInfo.first != EndLocInfo.first) 3600fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 3601f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3602f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek // Create a lexer 3603f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor bool Invalid = false; 3604f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer llvm::StringRef Buffer 3605f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid); 360647a3fcd4afe122b23f9e7b6148f147bfa460cfe8Douglas Gregor if (Invalid) 360747a3fcd4afe122b23f9e7b6148f147bfa460cfe8Douglas Gregor return; 3608aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor 3609fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), 3610fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXXUnit->getASTContext().getLangOptions(), 3611f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end()); 3612fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Lex.SetCommentRetentionState(true); 3613f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3614fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Lex tokens until we hit the end of the range. 3615f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second; 3616fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor llvm::SmallVector<CXToken, 32> CXTokens; 3617fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Token Tok; 3618096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall bool previousWasAt = false; 3619fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor do { 3620fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Lex the next token 3621fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor Lex.LexFromRawLexer(Tok); 3622fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (Tok.is(tok::eof)) 3623fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor break; 3624f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3625fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // Initialize the CXToken. 3626fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXToken CXTok; 3627f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3628fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // - Common fields 3629fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[1] = Tok.getLocation().getRawEncoding(); 3630fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[2] = Tok.getLength(); 3631fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[3] = 0; 3632f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3633fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor // - Kind-specific fields 3634fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (Tok.isLiteral()) { 3635fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[0] = CXToken_Literal; 3636fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = (void *)Tok.getLiteralData(); 3637fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } else if (Tok.is(tok::identifier)) { 3638aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor // Lookup the identifier to determine whether we have a keyword. 3639fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor std::pair<FileID, unsigned> LocInfo 3640fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = SourceMgr.getDecomposedLoc(Tok.getLocation()); 3641f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor bool Invalid = false; 3642f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer llvm::StringRef Buf 3643f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); 3644f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor if (Invalid) 3645aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor return; 3646aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor 3647f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer const char *StartPos = Buf.data() + LocInfo.second; 3648fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor IdentifierInfo *II 3649fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok, StartPos); 3650aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek 3651096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) { 3652aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek CXTok.int_data[0] = CXToken_Keyword; 3653aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek } 3654aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek else { 3655aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek CXTok.int_data[0] = II->getTokenID() == tok::identifier? 3656aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek CXToken_Identifier 3657aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek : CXToken_Keyword; 3658aa8a66de0e7951ba5a305f3e5a39c9b14a318c42Ted Kremenek } 3659fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = II; 3660fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } else if (Tok.is(tok::comment)) { 3661fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[0] = CXToken_Comment; 3662fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = 0; 3663fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } else { 3664fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.int_data[0] = CXToken_Punctuation; 3665fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTok.ptr_data = 0; 3666fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } 3667fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXTokens.push_back(CXTok); 3668096428b351ebf5de9871ce11e06ba6f2d8276ab5David Chisnall previousWasAt = Tok.is(tok::at); 3669fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor } while (Lex.getBufferLocation() <= EffectiveBufferEnd); 3670f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3671fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor if (CXTokens.empty()) 3672fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor return; 3673f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 3674fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size()); 3675fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); 3676fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor *NumTokens = CXTokens.size(); 3677fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 36780045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor 36796db610934bedc6896393c1e1099525b35380acd6Ted Kremenekvoid clang_disposeTokens(CXTranslationUnit TU, 36806db610934bedc6896393c1e1099525b35380acd6Ted Kremenek CXToken *Tokens, unsigned NumTokens) { 36816db610934bedc6896393c1e1099525b35380acd6Ted Kremenek free(Tokens); 36826db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} 36836db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 36846db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} // end: extern "C" 36856db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 36866db610934bedc6896393c1e1099525b35380acd6Ted Kremenek//===----------------------------------------------------------------------===// 36876db610934bedc6896393c1e1099525b35380acd6Ted Kremenek// Token annotation APIs. 36886db610934bedc6896393c1e1099525b35380acd6Ted Kremenek//===----------------------------------------------------------------------===// 36896db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 36900045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregortypedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData; 3691fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekstatic enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, 3692fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXCursor parent, 3693fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXClientData client_data); 36946db610934bedc6896393c1e1099525b35380acd6Ted Kremeneknamespace { 36956db610934bedc6896393c1e1099525b35380acd6Ted Kremenekclass AnnotateTokensWorker { 36966db610934bedc6896393c1e1099525b35380acd6Ted Kremenek AnnotateTokensData &Annotated; 369711949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek CXToken *Tokens; 369811949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek CXCursor *Cursors; 369911949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek unsigned NumTokens; 3700fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek unsigned TokIdx; 37014419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor unsigned PreprocessingTokIdx; 3702fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CursorVisitor AnnotateVis; 3703fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceManager &SrcMgr; 3704fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3705fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek bool MoreTokens() const { return TokIdx < NumTokens; } 3706fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek unsigned NextToken() const { return TokIdx; } 3707fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek void AdvanceToken() { ++TokIdx; } 3708fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation GetTokenLoc(unsigned tokI) { 3709fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]); 3710fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 3711fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 37126db610934bedc6896393c1e1099525b35380acd6Ted Kremenekpublic: 371311949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek AnnotateTokensWorker(AnnotateTokensData &annotated, 3714fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXToken *tokens, CXCursor *cursors, unsigned numTokens, 3715fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek ASTUnit *CXXUnit, SourceRange RegionOfInterest) 371611949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek : Annotated(annotated), Tokens(tokens), Cursors(cursors), 37174419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0), 3718fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AnnotateVis(CXXUnit, AnnotateTokensVisitor, this, 3719fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Decl::MaxPCHLevel, RegionOfInterest), 3720fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SrcMgr(CXXUnit->getSourceManager()) {} 372111949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek 3722fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); } 37236db610934bedc6896393c1e1099525b35380acd6Ted Kremenek enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent); 3724fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek void AnnotateTokens(CXCursor parent); 37256db610934bedc6896393c1e1099525b35380acd6Ted Kremenek}; 37266db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} 37270045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor 3728fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenekvoid AnnotateTokensWorker::AnnotateTokens(CXCursor parent) { 3729fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Walk the AST within the region of interest, annotating tokens 3730fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // along the way. 3731fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek VisitChildren(parent); 3732fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3733fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek for (unsigned I = 0 ; I < TokIdx ; ++I) { 373411949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); 37354419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor if (Pos != Annotated.end() && 37364419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor (clang_isInvalid(Cursors[I].kind) || 37374419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor Pos->second.kind != CXCursor_PreprocessingDirective)) 3738fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = Pos->second; 3739fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 3740fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3741fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Finish up annotating any tokens left. 3742fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (!MoreTokens()) 3743fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return; 374411949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek 3745fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const CXCursor &C = clang_getNullCursor(); 3746fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek for (unsigned I = TokIdx ; I < NumTokens ; ++I) { 3747fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); 3748fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second; 374911949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek } 375011949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek} 375111949cbae3f42c32a2933fb85b125620666d98eaTed Kremenek 37526db610934bedc6896393c1e1099525b35380acd6Ted Kremenekenum CXChildVisitResult 37534419b675577d7c281a659fab1fec10e1bfbe04c5Douglas GregorAnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { 3754fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXSourceLocation Loc = clang_getCursorLocation(cursor); 37554419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor SourceRange cursorRange = getRawCursorExtent(cursor); 375681d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor if (cursorRange.isInvalid()) 375781d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor return CXChildVisit_Recurse; 375881d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor 37594419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor if (clang_isPreprocessing(cursor.kind)) { 37604419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // For macro instantiations, just note where the beginning of the macro 37614419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // instantiation occurs. 37624419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor if (cursor.kind == CXCursor_MacroInstantiation) { 37634419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor Annotated[Loc.int_data] = cursor; 37644419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor return CXChildVisit_Recurse; 37654419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 37664419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 37674419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Items in the preprocessing record are kept separate from items in 37684419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // declarations, so we keep a separate token index. 37694419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor unsigned SavedTokIdx = TokIdx; 37704419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor TokIdx = PreprocessingTokIdx; 37714419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 37724419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Skip tokens up until we catch up to the beginning of the preprocessing 37734419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // entry. 37744419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor while (MoreTokens()) { 37754419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor const unsigned I = NextToken(); 37764419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor SourceLocation TokLoc = GetTokenLoc(I); 37774419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 37784419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeBefore: 37794419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor AdvanceToken(); 37804419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor continue; 37814419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeAfter: 37824419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeOverlap: 37834419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 37844419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 37854419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 37864419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 37874419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 37884419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Look at all of the tokens within this range. 37894419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor while (MoreTokens()) { 37904419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor const unsigned I = NextToken(); 37914419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor SourceLocation TokLoc = GetTokenLoc(I); 37924419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 37934419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeBefore: 37944419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor assert(0 && "Infeasible"); 37954419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeAfter: 37964419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 37974419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor case RangeOverlap: 37984419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor Cursors[I] = cursor; 37994419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor AdvanceToken(); 38004419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor continue; 38014419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 38024419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor break; 38034419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor } 38044419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 38054419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Save the preprocessing token index; restore the non-preprocessing 38064419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // token index. 38074419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor PreprocessingTokIdx = TokIdx; 38084419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor TokIdx = SavedTokIdx; 38090045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor return CXChildVisit_Recurse; 38100045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor } 3811fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3812fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (cursorRange.isInvalid()) 3813fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return CXChildVisit_Continue; 3814a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek 3815fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data); 3816fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3817a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek // Adjust the annotated range based specific declarations. 3818a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek const enum CXCursorKind cursorK = clang_getCursorKind(cursor); 3819a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) { 382023173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek Decl *D = cxcursor::getCursorDecl(cursor); 382123173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // Don't visit synthesized ObjC methods, since they have no syntatic 382223173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek // representation in the source. 382323173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 382423173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (MD->isSynthesized()) 382523173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek return CXChildVisit_Continue; 382623173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek } 382723173d7f029f430611caceea72ae61ba6b80af1cTed Kremenek if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { 3828a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) { 3829a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek TypeLoc TL = TI->getTypeLoc(); 3830bd054dba8a3023821f2a0951b0fae05e3522a7c9Abramo Bagnara SourceLocation TLoc = TL.getSourceRange().getBegin(); 383181d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor if (TLoc.isValid() && L.isValid() && 38326bfd53360072409715fe4e4d4f41d9ebdf948479Ted Kremenek SrcMgr.isBeforeInTranslationUnit(TLoc, L)) 3833a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek cursorRange.setBegin(TLoc); 3834a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek } 3835a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek } 3836a333c66b94f6d6dcd5ee7e625d816d3c0300e8e6Ted Kremenek } 383781d3c04b0934c43518355289ad104d34f6fde06fDouglas Gregor 38383f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // If the location of the cursor occurs within a macro instantiation, record 38393f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // the spelling location of the cursor in our annotation map. We can then 38403f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // paper over the token labelings during a post-processing step to try and 38413f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // get cursor mappings for tokens that are the *arguments* of a macro 38423f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // instantiation. 38433f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek if (L.isMacroID()) { 38443f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding(); 38453f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // Only invalidate the old annotation if it isn't part of a preprocessing 38463f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // directive. Here we assume that the default construction of CXCursor 38473f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // results in CXCursor.kind being an initialized value (i.e., 0). If 38483f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek // this isn't the case, we can fix by doing lookup + insertion. 38494419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 38503f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek CXCursor &oldC = Annotated[rawEncoding]; 38513f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek if (!clang_isPreprocessing(oldC.kind)) 38523f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek oldC = cursor; 38533f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek } 38543f4046004be223b03f1f895bb934e44921ccf805Ted Kremenek 3855fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const enum CXCursorKind K = clang_getCursorKind(parent); 3856fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const CXCursor updateC = 3857d8b0a84d586bc0a08695968acf2f169c9d01da69Ted Kremenek (clang_isInvalid(K) || K == CXCursor_TranslationUnit) 3858d8b0a84d586bc0a08695968acf2f169c9d01da69Ted Kremenek ? clang_getNullCursor() : parent; 3859fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3860fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek while (MoreTokens()) { 3861fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned I = NextToken(); 3862fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation TokLoc = GetTokenLoc(I); 3863fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 3864fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeBefore: 3865fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = updateC; 3866fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AdvanceToken(); 3867fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek continue; 3868fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeAfter: 3869fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeOverlap: 3870fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek break; 3871fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 3872fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek break; 3873fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 3874fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3875fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Visit children to get their cursor information. 3876fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned BeforeChildren = NextToken(); 3877fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek VisitChildren(cursor); 3878fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned AfterChildren = NextToken(); 3879fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3880fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Adjust 'Last' to the last token within the extent of the cursor. 3881fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek while (MoreTokens()) { 3882fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned I = NextToken(); 3883fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek SourceLocation TokLoc = GetTokenLoc(I); 3884fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 3885fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeBefore: 3886fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek assert(0 && "Infeasible"); 3887fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeAfter: 3888fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek break; 3889fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek case RangeOverlap: 3890fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = updateC; 3891fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AdvanceToken(); 3892fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek continue; 3893fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 3894fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek break; 3895fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 3896fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek const unsigned Last = NextToken(); 38976db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 3898fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Scan the tokens that are at the beginning of the cursor, but are not 3899fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // capture by the child cursors. 3900fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3901fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // For AST elements within macros, rely on a post-annotate pass to 3902fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // to correctly annotate the tokens with cursors. Otherwise we can 3903fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // get confusing results of having tokens that map to cursors that really 3904fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // are expanded by an instantiation. 3905fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (L.isMacroID()) 3906fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek cursor = clang_getNullCursor(); 3907fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3908fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek for (unsigned I = BeforeChildren; I != AfterChildren; ++I) { 3909fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (!clang_isInvalid(clang_getCursorKind(Cursors[I]))) 3910fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek break; 39114419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 3912fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = cursor; 3913fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek } 3914fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Scan the tokens that are at the end of the cursor, but are not captured 3915fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // but the child cursors. 3916fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek for (unsigned I = AfterChildren; I != Last; ++I) 3917fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Cursors[I] = cursor; 3918fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3919fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek TokIdx = Last; 3920fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek return CXChildVisit_Continue; 39210045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor} 39220045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor 39236db610934bedc6896393c1e1099525b35380acd6Ted Kremenekstatic enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, 39246db610934bedc6896393c1e1099525b35380acd6Ted Kremenek CXCursor parent, 39256db610934bedc6896393c1e1099525b35380acd6Ted Kremenek CXClientData client_data) { 39266db610934bedc6896393c1e1099525b35380acd6Ted Kremenek return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent); 39276db610934bedc6896393c1e1099525b35380acd6Ted Kremenek} 39286db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 39296db610934bedc6896393c1e1099525b35380acd6Ted Kremenekextern "C" { 39306db610934bedc6896393c1e1099525b35380acd6Ted Kremenek 3931fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregorvoid clang_annotateTokens(CXTranslationUnit TU, 3932fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXToken *Tokens, unsigned NumTokens, 3933fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor CXCursor *Cursors) { 3934fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3935fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek if (NumTokens == 0 || !Tokens || !Cursors) 39360045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor return; 3937fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 39384419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor // Any token we don't specifically annotate will have a NULL cursor. 39394419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor CXCursor C = clang_getNullCursor(); 39404419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor for (unsigned I = 0; I != NumTokens; ++I) 39414419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor Cursors[I] = C; 39424419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor 39430045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); 39444419b675577d7c281a659fab1fec10e1bfbe04c5Douglas Gregor if (!CXXUnit) 39450045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor return; 3946fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3947bdf6062bc10aa3b73b16402b440b8073310acd06Douglas Gregor ASTUnit::ConcurrencyCheck Check(*CXXUnit); 3948fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 39490396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // Determine the region of interest, which contains all of the tokens. 39500045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor SourceRange RegionOfInterest; 3951fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek RegionOfInterest.setBegin(cxloc::translateSourceLocation( 3952fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek clang_getTokenLocation(TU, Tokens[0]))); 3953a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor RegionOfInterest.setEnd(cxloc::translateSourceLocation( 3954a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor clang_getTokenLocation(TU, 3955a8e5c5bdbe387b2552c1c23b828f54abcf085a40Douglas Gregor Tokens[NumTokens - 1]))); 3956fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 39570396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // A mapping from the source locations found when re-lexing or traversing the 39580396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // region of interest to the corresponding cursors. 39590045e9fe1f7dfc37f1ea7bdb9b70bcdb6700f0c0Douglas Gregor AnnotateTokensData Annotated; 3960fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3961fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Relex the tokens within the source range to look for preprocessing 39620396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // directives. 39639f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor SourceManager &SourceMgr = CXXUnit->getSourceManager(); 39649f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor std::pair<FileID, unsigned> BeginLocInfo 39659f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin()); 39669f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor std::pair<FileID, unsigned> EndLocInfo 39679f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd()); 3968fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 39699f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor llvm::StringRef Buffer; 39700396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor bool Invalid = false; 39710396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (BeginLocInfo.first == EndLocInfo.first && 39720396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) && 39730396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor !Invalid) { 39749f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), 39759f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor CXXUnit->getASTContext().getLangOptions(), 3976fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Buffer.begin(), Buffer.data() + BeginLocInfo.second, 39774ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor Buffer.end()); 39789f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Lex.SetCommentRetentionState(true); 3979fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 3980fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // Lex tokens in raw mode until we hit the end of the range, to avoid 39819f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // entering #includes or expanding macros. 39824807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor while (true) { 39839f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Token Tok; 39849f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Lex.LexFromRawLexer(Tok); 3985fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 39869f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor reprocess: 39879f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) { 39889f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // We have found a preprocessing directive. Gobble it up so that we 39899f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // don't see it while preprocessing these tokens later, but keep track of 39909f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // all of the token locations inside this preprocessing directive so that 39919f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // we can annotate them appropriately. 39929f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // 39939f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // FIXME: Some simple tests here could identify macro definitions and 39949f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor // #undefs, to provide specific cursor kinds for those. 39959f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor std::vector<SourceLocation> Locations; 39969f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor do { 39979f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Locations.push_back(Tok.getLocation()); 3998fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Lex.LexFromRawLexer(Tok); 39999f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof)); 4000fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 40019f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor using namespace cxcursor; 40029f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor CXCursor Cursor 4003fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(), 4004fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek Locations.back()), 40056db610934bedc6896393c1e1099525b35380acd6Ted Kremenek CXXUnit); 40069f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor for (unsigned I = 0, N = Locations.size(); I != N; ++I) { 40079f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor Annotated[Locations[I].getRawEncoding()] = Cursor; 40089f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 4009fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 40109f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor if (Tok.isAtStartOfLine()) 40119f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor goto reprocess; 4012fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 40139f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor continue; 40149f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 4015fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 40164807231938d8aff28de09f78f301f9ba5845e5e4Douglas Gregor if (Tok.is(tok::eof)) 40179f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor break; 40189f1e3ff3b3095967e2b92b57a53524e2d6bb141cDouglas Gregor } 40194ae8f298b1ea51b4c2234f9148e2e4349c9bdd23Douglas Gregor } 4020fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek 40210396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor // Annotate all of the source locations in the region of interest that map to 4022fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek // a specific cursor. 4023fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens, 4024fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek CXXUnit, RegionOfInterest); 4025fbd84caf62a21afa4db5f730e2e2603ead17bb65Ted Kremenek W.AnnotateTokens(clang_getTranslationUnitCursor(CXXUnit)); 4026fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} 4027fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor} // end: extern "C" 4028fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor 4029fc8ea23eb6cbaaa5046f2abb4c033e24c8659efdDouglas Gregor//===----------------------------------------------------------------------===// 403016b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek// Operations for querying linkage of a cursor. 403116b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek//===----------------------------------------------------------------------===// 403216b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek 403316b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenekextern "C" { 403416b4259aecaa22b642d35d36fd89965ed700c1e0Ted KremenekCXLinkageKind clang_getCursorLinkage(CXCursor cursor) { 40350396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor if (!clang_isDeclaration(cursor.kind)) 40360396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor return CXLinkage_Invalid; 40370396f466978d65789eca85b2738e9df53adc78f5Douglas Gregor 403816b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek Decl *D = cxcursor::getCursorDecl(cursor); 403916b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D)) 404016b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek switch (ND->getLinkage()) { 404116b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case NoLinkage: return CXLinkage_NoLinkage; 404216b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case InternalLinkage: return CXLinkage_Internal; 404316b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case UniqueExternalLinkage: return CXLinkage_UniqueExternal; 404416b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek case ExternalLinkage: return CXLinkage_External; 404516b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek }; 404616b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek 404716b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek return CXLinkage_Invalid; 404816b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek} 404916b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek} // end: extern "C" 405016b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek 405116b4259aecaa22b642d35d36fd89965ed700c1e0Ted Kremenek//===----------------------------------------------------------------------===// 405245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek// Operations for querying language of a cursor. 405345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek//===----------------------------------------------------------------------===// 405445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 405545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenekstatic CXLanguageKind getDeclLanguage(const Decl *D) { 405645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek switch (D->getKind()) { 405745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek default: 405845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek break; 405945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ImplicitParam: 406045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCAtDefsField: 406145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCCategory: 406245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCCategoryImpl: 406345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCClass: 406445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCCompatibleAlias: 406545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCForwardProtocol: 406645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCImplementation: 406745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCInterface: 406845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCIvar: 406945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCMethod: 407045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCProperty: 407145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCPropertyImpl: 407245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ObjCProtocol: 407345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_ObjC; 407445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXConstructor: 407545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXConversion: 407645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXDestructor: 407745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXMethod: 407845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::CXXRecord: 407945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ClassTemplate: 408045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ClassTemplatePartialSpecialization: 408145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::ClassTemplateSpecialization: 408245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::Friend: 408345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::FriendTemplate: 408445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::FunctionTemplate: 408545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::LinkageSpec: 408645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::Namespace: 408745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::NamespaceAlias: 408845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::NonTypeTemplateParm: 408945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::StaticAssert: 409045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::TemplateTemplateParm: 409145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::TemplateTypeParm: 409245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UnresolvedUsingTypename: 409345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UnresolvedUsingValue: 409445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::Using: 409545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UsingDirective: 409645e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek case Decl::UsingShadow: 409745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_CPlusPlus; 409845e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek } 409945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 410045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_C; 410145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek} 410245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 410345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenekextern "C" { 410458ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 410558ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregorenum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) { 410658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor if (clang_isDeclaration(cursor.kind)) 410758ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor if (Decl *D = cxcursor::getCursorDecl(cursor)) { 410858ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor if (D->hasAttr<UnavailableAttr>() || 410958ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())) 411058ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor return CXAvailability_Available; 411158ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 411258ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor if (D->hasAttr<DeprecatedAttr>()) 411358ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor return CXAvailability_Deprecated; 411458ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor } 411558ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 411658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor return CXAvailability_Available; 411758ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor} 411858ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor 411945e1dae500bba7a9ef5b8206263a5609c07c6f03Ted KremenekCXLanguageKind clang_getCursorLanguage(CXCursor cursor) { 412045e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek if (clang_isDeclaration(cursor.kind)) 412145e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return getDeclLanguage(cxcursor::getCursorDecl(cursor)); 412245e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 412345e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek return CXLanguage_Invalid; 412445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek} 41252be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 41262be5bc9ad3981347a000742f81b91ab3080f1214Douglas GregorCXCursor clang_getCursorSemanticParent(CXCursor cursor) { 41272be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (clang_isDeclaration(cursor.kind)) { 41282be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (Decl *D = getCursorDecl(cursor)) { 41292be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor DeclContext *DC = D->getDeclContext(); 41302be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return MakeCXCursor(cast<Decl>(DC), getCursorASTUnit(cursor)); 41312be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 41322be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 41332be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 41342be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) { 41352be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (Decl *D = getCursorDecl(cursor)) 41362be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return MakeCXCursor(D, getCursorASTUnit(cursor)); 41372be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 41382be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 41392be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return clang_getNullCursor(); 41402be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor} 41412be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 41422be5bc9ad3981347a000742f81b91ab3080f1214Douglas GregorCXCursor clang_getCursorLexicalParent(CXCursor cursor) { 41432be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (clang_isDeclaration(cursor.kind)) { 41442be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor if (Decl *D = getCursorDecl(cursor)) { 41452be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor DeclContext *DC = D->getLexicalDeclContext(); 41462be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return MakeCXCursor(cast<Decl>(DC), getCursorASTUnit(cursor)); 41472be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 41482be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor } 41492be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 41502be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor // FIXME: Note that we can't easily compute the lexical context of a 41512be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor // statement or expression, so we return nothing. 41522be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor return clang_getNullCursor(); 41532be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor} 41542be5bc9ad3981347a000742f81b91ab3080f1214Douglas Gregor 41559f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorstatic void CollectOverriddenMethods(DeclContext *Ctx, 41569f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor ObjCMethodDecl *Method, 41579f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) { 41589f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!Ctx) 41599f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 41609f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 41619f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // If we have a class or category implementation, jump straight to the 41629f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // interface. 41639f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx)) 41649f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods); 41659f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 41669f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx); 41679f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!Container) 41689f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 41699f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 41709f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // Check whether we have a matching method at this level. 41719f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(), 41729f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Method->isInstanceMethod())) 41739f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (Method != Overridden) { 41749f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // We found an override at this level; there is no need to look 41759f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // into other protocols or categories. 41769f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Methods.push_back(Overridden); 41779f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 41789f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 41799f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 41809f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { 41819f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(), 41829f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor PEnd = Protocol->protocol_end(); 41839f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor P != PEnd; ++P) 41849f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(*P, Method, Methods); 41859f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 41869f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 41879f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) { 41889f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(), 41899f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor PEnd = Category->protocol_end(); 41909f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor P != PEnd; ++P) 41919f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(*P, Method, Methods); 41929f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 41939f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 41949f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) { 41959f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(), 41969f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor PEnd = Interface->protocol_end(); 41979f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor P != PEnd; ++P) 41989f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(*P, Method, Methods); 41999f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42009f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (ObjCCategoryDecl *Category = Interface->getCategoryList(); 42019f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Category; Category = Category->getNextClassCategory()) 42029f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(Category, Method, Methods); 42039f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42049f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // We only look into the superclass if we haven't found anything yet. 42059f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (Methods.empty()) 42069f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) 42079f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return CollectOverriddenMethods(Super, Method, Methods); 42089f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 42099f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor} 42109f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42119f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorvoid clang_getOverriddenCursors(CXCursor cursor, 42129f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CXCursor **overridden, 42139f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor unsigned *num_overridden) { 42149f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (overridden) 42159f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *overridden = 0; 42169f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (num_overridden) 42179f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *num_overridden = 0; 42189f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!overridden || !num_overridden) 42199f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 42209f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42219f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!clang_isDeclaration(cursor.kind)) 42229f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 42239f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42249f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor Decl *D = getCursorDecl(cursor); 42259f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!D) 42269f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 42279f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42289f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // Handle C++ member functions. 42299f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor ASTUnit *CXXUnit = getCursorASTUnit(cursor); 42309f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) { 42319f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *num_overridden = CXXMethod->size_overridden_methods(); 42329f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!*num_overridden) 42339f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 42349f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42359f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *overridden = new CXCursor [*num_overridden]; 42369f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor unsigned I = 0; 42379f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (CXXMethodDecl::method_iterator 42389f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor M = CXXMethod->begin_overridden_methods(), 42399f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor MEnd = CXXMethod->end_overridden_methods(); 42409f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor M != MEnd; (void)++M, ++I) 42419f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), CXXUnit); 42429f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 42439f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor } 42449f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42459f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D); 42469f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (!Method) 42479f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 42489f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42499f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor // Handle Objective-C methods. 42509f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor llvm::SmallVector<ObjCMethodDecl *, 4> Methods; 42519f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor CollectOverriddenMethods(Method->getDeclContext(), Method, Methods); 42529f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42539f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor if (Methods.empty()) 42549f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor return; 42559f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42569f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *num_overridden = Methods.size(); 42579f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor *overridden = new CXCursor [Methods.size()]; 42589f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor for (unsigned I = 0, N = Methods.size(); I != N; ++I) 42599f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor (*overridden)[I] = MakeCXCursor(Methods[I], CXXUnit); 42609f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor} 42619f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 42629f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregorvoid clang_disposeOverriddenCursors(CXCursor *overridden) { 42639f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor delete [] overridden; 42649f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor} 42659f59234a91d057cee7c5e3cee91da8696858c692Douglas Gregor 4266ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas GregorCXFile clang_getIncludedFile(CXCursor cursor) { 4267ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor if (cursor.kind != CXCursor_InclusionDirective) 4268ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return 0; 4269ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 4270ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor InclusionDirective *ID = getCursorInclusionDirective(cursor); 4271ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor return (void *)ID->getFile(); 4272ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor} 4273ecdcb883cbc6bb4a2445dc6f02d58d9bdb54a0edDouglas Gregor 427445e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek} // end: extern "C" 427545e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek 42769ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek 42779ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek//===----------------------------------------------------------------------===// 42789ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek// C++ AST instrospection. 42799ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek//===----------------------------------------------------------------------===// 42809ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek 42819ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenekextern "C" { 42829ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenekunsigned clang_CXXMethod_isStatic(CXCursor C) { 42839ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek if (!clang_isDeclaration(C.kind)) 42849ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek return 0; 428549f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor 428649f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor CXXMethodDecl *Method = 0; 428749f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor Decl *D = cxcursor::getCursorDecl(C); 428849f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D)) 428949f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); 429049f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor else 429149f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor Method = dyn_cast_or_null<CXXMethodDecl>(D); 429249f6f5489483beaffc7ce48dfc000af4e65b9216Douglas Gregor return (Method && Method->isStatic()) ? 1 : 0; 429340b492a43bac3ed0c465772aa6921d011cfc273fTed Kremenek} 4294b12903e1a4b8d1b611b8c7e4f910665d628e68cdTed Kremenek 42959ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek} // end: extern "C" 42969ada39a4ac82ff5f5087b0a7fa9ed0d32be55a3bTed Kremenek 429745e1dae500bba7a9ef5b8206263a5609c07c6f03Ted Kremenek//===----------------------------------------------------------------------===// 429895f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek// Attribute introspection. 429995f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek//===----------------------------------------------------------------------===// 430095f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 430195f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenekextern "C" { 430295f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted KremenekCXType clang_getIBOutletCollectionType(CXCursor C) { 430395f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek if (C.kind != CXCursor_IBOutletCollectionAttr) 430495f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek return cxtype::MakeCXType(QualType(), cxcursor::getCursorASTUnit(C)); 430595f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 430695f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek IBOutletCollectionAttr *A = 430795f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C)); 430895f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 430995f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorASTUnit(C)); 431095f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek} 431195f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek} // end: extern "C" 431295f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek 431395f33555a6d51b6537a9ed3968c3d1c2e4991b51Ted Kremenek//===----------------------------------------------------------------------===// 4314fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek// CXString Operations. 4315fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek//===----------------------------------------------------------------------===// 4316fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek 4317fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekextern "C" { 4318fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekconst char *clang_getCString(CXString string) { 4319fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek return string.Spelling; 4320fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} 43214ade6d6eae934f796ca43c81a5aa185e456dde9bSteve Naroff 4322fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenekvoid clang_disposeString(CXString string) { 4323fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek if (string.MustFreeString && string.Spelling) 4324fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek free((void*)string.Spelling); 4325fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} 432604bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek 4327fb48049fd5f0457d9052269f6d84768412f5f6dfTed Kremenek} // end: extern "C" 432804bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek 4329ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremeneknamespace clang { namespace cxstring { 4330ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted KremenekCXString createCXString(const char *String, bool DupString){ 4331ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek CXString Str; 4332ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek if (DupString) { 4333ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Str.Spelling = strdup(String); 4334ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Str.MustFreeString = 1; 4335ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek } else { 4336ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Str.Spelling = String; 4337ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Str.MustFreeString = 0; 4338ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek } 4339ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return Str; 4340ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek} 4341ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek 4342ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted KremenekCXString createCXString(llvm::StringRef String, bool DupString) { 4343ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek CXString Result; 4344ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek if (DupString || (!String.empty() && String.data()[String.size()] != 0)) { 4345ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek char *Spelling = (char *)malloc(String.size() + 1); 4346ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek memmove(Spelling, String.data(), String.size()); 4347ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Spelling[String.size()] = 0; 4348ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Result.Spelling = Spelling; 4349ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Result.MustFreeString = 1; 4350ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek } else { 4351ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Result.Spelling = String.data(); 4352ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek Result.MustFreeString = 0; 4353ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek } 4354ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return Result; 4355ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek} 4356ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek}} 4357ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek 435804bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek//===----------------------------------------------------------------------===// 435904bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek// Misc. utility functions. 436004bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek//===----------------------------------------------------------------------===// 4361f0e23e8ad647f41d090d76cc09684ecf4bb05a5bTed Kremenek 436204bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenekextern "C" { 436304bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek 4364a2a9d6e4e5b6001b86b7dfc5db1ea296ce29a3d3Ted KremenekCXString clang_getClangVersion() { 4365ee4db4fccbcab7e6bd614fe8757c5453e7ad0e86Ted Kremenek return createCXString(getClangFullVersion()); 436604bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek} 436704bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek 436804bb716aea8fd2372ac10b0c640cabc5e5caa615Ted Kremenek} // end: extern "C" 4369