CIndex.cpp revision e42e578ad8a36ad5bd06c8a3110cbd3119aaee36
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===// 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 3fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt// The LLVM Compiler Infrastructure 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt// This file is distributed under the University of Illinois Open Source 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt// License. See LICENSE.TXT for details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===// 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// This file implements the main API hooks in the Clang-C Source Indexing 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// library. 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===// 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "CIndexer.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "CIndexDiagnostic.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "CLog.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "CXComment.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "CXCursor.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "CXSourceLocation.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "CXString.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "CXTranslationUnit.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "CXType.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "CursorVisitor.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "SimpleFormatContext.h" 2661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "clang/AST/StmtVisitor.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Basic/Diagnostic.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Basic/Version.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Frontend/ASTUnit.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Frontend/CompilerInstance.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Frontend/FrontendDiagnostic.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Lex/HeaderSearch.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Lex/Lexer.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Lex/PreprocessingRecord.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "clang/Lex/Preprocessor.h" 361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "llvm/ADT/Optional.h" 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/ADT/STLExtras.h" 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/ADT/StringSwitch.h" 3904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "llvm/Config/config.h" 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Support/Compiler.h" 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Support/CrashRecoveryContext.h" 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "llvm/Support/Format.h" 431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "llvm/Support/MemoryBuffer.h" 4461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "llvm/Support/Mutex.h" 4561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "llvm/Support/PrettyStackTrace.h" 4661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "llvm/Support/Program.h" 4734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#include "llvm/Support/SaveAndRestore.h" 488da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt#include "llvm/Support/Signals.h" 49e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#include "llvm/Support/Threading.h" 5034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt#include "llvm/Support/Timer.h" 514b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt#include "llvm/Support/raw_ostream.h" 524b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt 5361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#if HAVE_PTHREAD_H 5461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include <pthread.h> 5561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif 56fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 5761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtusing namespace clang; 5861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtusing namespace clang::cxcursor; 5961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtusing namespace clang::cxstring; 6061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtusing namespace clang::cxtu; 61fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtusing namespace clang::cxindex; 6261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry ShmidtCXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) { 6461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!AU) 6561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 6661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt CXTranslationUnit D = new CXTranslationUnitImpl(); 6761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt D->CIdx = CIdx; 6861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt D->TheASTUnit = AU; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt D->StringPool = createCXStringPool(); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt D->Diagnostics = 0; 71cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt D->OverridenCursorsPool = createOverridenCXCursorsPool(); 72cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt D->FormatContext = 0; 73cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt D->FormatInMemoryUniqueId = 0; 74cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return D; 75cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 76cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 77cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtcxtu::CXTUOwner::~CXTUOwner() { 78cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (TU) 79cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt clang_disposeTranslationUnit(TU); 80cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 81cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 82cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt/// \brief Compare two source ranges to determine their relative position in 83cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt/// the translation unit. 84cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtstatic RangeComparisonResult RangeCompare(SourceManager &SM, 85cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt SourceRange R1, 865c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen SourceRange R2) { 875c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen assert(R1.isValid() && "First range is invalid?"); 885c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen assert(R2.isValid() && "Second range is invalid?"); 895c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen if (R1.getEnd() != R2.getBegin() && 905c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin())) 915c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen return RangeBefore; 925c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen if (R2.getEnd() != R1.getBegin() && 935c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin())) 945c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen return RangeAfter; 955c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen return RangeOverlap; 965c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen} 975c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen 985c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen/// \brief Determine if a source location falls within, before, or after a 995c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen/// a given source range. 1005c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinenstatic RangeComparisonResult LocationCompare(SourceManager &SM, 1015c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen SourceLocation L, SourceRange R) { 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(R.isValid() && "First range is invalid?"); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(L.isValid() && "Second range is invalid?"); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (L == R.getBegin() || L == R.getEnd()) 10561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return RangeOverlap; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SM.isBeforeInTranslationUnit(L, R.getBegin())) 1075c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen return RangeBefore; 1085c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen if (SM.isBeforeInTranslationUnit(R.getEnd(), L)) 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RangeAfter; 1105c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen return RangeOverlap; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// \brief Translate a Clang source range into a CIndex source range. 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// Clang internally represents ranges where the end location points to the 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// start of the token at the end. However, for external clients it is more 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// useful to have a CXSourceRange be a proper half-open interval. This routine 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// does the appropriate translation. 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtCXSourceRange cxloc::translateSourceRange(const SourceManager &SM, 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const LangOptions &LangOpts, 12104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const CharSourceRange &R) { 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // We want the last character in this location, so we will adjust the 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // location accordingly. 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceLocation EndLoc = R.getEnd(); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc)) 126d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt EndLoc = SM.getExpansionRange(EndLoc).second; 127d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (R.isTokenRange() && !EndLoc.isInvalid()) { 128d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), 129d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt SM, LangOpts); 130d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt EndLoc = EndLoc.getLocWithOffset(Length); 131d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 13261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 13361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt CXSourceRange Result = { 13461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt { &SM, &LangOpts }, 13561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt R.getBegin().getRawEncoding(), 13661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt EndLoc.getRawEncoding() 13761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt }; 13861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return Result; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt//===----------------------------------------------------------------------===// 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// Cursor visitor. 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===// 144a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 145a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic SourceRange getRawCursorExtent(CXCursor C); 146a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr); 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtRangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) { 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return RangeCompare(AU->getSourceManager(), R, RegionOfInterest); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// \brief Visit the given cursor and, if requested by the visitor, 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// its children. 155cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt/// 1565c879ee8a1def48a71e0929d378c0912ef63bb3fJouni Malinen/// \param Cursor the cursor to visit. 157cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt/// 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// \param CheckedRegionOfInterest if true, then the caller already checked 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// that this cursor is within the region of interest. 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// \returns true if the visitation should be aborted, false if it 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// should continue. 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) { 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (clang_isInvalid(Cursor.kind)) 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (clang_isDeclaration(Cursor.kind)) { 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const Decl *D = getCursorDecl(Cursor); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!D) { 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(0 && "Invalid declaration cursor"); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; // abort. 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Ignore implicit declarations, unless it's an objc method because 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // currently we should report implicit methods for properties when indexing. 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (D->isImplicit() && !isa<ObjCMethodDecl>(D)) 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If we have a range of interest, and this cursor doesn't intersect with it, 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // we're done. 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) { 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceRange Range = getRawCursorExtent(Cursor); 18404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (Range.isInvalid() || CompareRegionOfInterest(Range)) 18504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return false; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (Visitor(Cursor, Parent, ClientData)) { 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CXChildVisit_Break: 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 191c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 192c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt case CXChildVisit_Continue: 193c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt return false; 194c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CXChildVisit_Recurse: { 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool ret = VisitChildren(Cursor); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (PostChildrenVisitor) 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (PostChildrenVisitor(Cursor, ClientData)) 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 20304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 20404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt llvm_unreachable("Invalid CXChildVisitResult!"); 205c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 206c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 207c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic bool visitPreprocessedEntitiesInRange(SourceRange R, 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PreprocessingRecord &PPRec, 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CursorVisitor &Visitor) { 210c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt SourceManager &SM = Visitor.getASTUnit()->getSourceManager(); 211c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt FileID FID; 212c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt 213c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt if (!Visitor.shouldVisitIncludedEntities()) { 214c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt // If the begin/end of the range lie in the same FileID, do the optimization 215c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt // where we skip preprocessed entities that do not come from the same FileID. 216c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt FID = SM.getFileID(SM.getFileLoc(R.getBegin())); 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (FID != SM.getFileID(SM.getFileLoc(R.getEnd()))) 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FID = FileID(); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Entities = PPRec.getPreprocessedEntitiesInRange(R); 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visitor.visitPreprocessedEntities(Entities.first, Entities.second, 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PPRec, FID); 22561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 226b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 22761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid CursorVisitor::visitFileRegion() { 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (RegionOfInterest.isInvalid()) 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ASTUnit *Unit = cxtu::getASTUnit(TU); 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceManager &SM = Unit->getSourceManager(); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt std::pair<FileID, unsigned> 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())), 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd())); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (End.first != Begin.first) { 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If the end does not reside in the same file, try to recover by 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // picking the end of the file of begin location. 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt End.first = Begin.first; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt End.second = SM.getFileIDSize(Begin.first); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(Begin.first == End.first); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Begin.second > End.second) 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FileID File = Begin.first; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned Offset = Begin.second; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned Length = End.second - Begin.second; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!VisitDeclsOnly && !VisitPreprocessorLast) 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (visitPreprocessedEntitiesInRegion()) 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; // visitation break. 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt visitDeclsFromFileRegion(File, Offset, Length); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!VisitDeclsOnly && VisitPreprocessorLast) 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt visitPreprocessedEntitiesInRegion(); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic bool isInLexicalContext(Decl *D, DeclContext *DC) { 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DC) 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (DeclContext *DeclDC = D->getLexicalDeclContext(); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DeclDC; DeclDC = DeclDC->getLexicalParent()) { 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (DeclDC == DC) 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid CursorVisitor::visitDeclsFromFileRegion(FileID File, 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned Offset, unsigned Length) { 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ASTUnit *Unit = cxtu::getASTUnit(TU); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceManager &SM = Unit->getSourceManager(); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceRange Range = RegionOfInterest; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SmallVector<Decl *, 16> Decls; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Unit->findFileRegionDecls(File, Offset, Length, Decls); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If we didn't find any file level decls for the file, try looking at the 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // file that it was included from. 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) { 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool Invalid = false; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid); 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Invalid) 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceLocation Outer; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (SLEntry.isFile()) 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Outer = SLEntry.getFile().getIncludeLoc(); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Outer = SLEntry.getExpansion().getExpansionLocStart(); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Outer.isInvalid()) 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer); 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Length = 0; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Unit->findFileRegionDecls(File, Offset, Length, Decls); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(!Decls.empty()); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool VisitedAtLeastOnce = false; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DeclContext *CurDC = 0; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SmallVector<Decl *, 16>::iterator DIt = Decls.begin(); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (SmallVector<Decl *, 16>::iterator DE = Decls.end(); DIt != DE; ++DIt) { 3111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Decl *D = *DIt; 312391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (D->getSourceRange().isInvalid()) 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 314df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 315df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (isInLexicalContext(D, CurDC)) 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt CurDC = dyn_cast<DeclContext>(D); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TagDecl *TD = dyn_cast<TagDecl>(D)) 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!TD->isFreeStanding()) 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CompRes == RangeBefore) 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CompRes == RangeAfter) 32804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 32904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(CompRes == RangeOverlap); 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitedAtLeastOnce = true; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (isa<ObjCContainerDecl>(D)) { 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FileDI_current = &DIt; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FileDE_current = DE; 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FileDI_current = 0; 33804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 33904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 34004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true)) 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitedAtLeastOnce) 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // No Decls overlapped with the range. Move up the lexical context until there 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // is a context that contains the range or we reach the translation unit 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // level. 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext() 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt : (*(DIt-1))->getLexicalDeclContext(); 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3532271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt while (DC && !DC->isTranslationUnit()) { 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Decl *D = cast<Decl>(DC); 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceRange CurDeclRange = D->getSourceRange(); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CurDeclRange.isInvalid()) 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) { 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true); 3611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DC = D->getLexicalDeclContext(); 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::visitPreprocessedEntitiesInRegion() { 369b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if (!AU->getPreprocessor().getPreprocessingRecord()) 370b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return false; 371b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 372b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt PreprocessingRecord &PPRec 373b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt = *AU->getPreprocessor().getPreprocessingRecord(); 374b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt SourceManager &SM = AU->getSourceManager(); 375b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 376b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if (RegionOfInterest.isValid()) { 377b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest); 378b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt SourceLocation B = MappedRange.getBegin(); 379b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt SourceLocation E = MappedRange.getEnd(); 380b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 381b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if (AU->isInPreambleFileID(B)) { 382b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if (SM.isLoadedSourceLocation(E)) 3839bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt return visitPreprocessedEntitiesInRange(SourceRange(B, E), 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PPRec, *this); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 386b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt // Beginning of range lies in the preamble but it also extends beyond 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // it into the main file. Split the range into 2 parts, one covering 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // the preamble and another covering the main file. This allows subsequent 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // calls to visitPreprocessedEntitiesInRange to accept a source range that 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // lies in the same FileID, allowing it to skip preprocessed entities that 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // do not come from the same FileID. 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool breaked = 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt visitPreprocessedEntitiesInRange( 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceRange(B, AU->getEndOfPreambleFileID()), 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PPRec, *this); 396b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if (breaked) return true; 397b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return visitPreprocessedEntitiesInRange( 398b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt SourceRange(AU->getStartOfMainFileID(), E), 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PPRec, *this); 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool OnlyLocalDecls 40675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen = !AU->isMainFileAST() && AU->getOnlyLocalDecls(); 40775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 40875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (OnlyLocalDecls) 409f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(), 410f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt PPRec); 411f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttemplate<typename InputIterator> 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::visitPreprocessedEntities(InputIterator First, 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt InputIterator Last, 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PreprocessingRecord &PPRec, 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FileID FID) { 4209bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt for (; First != Last; ++First) { 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID)) 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PreprocessedEntity *PPE = *First; 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) { 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeMacroExpansionCursor(ME, TU))) 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) { 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeMacroDefinitionCursor(MD, TU))) 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4389bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) { 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeInclusionDirectiveCursor(ID, TU))) 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// \brief Visit the children of the given cursor. 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// \returns true if the visitation should be aborted, false if it 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/// should continue. 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitChildren(CXCursor Cursor) { 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (clang_isReference(Cursor.kind) && 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Cursor.kind != CXCursor_CXXBaseSpecifier) { 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // By definition, references have no children. 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Set the Parent field to Cursor, then back to its old value once we're 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // done. 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SetParentRAII SetParent(Parent, StmtParent, Cursor); 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (clang_isDeclaration(Cursor.kind)) { 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Decl *D = const_cast<Decl *>(getCursorDecl(Cursor)); 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!D) 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VisitAttributes(D) || Visit(D); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (clang_isStatement(Cursor.kind)) { 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const Stmt *S = getCursorStmt(Cursor)) 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(S); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (clang_isExpression(Cursor.kind)) { 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const Expr *E = getCursorExpr(Cursor)) 482d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return Visit(E); 483d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 484d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return false; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (clang_isTranslationUnit(Cursor.kind)) { 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXTranslationUnit TU = getCursorTU(Cursor); 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast }; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (unsigned I = 0; I != 2; ++I) { 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitOrder[I]) { 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() && 4959bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt RegionOfInterest.isInvalid()) { 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(), 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLEnd = CXXUnit->top_level_end(); 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TL != TLEnd; ++TL) { 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true)) 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (VisitDeclContext( 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXXUnit->getASTContext().getTranslationUnitDecl())) 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Walk the preprocessing record. 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CXXUnit->getPreprocessor().getPreprocessingRecord()) 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt visitPreprocessedEntitiesInRegion(); 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Cursor.kind == CXCursor_CXXBaseSpecifier) { 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) { 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) { 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(BaseTSInfo->getTypeLoc()); 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Cursor.kind == CXCursor_IBOutletCollectionAttr) { 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const IBOutletCollectionAttr *A = 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor)); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>()) 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(), 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt A->getInterfaceLoc(), TU)); 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If pointing inside a macro definition, check if the token is an identifier 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // that was ever defined as a macro. In such a case, create a "pseudo" macro 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // expansion cursor for that token. 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceLocation BeginLoc = RegionOfInterest.getBegin(); 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Cursor.kind == CXCursor_MacroDefinition && 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BeginLoc == RegionOfInterest.getEnd()) { 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc); 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const MacroInfo *MI = 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU); 54161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (MacroDefinition *MacroDef = 54261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt checkForMacroInMacroDefinition(MI, Loc, TU)) 54361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU)); 54461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 54561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 54661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt // Nothing to visit at the moment. 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitBlockDecl(BlockDecl *B) { 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten()) 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(TSInfo->getTypeLoc())) 553f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return true; 554f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 555f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (Stmt *Body = B->getBody()) 556f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest)); 557f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 558f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return false; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtllvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) { 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (RegionOfInterest.isValid()) { 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager()); 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Range.isInvalid()) 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return llvm::Optional<bool>(); 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (CompareRegionOfInterest(Range)) { 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RangeBefore: 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // This declaration comes before the region of interest; skip it. 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return llvm::Optional<bool>(); 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RangeAfter: 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // This declaration comes after the region of interest; we're done. 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case RangeOverlap: 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // This declaration overlaps the region of interest; visit it. 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitDeclContext(DeclContext *DC) { 5859ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); 5861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // FIXME: Eventually remove. This part of a hack to support proper 5881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // iteration over all Decls contained lexically within an ObjC container. 5891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I); 5901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E); 5911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for ( ; I != E; ++I) { 5931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Decl *D = *I; 5941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (D->getLexicalDeclContext() != DC) 5951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 5961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest); 5971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // Ignore synthesized ivars here, otherwise if we have something like: 5991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // @synthesize prop = _prop; 6001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // and '_prop' is not declared, we will encounter a '_prop' ivar before 6011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // encountering the 'prop' synthesize declaration and we will think that 6021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // we passed the region-of-interest. 6039ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) { 604c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (ivarD->getSynthesize()) 605c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt continue; 606c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 607c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 608c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol 609c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // declarations is a mismatch with the compiler semantics. 610c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (Cursor.kind == CXCursor_ObjCInterfaceDecl) { 611c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D); 612c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!ID->isThisDeclarationADefinition()) 613c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU); 614c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 615c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) { 616c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D); 617c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!PD->isThisDeclarationADefinition()) 618c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU); 619c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 620c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 6219bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt const llvm::Optional<bool> &V = shouldVisitCursor(Cursor); 6221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!V.hasValue()) 6231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 6241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!V.getValue()) 6251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return false; 6261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (Visit(Cursor, true)) 6271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return true; 6281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return false; 6301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 6311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtbool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) { 6331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt llvm_unreachable("Translation units are visited directly by Visit()"); 6341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 6351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtbool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) { 6371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo()) 6381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return Visit(TSInfo->getTypeLoc()); 6391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return false; 6411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 6421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtbool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) { 6441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo()) 6451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return Visit(TSInfo->getTypeLoc()); 6461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return false; 6481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 6491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtbool CursorVisitor::VisitTagDecl(TagDecl *D) { 6511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return VisitDeclContext(D); 6521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 6531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtbool CursorVisitor::VisitClassTemplateSpecializationDecl( 6551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ClassTemplateSpecializationDecl *D) { 6561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt bool ShouldVisitBody = false; 6571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (D->getSpecializationKind()) { 6581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case TSK_Undeclared: 6599bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt case TSK_ImplicitInstantiation: 6601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // Nothing to visit 6611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return false; 6621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case TSK_ExplicitInstantiationDeclaration: 6641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case TSK_ExplicitInstantiationDefinition: 6651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 6661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case TSK_ExplicitSpecialization: 6681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ShouldVisitBody = true; 6691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 6701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // Visit the template arguments used in the specialization. 6731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) { 6741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TypeLoc TL = SpecType->getTypeLoc(); 6751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (TemplateSpecializationTypeLoc *TSTLoc 6761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) { 6771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I) 6781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I))) 6791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return true; 6801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ShouldVisitBody && VisitCXXRecordDecl(D)) 6841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return true; 6851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 686c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return false; 687c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt} 688c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 689c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtbool CursorVisitor::VisitClassTemplatePartialSpecializationDecl( 690c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ClassTemplatePartialSpecializationDecl *D) { 691c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // FIXME: Visit the "outer" template parameter lists on the TagDecl 692c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // before visiting these template parameters. 693c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (VisitTemplateParameters(D->getTemplateParameters())) 694c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return true; 695c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 696c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // Visit the partial specialization arguments. 697c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten(); 6981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I) 6991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (VisitTemplateArgumentLoc(TemplateArgs[I])) 7001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return true; 7011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return VisitCXXRecordDecl(D); 7031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 7041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtbool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { 7061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // Visit the default argument. 7071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) 7081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo()) 7091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (Visit(DefArg->getTypeLoc())) 7101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return true; 7111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return false; 7131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 7141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtbool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) { 7161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (Expr *Init = D->getInitExpr()) 7171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest)); 7181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return false; 7191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 7201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtbool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { 7221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo()) 7231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (Visit(TSInfo->getTypeLoc())) 724f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return true; 725f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 726f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt // Visit the nested-name-specifier, if present. 727f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc()) 728f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (VisitNestedNameSpecifierLoc(QualifierLoc)) 729f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return true; 730f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 731f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return false; 732f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt} 733f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 734f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt/// \brief Compare two base or member initializers based on their source order. 735f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtstatic int CompareCXXCtorInitializers(const void* Xp, const void *Yp) { 736f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt CXXCtorInitializer const * const *X 737f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt = static_cast<CXXCtorInitializer const * const *>(Xp); 738f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt CXXCtorInitializer const * const *Y 739f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt = static_cast<CXXCtorInitializer const * const *>(Yp); 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7419bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt if ((*X)->getSourceOrder() < (*Y)->getSourceOrder()) 742f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return -1; 743f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder()) 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 7459bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt else 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { 750f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) { 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit the function declaration's syntactic components in the order 7529bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt // written. This requires a bit of work. 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL); 7559bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If we have a function declared directly (without the use of a typedef), 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // visit just the return type. Otherwise, just visit the function's type 758f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt // now. 759f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) || 760f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt (!FTL && Visit(TL))) 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 762f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 7639bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt // Visit the nested-name-specifier, if present. 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc()) 7659657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt if (VisitNestedNameSpecifierLoc(QualifierLoc)) 7669657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt return true; 7679657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 768f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt // Visit the declaration name. 769f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (VisitDeclarationNameInfo(ND->getNameInfo())) 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: Visit explicitly-specified template arguments! 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 77404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt // Visit the function parameters, if we have a function type. 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (FTL && VisitFunctionTypeLoc(*FTL, true)) 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: Attributes? 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) { 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) { 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Find the initializers that were written in the source. 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SmallVector<CXXCtorInitializer *, 4> WrittenInits; 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(), 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEnd = Constructor->init_end(); 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt I != IEnd; ++I) { 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(*I)->isWritten()) 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WrittenInits.push_back(*I); 7929bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt } 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Sort the initializers in source order 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(), 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &CompareCXXCtorInitializers); 797d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 798d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt // Visit the initializers in source order 799d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) { 800d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt CXXCtorInitializer *Init = WrittenInits[I]; 801d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (Init->isAnyMemberInitializer()) { 802d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (Visit(MakeCursorMemberRef(Init->getAnyMember(), 803d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt Init->getMemberLocation(), TU))) 804d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return true; 805d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) { 806d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (Visit(TInfo->getTypeLoc())) 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 809f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit the initializer value. 81161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (Expr *Initializer = Init->getInit()) 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest))) 81304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return true; 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest))) 81861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return true; 81961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 82061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 82161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return false; 82261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 82361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 82461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtbool CursorVisitor::VisitFieldDecl(FieldDecl *D) { 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitDeclaratorDecl(D)) 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Expr *BitWidth = D->getBitWidth()) 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest)); 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitVarDecl(VarDecl *D) { 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitDeclaratorDecl(D)) 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Expr *Init = D->getInit()) 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest)); 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitDeclaratorDecl(D)) 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 8471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) 8491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (Expr *DefArg = D->getDefaultArgument()) 8501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest)); 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8529bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt return false; 8539bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt} 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: Visit the "outer" template parameter lists on the FunctionDecl 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // before visiting these template parameters. 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitTemplateParameters(D->getTemplateParameters())) 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VisitFunctionDecl(D->getTemplatedDecl()); 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) { 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: Visit the "outer" template parameter lists on the TagDecl 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // before visiting these template parameters. 867f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (VisitTemplateParameters(D->getTemplateParameters())) 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VisitCXXRecordDecl(D->getTemplatedDecl()); 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitTemplateParameters(D->getTemplateParameters())) 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 876b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 877b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() && 878b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt VisitTemplateArgumentLoc(D->getDefaultArgument())) 879b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return true; 880b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 881b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt return false; 882f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt} 883f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 884f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtbool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) { 885f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo()) 886f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (Visit(TSInfo->getTypeLoc())) 887f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return true; 88875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ObjCMethodDecl::param_iterator P = ND->param_begin(), 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PEnd = ND->param_end(); 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P != PEnd; ++P) { 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCXCursor(*P, TU, RegionOfInterest))) 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 894f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 895f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ND->isThisDeclarationADefinition() && 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest))) 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttemplate <typename DeclIt> 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current, 9051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt SourceManager &SM, SourceLocation EndLoc, 9061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt SmallVectorImpl<Decl *> &Decls) { 9071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt DeclIt next = *DI_current; 9081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt while (++next != DE_current) { 9091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Decl *D_next = *next; 9101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!D_next) 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9129657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt SourceLocation L = D_next->getLocStart(); 9139657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt if (!L.isValid()) 9149657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt break; 9159657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt if (SM.isBeforeInTranslationUnit(L, EndLoc)) { 9169657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt *DI_current = next; 9179657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt Decls.push_back(D_next); 9189657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt continue; 9195460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 9205460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt break; 9215460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 9225460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt} 9235460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 9245460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidtnamespace { 9255460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt struct ContainerDeclsSort { 9265460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt SourceManager &SM; 9275460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt ContainerDeclsSort(SourceManager &sm) : SM(sm) {} 9285460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt bool operator()(Decl *A, Decl *B) { 9295460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt SourceLocation L_A = A->getLocStart(); 9305460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt SourceLocation L_B = B->getLocStart(); 9315460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt assert(L_A.isValid() && L_B.isValid()); 9325460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt return SM.isBeforeInTranslationUnit(L_A, L_B); 9335460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 9345460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt }; 9355460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt} 9365460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 9375460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidtbool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) { 9385460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially 9395460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt // an @implementation can lexically contain Decls that are not properly 9405460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt // nested in the AST. When we identify such cases, we need to retrofit 9415460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt // this nesting here. 9425460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (!DI_current && !FileDI_current) 9435460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt return VisitDeclContext(D); 9445460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Scan the Decls that immediately come after the container 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // in the current DeclContext. If any fall within the 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // container's lexical region, stash them into a vector 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // for later processing. 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SmallVector<Decl *, 24> DeclsInContainer; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceLocation EndLoc = D->getSourceRange().getEnd(); 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceManager &SM = AU->getSourceManager(); 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (EndLoc.isValid()) { 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (DI_current) { 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc, 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DeclsInContainer); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc, 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DeclsInContainer); 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // The common case. 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (DeclsInContainer.empty()) 964f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return VisitDeclContext(D); 965f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Get all the Decls in the DeclContext, and sort them with the 9679bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt // additional ones we've collected. Then visit them. 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end(); 969f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt I!=E; ++I) { 970f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt Decl *subDecl = *I; 971f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (!subDecl || subDecl->getLexicalDeclContext() != D || 972f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt subDecl->getLocStart().isInvalid()) 973f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 974f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt DeclsInContainer.push_back(subDecl); 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9769bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt 9779bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt // Now sort the Decls so that they appear in lexical order. 978f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt std::sort(DeclsInContainer.begin(), DeclsInContainer.end(), 979f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ContainerDeclsSort(SM)); 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Now visit the decls. 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(), 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt E = DeclsInContainer.end(); I != E; ++I) { 9849bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest); 9859bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt const llvm::Optional<bool> &V = shouldVisitCursor(Cursor); 9869bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt if (!V.hasValue()) 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!V.getValue()) 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(Cursor, true)) 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 993444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return false; 994444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt} 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(), 9984582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt TU))) 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 10009bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt 10019bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin(); 10029bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(), 10039bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt E = ND->protocol_end(); I != E; ++I, ++PL) 10044582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 10054582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt return true; 1006f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 10074582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt return VisitObjCContainerDecl(ND); 10084582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt} 10094582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt 10104582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidtbool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { 10114582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt if (!PID->isThisDeclarationADefinition()) 10124582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU)); 10134582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt 10144582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin(); 1015f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), 10164582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt E = PID->protocol_end(); I != E; ++I, ++PL) 10174582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 10184582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt return true; 10194582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt 1020f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return VisitObjCContainerDecl(PID); 10214582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt} 1022f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 1023f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidtbool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) { 1024f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc())) 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 10269bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt 1027f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt // FIXME: This implements a workaround with @property declarations also being 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // installed in the DeclContext for the @interface. Eventually this code 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // should be removed. 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext()); 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CDecl || !CDecl->IsClassExtension()) 10321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return false; 10331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ObjCInterfaceDecl *ID = CDecl->getClassInterface(); 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ID) 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IdentifierInfo *PropertyId = PD->getIdentifier(); 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ObjCPropertyDecl *prevDecl = 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId); 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!prevDecl) 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit synthesized methods since they will be skipped when visiting 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // the @interface. 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl()) 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl) 104904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (Visit(MakeCXCursor(MD, TU, RegionOfInterest))) 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl()) 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl) 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCXCursor(MD, TU, RegionOfInterest))) 1055aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt return true; 1056aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1060d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtbool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { 1061d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!D->isThisDeclarationADefinition()) { 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Forward declaration is treated like a reference. 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU)); 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 106644da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt // Issue callbacks for super class. 10671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (D->getSuperClass() && 10681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt D->getSuperClassLoc(), 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TU))) 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); 1074df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), 1075df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt E = D->protocol_end(); I != E; ++I, ++PL) 1076df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) 1077df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return true; 107844da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt 1079df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return VisitObjCContainerDecl(D); 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) { 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VisitObjCContainerDecl(D); 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 108544da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // 'ID' could be null when dealing with invalid code. 1088f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt if (ObjCInterfaceDecl *ID = D->getClassInterface()) 1089f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU))) 1090f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt return true; 1091f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 1092f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt return VisitObjCImplDecl(D); 1093f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt} 1094f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 1095f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidtbool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { 1096f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt#if 0 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Issue callbacks for super class. 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: No source location information! 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (D->getSuperClass() && 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt D->getSuperClassLoc(), 11021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TU))) 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1106f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt return VisitObjCImplDecl(D); 1107f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt} 1108f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 1109f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidtbool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) { 1110f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl()) 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (PD->isIvarNameSpecified()) 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU)); 111344da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 1115f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt} 1116f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) { 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VisitDeclContext(D); 1119f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt} 1120f7e0a9905988e62e4f70fed8b795722abeab719bDmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { 11221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // Visit nested-name-specifier. 112344da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitNestedNameSpecifierLoc(QualifierLoc)) 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(), 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt D->getTargetNameLoc(), TU)); 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitUsingDecl(UsingDecl *D) { 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit nested-name-specifier. 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) { 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitNestedNameSpecifierLoc(QualifierLoc)) 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 113604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU))) 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VisitDeclarationNameInfo(D->getNameInfo()); 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit nested-name-specifier. 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitNestedNameSpecifierLoc(QualifierLoc)) 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 115087fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(), 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt D->getIdentLocation(), TU)); 115287fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen} 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit nested-name-specifier. 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) { 115787fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen if (VisitNestedNameSpecifierLoc(QualifierLoc)) 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 116087fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VisitDeclarationNameInfo(D->getNameInfo()); 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 116487fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinenbool CursorVisitor::VisitUnresolvedUsingTypenameDecl( 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt UnresolvedUsingTypenameDecl *D) { 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit nested-name-specifier. 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) 116887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen if (VisitNestedNameSpecifierLoc(QualifierLoc)) 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) { 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (Name.getName().getNameKind()) { 11769bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt case clang::DeclarationName::Identifier: 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case clang::DeclarationName::CXXLiteralOperatorName: 11789bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt case clang::DeclarationName::CXXOperatorName: 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case clang::DeclarationName::CXXUsingDirective: 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case clang::DeclarationName::CXXConstructorName: 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case clang::DeclarationName::CXXDestructorName: 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case clang::DeclarationName::CXXConversionFunctionName: 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo()) 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(TSInfo->getTypeLoc()); 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case clang::DeclarationName::ObjCZeroArgSelector: 11901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case clang::DeclarationName::ObjCOneArgSelector: 11911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case clang::DeclarationName::ObjCMultiArgSelector: 11921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // FIXME: Per-identifier location info? 11939bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt return false; 11949bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt } 11959bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt 11969bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt llvm_unreachable("Invalid DeclarationName::Kind!"); 11979bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt} 11989bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS, 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceRange Range) { 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: This whole routine is a hack to work around the lack of proper 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // source information in nested-name-specifiers (PR5791). Since we do have 12039bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt // a beginning source location, we can visit the first component of the 12049bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt // nested-name-specifier, if it's a single-token component. 12059bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt if (!NNS) 12069bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt return false; 12079bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt 12089bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt // Get the first component in the nested-name-specifier. 12099e07767d5d76159ef38a241da00eb0d9f3bc6420Dmitry Shmidt while (NestedNameSpecifier *Prefix = NNS->getPrefix()) 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NNS = Prefix; 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (NNS->getKind()) { 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NestedNameSpecifier::Namespace: 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TU)); 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NestedNameSpecifier::NamespaceAlias: 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(), 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Range.getBegin(), TU)); 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NestedNameSpecifier::TypeSpec: { 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If the type has a form where we know that the beginning of the source 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // range matches up with a reference cursor. Visit the appropriate reference 1224d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt // cursor. 1225d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const Type *T = NNS->getAsType(); 1226d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (const TypedefType *Typedef = dyn_cast<TypedefType>(T)) 1227d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU)); 1228d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (const TagType *Tag = dyn_cast<TagType>(T)) 1229d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU)); 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const TemplateSpecializationType *TST 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt = dyn_cast<TemplateSpecializationType>(T)) 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VisitTemplateName(TST->getTemplateName(), Range.getBegin()); 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NestedNameSpecifier::TypeSpecWithTemplate: 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NestedNameSpecifier::Global: 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NestedNameSpecifier::Identifier: 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtCursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) { 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SmallVector<NestedNameSpecifierLoc, 4> Qualifiers; 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (; Qualifier; Qualifier = Qualifier.getPrefix()) 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Qualifiers.push_back(Qualifier); 125004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1251efdec2efdda2f534d84b32f2737ca3d8a00fdf02Dmitry Shmidt while (!Qualifiers.empty()) { 125204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt NestedNameSpecifierLoc Q = Qualifiers.pop_back_val(); 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NestedNameSpecifier *NNS = Q.getNestedNameSpecifier(); 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (NNS->getKind()) { 1255c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt case NestedNameSpecifier::Namespace: 125689ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), 125704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Q.getLocalBeginLoc(), 1258f6c92c4dd33d21c040e51bcb30beac24173a62b9Dmitry Shmidt TU))) 125937d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt return true; 126037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1262fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1263fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case NestedNameSpecifier::NamespaceAlias: 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(), 12654530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt Q.getLocalBeginLoc(), 12664530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt TU))) 12674530cfd4d14a77c58e35393b91e40f8dd9d62697Dmitry Shmidt return true; 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NestedNameSpecifier::TypeSpec: 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NestedNameSpecifier::TypeSpecWithTemplate: 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(Q.getTypeLoc())) 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NestedNameSpecifier::Global: 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NestedNameSpecifier::Identifier: 12804b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt break; 12814b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt } 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 128337d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 128437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt return false; 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitTemplateParameters( 1288fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const TemplateParameterList *Params) { 1289fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (!Params) 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (TemplateParameterList::const_iterator P = Params->begin(), 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PEnd = Params->end(); 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P != PEnd; ++P) { 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCXCursor(*P, TU, RegionOfInterest))) 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) { 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (Name.getKind()) { 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TemplateName::Template: 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU)); 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TemplateName::OverloadedTemplate: 1308fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt // Visit the overloaded template set. 1309fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU))) 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TemplateName::DependentTemplate: 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: Visit nested-name-specifier. 1316fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return false; 1317fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TemplateName::QualifiedTemplate: 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: Visit nested-name-specifier. 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCursorTemplateRef( 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Name.getAsQualifiedTemplateName()->getDecl(), 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Loc, TU)); 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TemplateName::SubstTemplateTemplateParm: 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCursorTemplateRef( 1326fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt Name.getAsSubstTemplateTemplateParm()->getParameter(), 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Loc, TU)); 132837d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 1329fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case TemplateName::SubstTemplateTemplateParmPack: 1330fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return Visit(MakeCursorTemplateRef( 1331fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), 1332fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt Loc, TU)); 1333fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1334fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1335fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt llvm_unreachable("Invalid TemplateName::Kind!"); 1336fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 1337fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1338fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtbool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) { 133904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt switch (TAL.getArgument().getKind()) { 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TemplateArgument::Null: 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TemplateArgument::Integral: 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TemplateArgument::Pack: 1343fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return false; 1344fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 134504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case TemplateArgument::Type: 134604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo()) 134704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return Visit(TSInfo->getTypeLoc()); 134804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return false; 1349fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1350fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case TemplateArgument::Declaration: 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Expr *E = TAL.getSourceDeclExpression()) 1352fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest)); 1353fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return false; 1354fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1355fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case TemplateArgument::NullPtr: 1356fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (Expr *E = TAL.getSourceNullPtrExpression()) 135704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest)); 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1360fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case TemplateArgument::Expression: 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Expr *E = TAL.getSourceExpression()) 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest)); 13631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return false; 1364fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1365fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case TemplateArgument::Template: 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TemplateArgument::TemplateExpansion: 136761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc())) 136861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return true; 13699bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt 13709bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(), 1371fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt TAL.getTemplateNameLoc()); 1372fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1373fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1374fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt llvm_unreachable("Invalid TemplateArgument::Kind!"); 1375fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 1376fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1377e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtbool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) { 1378fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return VisitDeclContext(D); 1379fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 1380fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1381fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtbool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { 1382fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return Visit(TL.getUnqualifiedLoc()); 1383fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 1384fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1385fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtbool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { 1386fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ASTContext &Context = AU->getASTContext(); 13879bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt 13889bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt // Some builtin types (such as Objective-C's "id", "sel", and 13899bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt // "Class") have associated declarations. Create cursors for those. 13908da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt QualType VisitType; 1391e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt switch (TL.getTypePtr()->getKind()) { 13929bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt 13939bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt case BuiltinType::Void: 13949bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt case BuiltinType::NullPtr: 13959bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt case BuiltinType::Dependent: 13969bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt case BuiltinType::OCLImage1d: 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case BuiltinType::OCLImage1dArray: 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case BuiltinType::OCLImage1dBuffer: 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case BuiltinType::OCLImage2d: 14009bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt case BuiltinType::OCLImage2dArray: 14011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case BuiltinType::OCLImage3d: 14028da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt case BuiltinType::OCLEvent: 14038da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt#define BUILTIN_TYPE(Id, SingletonId) 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id: 14051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id: 14061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id: 140744da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id: 14081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "clang/AST/BuiltinTypes.def" 140944da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt break; 141044da0253a740e0329b18f60c196e1f2dcacfcceaDmitry Shmidt 14118da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt case BuiltinType::ObjCId: 14128da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt VisitType = Context.getObjCIdType(); 141389ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen break; 141489ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen 141589ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen case BuiltinType::ObjCClass: 141689ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen VisitType = Context.getObjCClassType(); 141789ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen break; 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case BuiltinType::ObjCSel: 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitType = Context.getObjCSelType(); 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14248da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (!VisitType.isNull()) { 14258da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (const TypedefType *Typedef = VisitType->getAs<TypedefType>()) 1426e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), 1427e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt TU)); 1428e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 1429e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 1430e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return false; 1431e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) { 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU)); 143504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 143604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 143704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { 1438fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 143915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt} 144015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) { 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TL.isDefinition()) 1443fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest)); 1444fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtbool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { 14491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 14501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { 145361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU))) 145461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return true; 145561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 145661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return false; 145761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 145861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 145961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtbool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { 146061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc())) 146161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return true; 146261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 146389ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { 146461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I), 146561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt TU))) 1466fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return true; 1467fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1468fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1469fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return false; 1470fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 1471fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1472fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtbool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { 1473fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return Visit(TL.getPointeeLoc()); 1474fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 1475fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 14761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtbool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) { 14771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return Visit(TL.getInnerLoc()); 14781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) { 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(TL.getPointeeLoc()); 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(TL.getPointeeLoc()); 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { 148937d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt return Visit(TL.getPointeeLoc()); 149037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt} 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(TL.getPointeeLoc()); 149489ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen} 149589ca702e8ed3247d7007dbdebe531036671c34afJouni Malinen 149689ca702e8ed3247d7007dbdebe531036671c34afJouni Malinenbool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(TL.getPointeeLoc()); 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) { 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(TL.getModifiedLoc()); 150201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt} 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL, 150501904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt bool SkipResultType) { 150601904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt if (!SkipResultType && Visit(TL.getResultLoc())) 150701904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt return true; 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 151037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt if (Decl *D = TL.getArg(I)) 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCXCursor(D, TU, RegionOfInterest))) 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) { 15184b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt if (Visit(TL.getElementLoc())) 15194b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt return true; 15204b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt 15214b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt if (Expr *Size = TL.getSizeExpr()) 15224b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest)); 1523fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 15244b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt return false; 15254b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt} 15264b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt 15274b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidtbool CursorVisitor::VisitTemplateSpecializationTypeLoc( 1528fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt TemplateSpecializationTypeLoc TL) { 1529fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt // Visit the template name. 15304b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt if (VisitTemplateName(TL.getTypePtr()->getTemplateName(), 15314b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt TL.getTemplateNameLoc())) 15324b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt return true; 15334b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt 1534e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt // Visit the template arguments. 15354b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 15364b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt if (VisitTemplateArgumentLoc(TL.getArgLoc(I))) 15374b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt return true; 153804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 153904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return false; 154004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 154104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 154204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { 154304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU)); 154404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 154504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 154604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { 1547a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo()) 1548a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return Visit(TSInfo->getTypeLoc()); 1549a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1550a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return false; 1551a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 1552a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 1553a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtbool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { 1554a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo()) 1555a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return Visit(TSInfo->getTypeLoc()); 1556a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 155704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return false; 155804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 155904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 156004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { 156104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc())) 156204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return true; 156304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 156404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return false; 156504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 156604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 156704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc( 156804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DependentTemplateSpecializationTypeLoc TL) { 156904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt // Visit the nested-name-specifier, if there is one. 157004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (TL.getQualifierLoc() && 157104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt VisitNestedNameSpecifierLoc(TL.getQualifierLoc())) 157204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return true; 157304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 157404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt // Visit the template arguments. 157504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) 157604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (VisitTemplateArgumentLoc(TL.getArgLoc(I))) 157704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return true; 157804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 157904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return false; 158004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 158104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 158204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { 158304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc())) 158404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return true; 158504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 158604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return Visit(TL.getNamedTypeLoc()); 158704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 158804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 158904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) { 159004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return Visit(TL.getPatternLoc()); 159104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 159204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 159304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { 159404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (Expr *E = TL.getUnderlyingExpr()) 159504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return Visit(MakeCXCursor(E, StmtParent, TU)); 159604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 159704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return false; 159804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 159904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 160004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { 160104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); 160204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 160304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 160404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) { 160504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return Visit(TL.getValueLoc()); 160604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 160704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 160804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \ 160904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtbool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \ 161004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return Visit##PARENT##Loc(TL); \ 161104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 161204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 161304949598a23f501be6eec21697465fd46a28840aDmitry ShmidtDEFAULT_TYPELOC_IMPL(Complex, Type) 161404949598a23f501be6eec21697465fd46a28840aDmitry ShmidtDEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType) 161504949598a23f501be6eec21697465fd46a28840aDmitry ShmidtDEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType) 161604949598a23f501be6eec21697465fd46a28840aDmitry ShmidtDEFAULT_TYPELOC_IMPL(VariableArray, ArrayType) 161704949598a23f501be6eec21697465fd46a28840aDmitry ShmidtDEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType) 1618051af73b8f8014eff33330aead0f36944b3403e6Dmitry ShmidtDEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type) 1619051af73b8f8014eff33330aead0f36944b3403e6Dmitry ShmidtDEFAULT_TYPELOC_IMPL(Vector, Type) 1620051af73b8f8014eff33330aead0f36944b3403e6Dmitry ShmidtDEFAULT_TYPELOC_IMPL(ExtVector, VectorType) 1621051af73b8f8014eff33330aead0f36944b3403e6Dmitry ShmidtDEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType) 1622051af73b8f8014eff33330aead0f36944b3403e6Dmitry ShmidtDEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType) 1623051af73b8f8014eff33330aead0f36944b3403e6Dmitry ShmidtDEFAULT_TYPELOC_IMPL(Record, TagType) 1624051af73b8f8014eff33330aead0f36944b3403e6Dmitry ShmidtDEFAULT_TYPELOC_IMPL(Enum, TagType) 1625051af73b8f8014eff33330aead0f36944b3403e6Dmitry ShmidtDEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type) 1626051af73b8f8014eff33330aead0f36944b3403e6Dmitry ShmidtDEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type) 1627051af73b8f8014eff33330aead0f36944b3403e6Dmitry ShmidtDEFAULT_TYPELOC_IMPL(Auto, Type) 1628051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1629051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtbool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) { 1630051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt // Visit the nested-name-specifier, if present. 1631051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) 1632051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (VisitNestedNameSpecifierLoc(QualifierLoc)) 1633051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return true; 1634051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1635051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (D->isCompleteDefinition()) { 1636051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), 1637051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt E = D->bases_end(); I != E; ++I) { 1638051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU))) 1639051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return true; 1640051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1641051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 1642051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1643051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return VisitTagDecl(D); 1644051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 1645051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1646051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtbool CursorVisitor::VisitAttributes(Decl *D) { 1647051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end(); 1648051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt i != e; ++i) 1649051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (Visit(MakeCXCursor(*i, D, TU))) 1650051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return true; 1651051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1652051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return false; 1653051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 1654051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===// 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// Data-recursive visitor methods. 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===// 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnamespace { 1660700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#define DEF_JOB(NAME, DATA, KIND)\ 1661700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtclass NAME : public VisitorJob {\ 1662700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtpublic:\ 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NAME(const DATA *d, CXCursor parent) : \ 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitorJob(parent, VisitorJob::KIND, d) {} \ 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\ 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const DATA *get() const { return static_cast<const DATA*>(data[0]); }\ 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDEF_JOB(StmtVisit, Stmt, StmtVisitKind) 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind) 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind) 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind) 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtDEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo, 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ExplicitTemplateArgsVisitKind) 167504949598a23f501be6eec21697465fd46a28840aDmitry ShmidtDEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind) 167604949598a23f501be6eec21697465fd46a28840aDmitry ShmidtDEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind) 167704949598a23f501be6eec21697465fd46a28840aDmitry ShmidtDEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind) 167804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#undef DEF_JOB 1679051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1680051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtclass DeclVisit : public VisitorJob { 1681051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtpublic: 1682051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt DeclVisit(const Decl *D, CXCursor parent, bool isFirst) : 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitorJob(parent, VisitorJob::DeclVisitKind, 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const_cast<Decl *>(D), isFirst ? (void*) 1 : (void*) 0) {} 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static bool classof(const VisitorJob *VJ) { 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VJ->getKind() == DeclVisitKind; 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const Decl *get() const { return static_cast<const Decl *>(data[0]); } 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool isFirst() const { return data[1] ? true : false; } 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass TypeLocVisit : public VisitorJob { 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic: 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TypeLocVisit(TypeLoc tl, CXCursor parent) : 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitorJob(parent, VisitorJob::TypeLocVisitKind, 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {} 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static bool classof(const VisitorJob *VJ) { 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VJ->getKind() == TypeLocVisitKind; 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TypeLoc get() const { 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt QualType T = QualType::getFromOpaquePtr(data[0]); 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TypeLoc(T, const_cast<void *>(data[1])); 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass LabelRefVisit : public VisitorJob { 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic: 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent) 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD, 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt labelLoc.getPtrEncoding()) {} 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static bool classof(const VisitorJob *VJ) { 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VJ->getKind() == VisitorJob::LabelRefVisitKind; 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const LabelDecl *get() const { 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return static_cast<const LabelDecl *>(data[0]); 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceLocation getLoc() const { 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return SourceLocation::getFromPtrEncoding(data[1]); } 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass NestedNameSpecifierLocVisit : public VisitorJob { 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic: 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent) 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind, 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Qualifier.getNestedNameSpecifier(), 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Qualifier.getOpaqueData()) { } 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static bool classof(const VisitorJob *VJ) { 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind; 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NestedNameSpecifierLoc get() const { 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NestedNameSpecifierLoc( 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const_cast<NestedNameSpecifier *>( 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static_cast<const NestedNameSpecifier *>(data[0])), 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const_cast<void *>(data[1])); 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass DeclarationNameInfoVisit : public VisitorJob { 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic: 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DeclarationNameInfoVisit(const Stmt *S, CXCursor parent) 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const_cast<Stmt *>(S)) {} 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static bool classof(const VisitorJob *VJ) { 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind; 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DeclarationNameInfo get() const { 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const Stmt *S = static_cast<const Stmt *>(data[0]); 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (S->getStmtClass()) { 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm_unreachable("Unhandled Stmt"); 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case clang::Stmt::MSDependentExistsStmtClass: 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return cast<MSDependentExistsStmt>(S)->getNameInfo(); 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Stmt::CXXDependentScopeMemberExprClass: 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo(); 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Stmt::DependentScopeDeclRefExprClass: 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return cast<DependentScopeDeclRefExpr>(S)->getNameInfo(); 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclass MemberRefVisit : public VisitorJob { 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtpublic: 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent) 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D, 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt L.getPtrEncoding()) {} 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static bool classof(const VisitorJob *VJ) { 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return VJ->getKind() == VisitorJob::MemberRefVisitKind; 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const FieldDecl *get() const { 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return static_cast<const FieldDecl *>(data[0]); 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceLocation getLoc() const { 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]); 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1778700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt}; 1779700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtclass EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> { 1780700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt VisitorWorkList &WL; 1781700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt CXCursor Parent; 1782700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidtpublic: 1783700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt EnqueueVisitor(VisitorWorkList &wl, CXCursor parent) 1784700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt : WL(wl), Parent(parent) {} 1785700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt 1786700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt void VisitAddrLabelExpr(const AddrLabelExpr *E); 1787700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt void VisitBlockExpr(const BlockExpr *B); 1788700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); 1789700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt void VisitCompoundStmt(const CompoundStmt *S); 1790700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ } 1791700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S); 1792700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E); 1793700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt void VisitCXXNewExpr(const CXXNewExpr *E); 1794700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E); 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E); 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E); 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E); 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitCXXTypeidExpr(const CXXTypeidExpr *E); 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E); 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitCXXUuidofExpr(const CXXUuidofExpr *E); 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitCXXCatchStmt(const CXXCatchStmt *S); 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitDeclRefExpr(const DeclRefExpr *D); 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitDeclStmt(const DeclStmt *S); 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E); 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitDesignatedInitExpr(const DesignatedInitExpr *E); 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitExplicitCastExpr(const ExplicitCastExpr *E); 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitForStmt(const ForStmt *FS); 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitGotoStmt(const GotoStmt *GS); 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitIfStmt(const IfStmt *If); 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitInitListExpr(const InitListExpr *IE); 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitMemberExpr(const MemberExpr *M); 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitOffsetOfExpr(const OffsetOfExpr *E); 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitObjCEncodeExpr(const ObjCEncodeExpr *E); 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitObjCMessageExpr(const ObjCMessageExpr *M); 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitOverloadExpr(const OverloadExpr *E); 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E); 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitStmt(const Stmt *S); 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitSwitchStmt(const SwitchStmt *S); 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitWhileStmt(const WhileStmt *W); 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E); 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E); 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitTypeTraitExpr(const TypeTraitExpr *E); 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E); 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitExpressionTraitExpr(const ExpressionTraitExpr *E); 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U); 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitVAArgExpr(const VAArgExpr *E); 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitSizeOfPackExpr(const SizeOfPackExpr *E); 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitPseudoObjectExpr(const PseudoObjectExpr *E); 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitOpaqueValueExpr(const OpaqueValueExpr *E); 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void VisitLambdaExpr(const LambdaExpr *E); 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtprivate: 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void AddDeclarationNameInfo(const Stmt *S); 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier); 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A); 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void AddMemberRef(const FieldDecl *D, SourceLocation L); 183787fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen void AddStmt(const Stmt *S); 183887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen void AddDecl(const Decl *D, bool isFirst = true); 183987fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen void AddTypeLoc(TypeSourceInfo *TI); 184087fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen void EnqueueChildren(const Stmt *S); 184187fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen}; 184287fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen} // end anonyous namespace 184387fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen 184487fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinenvoid EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) { 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // 'S' should always be non-null, since it comes from the 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // statement we are visiting. 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WL.push_back(DeclarationNameInfoVisit(S, Parent)); 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid 1851c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry ShmidtEnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) { 1852c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (Qualifier) 1853c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent)); 1854c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 1855c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 1856c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid EnqueueVisitor::AddStmt(const Stmt *S) { 1857c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (S) 1858c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt WL.push_back(StmtVisit(S, Parent)); 1859c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 1860c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) { 1861c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (D) 1862c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt WL.push_back(DeclVisit(D, Parent, isFirst)); 1863c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 1864c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid EnqueueVisitor:: 1865c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) { 1866c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (A) 1867c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt WL.push_back(ExplicitTemplateArgsVisit(A, Parent)); 1868c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 1869c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) { 1870c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (D) 1871c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt WL.push_back(MemberRefVisit(D, L, Parent)); 1872c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 1873c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) { 1874c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (TI) 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent)); 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::EnqueueChildren(const Stmt *S) { 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned size = WL.size(); 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (Stmt::const_child_range Child = S->children(); Child; ++Child) { 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(*Child); 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (size == WL.size()) 188309f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt return; 188409f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt // Now reverse the entries we just added. This will match the DFS 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // ordering performed by the worklist. 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitorWorkList::iterator I = WL.begin() + size, E = WL.end(); 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt std::reverse(I, E); 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) { 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent)); 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) { 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddDecl(B->getBlockDecl()); 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnqueueChildren(E); 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddTypeLoc(E->getTypeSourceInfo()); 189861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 189961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) { 1900d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(), 190161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt E = S->body_rend(); I != E; ++I) { 190261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt AddStmt(*I); 190361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 190461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor:: 190661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry ShmidtVisitMSDependentExistsStmt(const MSDependentExistsStmt *S) { 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(S->getSubStmt()); 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddDeclarationNameInfo(S); 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc()) 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddNestedNameSpecifierLoc(QualifierLoc); 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 191261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor:: 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtVisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) { 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs()); 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddDeclarationNameInfo(E); 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc()) 1918d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt AddNestedNameSpecifierLoc(QualifierLoc); 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!E->isImplicitAccess()) 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(E->getBase()); 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1922c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) { 19231e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt // Enqueue the initializer , if any. 19241e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt AddStmt(E->getInitializer()); 19251e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt // Enqueue the array size, if any. 1926c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt AddStmt(E->getArraySize()); 1927c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt // Enqueue the allocated type. 19281e1c48d2b342d4945d600ddb650bd2925822d1bbDmitry Shmidt AddTypeLoc(E->getAllocatedTypeSourceInfo()); 1929c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt // Enqueue the placement arguments. 1930c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt for (unsigned I = E->getNumPlacementArgs(); I > 0; --I) 1931c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt AddStmt(E->getPlacementArg(I-1)); 1932c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt} 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) { 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I) 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(CE->getArg(I-1)); 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(CE->getCallee()); 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(CE->getArg(0)); 19380c08fdcf5231617f2340cb18e45769a8ed3a1dc4Dmitry Shmidt} 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitCXXPseudoDestructorExpr( 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CXXPseudoDestructorExpr *E) { 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit the name of the type being destroyed. 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddTypeLoc(E->getDestroyedTypeInfo()); 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit the scope type that looks disturbingly like the nested-name-specifier 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // but isn't. 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddTypeLoc(E->getScopeTypeInfo()); 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit the nested-name-specifier. 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc()) 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddNestedNameSpecifierLoc(QualifierLoc); 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit base expression. 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(E->getBase()); 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitCXXScalarValueInitExpr( 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CXXScalarValueInitExpr *E) { 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddTypeLoc(E->getTypeSourceInfo()); 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitCXXTemporaryObjectExpr( 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CXXTemporaryObjectExpr *E) { 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnqueueChildren(E); 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddTypeLoc(E->getTypeSourceInfo()); 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) { 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnqueueChildren(E); 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (E->isTypeOperand()) 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddTypeLoc(E->getTypeOperandSourceInfo()); 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitCXXUnresolvedConstructExpr( 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CXXUnresolvedConstructExpr *E) { 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnqueueChildren(E); 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddTypeLoc(E->getTypeSourceInfo()); 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnqueueChildren(E); 197409f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt if (E->isTypeOperand()) 197509f57babfc1e4473db20ced4f58a4c9f082c8ed8Dmitry Shmidt AddTypeLoc(E->getTypeOperandSourceInfo()); 197651b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt} 197751b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt 197851b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidtvoid EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) { 197951b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt EnqueueChildren(S); 198051b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt AddDecl(S->getExceptionDecl()); 198151b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt} 198251b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt 198351b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidtvoid EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) { 198451b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (DR->hasExplicitTemplateArgs()) { 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs()); 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WL.push_back(DeclRefExprParts(DR, Parent)); 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitDependentScopeDeclRefExpr( 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const DependentScopeDeclRefExpr *E) { 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs()); 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddDeclarationNameInfo(E); 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddNestedNameSpecifierLoc(E->getQualifierLoc()); 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) { 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned size = WL.size(); 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool isFirst = true; 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt D != DEnd; ++D) { 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddDecl(*D, isFirst); 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt isFirst = false; 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (size == WL.size()) 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Now reverse the entries we just added. This will match the DFS 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // ordering performed by the worklist. 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt VisitorWorkList::iterator I = WL.begin() + size, E = WL.end(); 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt std::reverse(I, E); 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) { 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(E->getInit()); 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt typedef DesignatedInitExpr::Designator Designator; 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (DesignatedInitExpr::const_reverse_designators_iterator 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt D = E->designators_rbegin(), DEnd = E->designators_rend(); 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt D != DEnd; ++D) { 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (D->isFieldDesignator()) { 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (FieldDecl *Field = D->getField()) 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddMemberRef(Field, D->getFieldLoc()); 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (D->isArrayDesignator()) { 2022a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen AddStmt(E->getArrayIndex(*D)); 2023a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen continue; 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2025fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt assert(D->isArrayRangeDesignator() && "Unknown designator kind"); 2026fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt AddStmt(E->getArrayRangeEnd(*D)); 2027fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt AddStmt(E->getArrayRangeStart(*D)); 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) { 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnqueueChildren(E); 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddTypeLoc(E->getTypeInfoAsWritten()); 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitForStmt(const ForStmt *FS) { 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(FS->getBody()); 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(FS->getInc()); 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(FS->getCond()); 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddDecl(FS->getConditionVariable()); 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(FS->getInit()); 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) { 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent)); 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitIfStmt(const IfStmt *If) { 204551b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt AddStmt(If->getElse()); 204651b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt AddStmt(If->getThen()); 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(If->getCond()); 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddDecl(If->getConditionVariable()); 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) { 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // We care about the syntactic form of the initializer list, only. 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (InitListExpr *Syntactic = IE->getSyntacticForm()) 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IE = Syntactic; 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnqueueChildren(IE); 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) { 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WL.push_back(MemberExprParts(M, Parent)); 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If the base of the member access expression is an implicit 'this', don't 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // visit it. 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: If we ever want to show these implicit accesses, this will be 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // unfortunate. However, clang_getCursor() relies on this behavior. 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!M->isImplicitAccess()) 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(M->getBase()); 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddTypeLoc(E->getEncodedTypeSourceInfo()); 206861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 206961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) { 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnqueueChildren(M); 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddTypeLoc(M->getClassReceiverTypeInfo()); 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) { 20741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // Visit the components of the offsetof expression. 20751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) { 20761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt typedef OffsetOfExpr::OffsetOfNode OffsetOfNode; 20771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const OffsetOfNode &Node = E->getComponent(I-1); 20781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (Node.getKind()) { 20791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case OffsetOfNode::Array: 20801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt AddStmt(E->getIndexExpr(Node.getArrayExprIndex())); 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2082c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt case OffsetOfNode::Field: 2083c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt AddMemberRef(Node.getField(), Node.getSourceRange().getEnd()); 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case OffsetOfNode::Identifier: 20862b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen case OffsetOfNode::Base: 20872b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen continue; 20882b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen } 20892b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen } 20902b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen // Visit the type into which we're computing the offset. 20912b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen AddTypeLoc(E->getTypeSourceInfo()); 20922b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen} 20932b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenvoid EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) { 20942b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs()); 20952b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen WL.push_back(OverloadExprParts(E, Parent)); 20962b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen} 20972b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenvoid EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr( 20982b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen const UnaryExprOrTypeTraitExpr *E) { 20992b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen EnqueueChildren(E); 21002b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen if (E->isArgumentType()) 21012b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen AddTypeLoc(E->getArgumentTypeInfo()); 21022b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen} 21032b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenvoid EnqueueVisitor::VisitStmt(const Stmt *S) { 21042b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen EnqueueChildren(S); 21052b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen} 21062b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenvoid EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) { 21072b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen AddStmt(S->getBody()); 21082b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen AddStmt(S->getCond()); 21092b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen AddDecl(S->getConditionVariable()); 2110d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 2111d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2112d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) { 2113d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt AddStmt(W->getBody()); 2114d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt AddStmt(W->getCond()); 2115d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt AddDecl(W->getConditionVariable()); 2116d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 2117d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2118d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) { 2119d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt AddTypeLoc(E->getQueriedTypeSourceInfo()); 2120d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 2121d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2122d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) { 2123d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt AddTypeLoc(E->getRhsTypeSourceInfo()); 2124d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt AddTypeLoc(E->getLhsTypeSourceInfo()); 2125d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 2126d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2127d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) { 2128d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for (unsigned I = E->getNumArgs(); I > 0; --I) 2129d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt AddTypeLoc(E->getArg(I-1)); 2130d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 2131d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 21322b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenvoid EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) { 21332b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen AddTypeLoc(E->getQueriedTypeSourceInfo()); 21342b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen} 21352b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinen 21362b89da85b8cfe9bb862e8dd334855263c3522c00Jouni Malinenvoid EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) { 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnqueueChildren(E); 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) { 2141f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen VisitOverloadExpr(U); 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!U->isImplicitAccess()) 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(U->getBase()); 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) { 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(E->getSubExpr()); 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddTypeLoc(E->getWrittenTypeInfo()); 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) { 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WL.push_back(SizeOfPackExprParts(E, Parent)); 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) { 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // If the opaque value has a source expression, just transparently 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // visit that. This is useful for (e.g.) pseudo-object expressions. 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Expr *SourceExpr = E->getSourceExpr()) 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Visit(SourceExpr); 2157d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) { 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AddStmt(E->getBody()); 2160391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt WL.push_back(LambdaExprParts(E, Parent)); 2161391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt} 21626dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidtvoid EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) { 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Treat the expression like its syntactic form. 2164ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt Visit(E->getSyntacticForm()); 2165ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt} 2166661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 2167661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidtvoid CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) { 21681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S); 2169661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt} 21701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2171661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidtbool CursorVisitor::IsInRegionOfInterest(CXCursor C) { 21721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (RegionOfInterest.isValid()) { 21731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt SourceRange Range = getRawCursorExtent(C); 21741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (Range.isInvalid() || CompareRegionOfInterest(Range)) 21751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return false; 2176c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 21771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return true; 21781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 21791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtbool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { 21811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt while (!WL.empty()) { 21821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // Dequeue the worklist item. 21831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt VisitorJob LI = WL.back(); 21841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WL.pop_back(); 21851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // Set the Parent field, then back to its old value once we're done. 2187c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt SetParentRAII SetParent(Parent, StmtParent, LI.getParent()); 21881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (LI.getKind()) { 21901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case VisitorJob::DeclVisitKind: { 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const Decl *D = cast<DeclVisit>(&LI)->get(); 21921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!D) 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // For now, perform default visitation for Decls. 2196c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (Visit(MakeCXCursor(D, TU, RegionOfInterest, 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cast<DeclVisit>(&LI)->isFirst()))) 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 22011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 22021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case VisitorJob::ExplicitTemplateArgsVisitKind: { 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const ASTTemplateArgumentListInfo *ArgList = 220404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cast<ExplicitTemplateArgsVisit>(&LI)->get(); 220504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(), 220604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *ArgEnd = Arg + ArgList->NumTemplateArgs; 220704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt Arg != ArgEnd; ++Arg) { 220804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (VisitTemplateArgumentLoc(*Arg)) 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2213f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen case VisitorJob::TypeLocVisitKind: { 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Perform default visitation for TypeLocs. 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(cast<TypeLocVisit>(&LI)->get())) 2216f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen return true; 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2218f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen } 2219f8a26a8e6e081a2c576568198d0bcb4f976258acJouni Malinen case VisitorJob::LabelRefVisitKind: { 22201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get(); 2221f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (LabelStmt *stmt = LS->getStmt()) { 2222f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(), 2223f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt TU))) { 2224f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return true; 2225f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 2226f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 22271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 22281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 22291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 22301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case VisitorJob::NestedNameSpecifierLocVisitKind: { 22311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI); 22321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (VisitNestedNameSpecifierLoc(V->get())) 22331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return true; 22341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 2235f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 2236f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt 2237f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt case VisitorJob::DeclarationNameInfoVisitKind: { 2238f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI) 2239f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt ->get())) 2240f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return true; 2241f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt continue; 2242f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt } 22431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case VisitorJob::MemberRefVisitKind: { 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MemberRefVisit *V = cast<MemberRefVisit>(&LI); 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU))) 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 22481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case VisitorJob::StmtVisitKind: { 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const Stmt *S = cast<StmtVisit>(&LI)->get(); 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!S) 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Update the current cursor. 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest); 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!IsInRegionOfInterest(Cursor)) 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (Visitor(Cursor, Parent, ClientData)) { 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CXChildVisit_Break: return true; 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CXChildVisit_Continue: break; 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CXChildVisit_Recurse: 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (PostChildrenVisitor) 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WL.push_back(PostChildrenVisit(0, Cursor)); 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnqueueWorkList(WL, S); 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2267fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt continue; 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case VisitorJob::MemberExprPartsKind: { 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Handle the other pieces in the MemberExpr besides the base. 2271fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const MemberExpr *M = cast<MemberExprParts>(&LI)->get(); 2272fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2273fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt // Visit the nested-name-specifier 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc()) 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitNestedNameSpecifierLoc(QualifierLoc)) 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit the declaration name. 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitDeclarationNameInfo(M->getMemberNameInfo())) 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit the explicitly-specified template arguments, if any. 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (M->hasExplicitTemplateArgs()) { 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(), 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *ArgEnd = Arg + M->getNumTemplateArgs(); 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Arg != ArgEnd; ++Arg) { 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitTemplateArgumentLoc(*Arg)) 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 22921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 22931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case VisitorJob::DeclRefExprPartsKind: { 22941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get(); 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit nested-name-specifier, if present. 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc()) 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitNestedNameSpecifierLoc(QualifierLoc)) 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit declaration name. 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitDeclarationNameInfo(DR->getNameInfo())) 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case VisitorJob::OverloadExprPartsKind: { 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get(); 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit the nested-name-specifier. 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc()) 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitNestedNameSpecifierLoc(QualifierLoc)) 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit the declaration name. 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (VisitDeclarationNameInfo(O->getNameInfo())) 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit the overloaded declaration reference. 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCursorOverloadedDeclRef(O, TU))) 23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case VisitorJob::SizeOfPackExprPartsKind: { 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get(); 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NamedDecl *Pack = E->getPack(); 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (isa<TemplateTypeParmDecl>(Pack)) { 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack), 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt E->getPackLoc(), TU))) 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (isa<TemplateTemplateParmDecl>(Pack)) { 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack), 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt E->getPackLoc(), TU))) 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Non-type template parameter packs and function parameter packs are 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // treated like DeclRefExpr cursors. 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case VisitorJob::LambdaExprPartsKind: { 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit captures. 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get(); 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(), 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CEnd = E->explicit_capture_end(); 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C != CEnd; ++C) { 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (C->capturesThis()) 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2351fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (Visit(MakeCursorVariableRef(C->getCapturedVar(), 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C->getLocation(), 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TU))) 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit parameters and return type, if present. 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (E->hasExplicitParameters() || E->hasExplicitResultType()) { 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (E->hasExplicitParameters() && E->hasExplicitResultType()) { 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit the whole type. 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(TL)) 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (isa<FunctionProtoTypeLoc>(TL)) { 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL); 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (E->hasExplicitParameters()) { 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit parameters. 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(MakeCXCursor(Proto.getArg(I), TU))) 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Visit result type. 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Visit(Proto.getResultLoc())) 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case VisitorJob::PostChildrenVisitKind: 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (PostChildrenVisitor(Parent, ClientData)) 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return true; 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return false; 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtbool CursorVisitor::Visit(const Stmt *S) { 239104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt VisitorWorkList *WL = 0; 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!WorkListFreeList.empty()) { 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WL = WorkListFreeList.back(); 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WL->clear(); 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WorkListFreeList.pop_back(); 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WL = new VisitorWorkList(); 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WorkListCache.push_back(WL); 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnqueueWorkList(*WL, S); 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool result = RunVisitorWorkList(*WL); 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WorkListFreeList.push_back(WL); 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return result; 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnamespace { 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef SmallVector<SourceRange, 4> RefNamePieces; 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtRefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr, 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const DeclarationNameInfo &NI, 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const SourceRange &QLoc, 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const ASTTemplateArgumentListInfo *TemplateArgs = 0){ 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const bool WantQualifier = NameFlags & CXNameRange_WantQualifier; 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs; 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece; 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const DeclarationName::NameKind Kind = NI.getName().getNameKind(); 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RefNamePieces Pieces; 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WantQualifier && QLoc.isValid()) 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Pieces.push_back(QLoc); 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24244b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr) 24254b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt Pieces.push_back(NI.getLoc()); 24264b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt 24274b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt if (WantTemplateArgs && TemplateArgs) 24284b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc, 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TemplateArgs->RAngleLoc)); 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24316a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt if (Kind == DeclarationName::CXXOperatorName) { 24326a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt Pieces.push_back(SourceLocation::getFromRawEncoding( 24336a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt NI.getInfo().CXXOperatorName.BeginOpNameLoc)); 24346a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt Pieces.push_back(SourceLocation::getFromRawEncoding( 24356a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt NI.getInfo().CXXOperatorName.EndOpNameLoc)); 24366a9f522e56dae5b1fff00642e27b82e82772dcf7Sunil Dutt } 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WantSinglePiece) { 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd()); 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Pieces.clear(); 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Pieces.push_back(R); 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2443a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 244461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return Pieces; 244561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 244661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 244761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 244861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt//===----------------------------------------------------------------------===// 244961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt// Misc. API hooks. 245061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt//===----------------------------------------------------------------------===// 245161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 245261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic llvm::sys::Mutex EnableMultithreadingMutex; 245361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic bool EnabledMultithreading; 245461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2455a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic void fatal_error_handler(void *user_data, const std::string& reason) { 245661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt // Write the result out to stderr avoiding errs() because raw_ostreams can 245761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt // call report_fatal_error. 245861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str()); 2459a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ::abort(); 246061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 246161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern "C" { 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtCXIndex clang_createIndex(int excludeDeclarationsFromPCH, 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int displayDiagnostics) { 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Disable pretty stack trace functionality, which will otherwise be a very 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // poor citizen of the world and set up all sorts of signal handlers. 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::DisablePrettyStackTrace = true; 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // We use crash recovery to make some of our APIs more reliable, implicitly 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // enable it. 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::CrashRecoveryContext::Enable(); 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Enable support for multithreading in LLVM. 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::sys::ScopedLock L(EnableMultithreadingMutex); 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!EnabledMultithreading) { 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::install_fatal_error_handler(fatal_error_handler, 0); 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::llvm_start_multithreaded(); 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EnabledMultithreading = true; 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CIndexer *CIdxr = new CIndexer(); 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (excludeDeclarationsFromPCH) 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CIdxr->setOnlyLocalDecls(); 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (displayDiagnostics) 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CIdxr->setDisplayDiagnostics(); 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (getenv("LIBCLANG_BGPRIO_INDEX")) 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() | 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXGlobalOpt_ThreadBackgroundPriorityForIndexing); 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (getenv("LIBCLANG_BGPRIO_EDIT")) 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() | 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXGlobalOpt_ThreadBackgroundPriorityForEditing); 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return CIdxr; 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2499c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtvoid clang_disposeIndex(CXIndex CIdx) { 2500c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (CIdx) 2501c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt delete static_cast<CIndexer *>(CIdx); 2502c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt} 2503c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2504c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtvoid clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) { 2505c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (CIdx) 2506c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options); 2507c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt} 2508c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2509c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtunsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) { 2510c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (CIdx) 2511c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags(); 2512c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return 0; 2513c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt} 2514c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2515c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtvoid clang_toggleCrashRecovery(unsigned isEnabled) { 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (isEnabled) 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::CrashRecoveryContext::Enable(); 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::CrashRecoveryContext::Disable(); 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtCXTranslationUnit clang_createTranslationUnit(CXIndex CIdx, 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ast_filename) { 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CIdx) 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FileSystemOptions FileSystemOpts; 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IntrusiveRefCntPtr<DiagnosticsEngine> Diags; 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts, 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXXIdx->getOnlyLocalDecls(), 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, 0, 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /*CaptureDiagnostics=*/true, 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /*AllowPCHWithCompilerErrors=*/true, 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /*UserFilesAreVolatile=*/true); 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return MakeCXTranslationUnit(CXXIdx, TU); 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtunsigned clang_defaultEditingTranslationUnitOptions() { 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return CXTranslationUnit_PrecompiledPreamble | 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXTranslationUnit_CacheCompletionResults; 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtCXTranslationUnit 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtclang_createTranslationUnitFromSourceFile(CXIndex CIdx, 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *source_filename, 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_command_line_args, 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char * const *command_line_args, 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned num_unsaved_files, 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct CXUnsavedFile *unsaved_files) { 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord; 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return clang_parseTranslationUnit(CIdx, source_filename, 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt command_line_args, num_command_line_args, 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsaved_files, num_unsaved_files, 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Options); 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct ParseTranslationUnitInfo { 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXIndex CIdx; 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *source_filename; 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *const *command_line_args; 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_command_line_args; 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct CXUnsavedFile *unsaved_files; 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned num_unsaved_files; 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned options; 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXTranslationUnit result; 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void clang_parseTranslationUnit_Impl(void *UserData) { 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ParseTranslationUnitInfo *PTUI = 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static_cast<ParseTranslationUnitInfo*>(UserData); 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXIndex CIdx = PTUI->CIdx; 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *source_filename = PTUI->source_filename; 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char * const *command_line_args = PTUI->command_line_args; 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_command_line_args = PTUI->num_command_line_args; 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files; 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned num_unsaved_files = PTUI->num_unsaved_files; 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned options = PTUI->options; 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PTUI->result = 0; 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!CIdx) 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing)) 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt setThreadBackgroundPriority(); 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble; 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: Add a flag for modules. 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TranslationUnitKind TUKind 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete; 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool CacheCodeCompetionResults 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt = options & CXTranslationUnit_CacheCompletionResults; 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool IncludeBriefCommentsInCodeCompletion 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies; 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bool ForSerialization = options & CXTranslationUnit_ForSerialization; 2599c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2600c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // Configure the diagnostics. 2601c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt IntrusiveRefCntPtr<DiagnosticsEngine> 2602c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); 2603c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2604c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // Recover resources if we crash before exiting this function. 2605c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, 2606c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> > 2607c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt DiagCleanup(Diags.getPtr()); 2608c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2609c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt OwningPtr<std::vector<ASTUnit::RemappedFile> > 2610c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt RemappedFiles(new std::vector<ASTUnit::RemappedFile>()); 2611c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2612c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // Recover resources if we crash before exiting this function. 2613c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt llvm::CrashRecoveryContextCleanupRegistrar< 2614c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get()); 2615c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2616c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (unsigned I = 0; I != num_unsaved_files; ++I) { 2617344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); 2618344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt const llvm::MemoryBuffer *Buffer 2619344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); 2620344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename, 2621344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt Buffer)); 26226dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt } 2623c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2624c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt OwningPtr<std::vector<const char *> > 2625391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt Args(new std::vector<const char*>()); 2626c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2627c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // Recover resources if we crash before exiting this method. 2628c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> > 2629c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ArgsCleanup(Args.get()); 2630c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2631c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // Since the Clang C library is primarily used by batch tools dealing with 2632c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // (often very broken) source code, where spell-checking can have a 2633c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // significant negative impact on performance (particularly when 2634c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // precompiled headers are involved), we disable it by default. 2635c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // Only do this if we haven't found a spell-checking-related argument. 2636c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt bool FoundSpellCheckingArgument = false; 2637c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (int I = 0; I != num_command_line_args; ++I) { 2638c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 || 2639c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt strcmp(command_line_args[I], "-fspell-checking") == 0) { 2640c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt FoundSpellCheckingArgument = true; 2641c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt break; 2642c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 2643c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 2644c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!FoundSpellCheckingArgument) 2645c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt Args->push_back("-fno-spell-checking"); 2646c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2647c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt Args->insert(Args->end(), command_line_args, 2648c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt command_line_args + num_command_line_args); 2649c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2650c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // The 'source_filename' argument is optional. If the caller does not 2651c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // specify it then it is assumed that the source file is specified 2652c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // in the actual argument list. 2653c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // Put the source file after command_line_args otherwise if '-x' flag is 2654c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // present it will be unused. 2655c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (source_filename) 2656c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt Args->push_back(source_filename); 2657c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2658c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // Do we need the detailed preprocessing record? 2659c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (options & CXTranslationUnit_DetailedPreprocessingRecord) { 2660c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt Args->push_back("-Xclang"); 2661c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt Args->push_back("-detailed-preprocessing-record"); 2662c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 2663c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2664c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsigned NumErrors = Diags->getClient()->getNumErrors(); 2665c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt OwningPtr<ASTUnit> ErrUnit; 2666c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt OwningPtr<ASTUnit> Unit( 2667c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0 2668c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt /* vector::data() not portable */, 2669c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt Args->size() ? (&(*Args)[0] + Args->size()) :0, 2670c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt Diags, 2671c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt CXXIdx->getClangResourcesPath(), 2672c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt CXXIdx->getOnlyLocalDecls(), 2673c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt /*CaptureDiagnostics=*/true, 2674c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt RemappedFiles->size() ? &(*RemappedFiles)[0]:0, 2675c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt RemappedFiles->size(), 2676c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt /*RemappedFilesKeepOriginalName=*/true, 2677c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt PrecompilePreamble, 2678c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt TUKind, 2679c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt CacheCodeCompetionResults, 2680c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt IncludeBriefCommentsInCodeCompletion, 2681c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt /*AllowPCHWithCompilerErrors=*/true, 2682c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt SkipFunctionBodies, 2683c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt /*UserFilesAreVolatile=*/true, 2684c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ForSerialization, 2685c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt &ErrUnit)); 2686c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2687c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (NumErrors != Diags->getClient()->getNumErrors()) { 2688c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt // Make sure to check that 'Unit' is non-NULL. 2689c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (CXXIdx->getDisplayDiagnostics()) 2690c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get()); 2691c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 2692c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2693c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take()); 2694c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt} 2695c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry ShmidtCXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, 2696c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt const char *source_filename, 2697c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt const char * const *command_line_args, 2698c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int num_command_line_args, 2699c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt struct CXUnsavedFile *unsaved_files, 2700c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsigned num_unsaved_files, 2701c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsigned options) { 2702c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt LOG_FUNC_SECTION { 2703c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt *Log << source_filename << ": "; 2704c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (int i = 0; i != num_command_line_args; ++i) 2705c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt *Log << command_line_args[i] << " "; 2706c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 2707c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2708c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args, 2709c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt num_command_line_args, unsaved_files, 2710c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt num_unsaved_files, options, 0 }; 2711c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt llvm::CrashRecoveryContext CRC; 2712c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 2713c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) { 2714c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt fprintf(stderr, "libclang: crash detected during parsing: {\n"); 2715c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt fprintf(stderr, " 'source_filename' : '%s'\n", source_filename); 2716c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt fprintf(stderr, " 'command_line_args' : ["); 2717c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (int i = 0; i != num_command_line_args; ++i) { 2718c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (i) 2719c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt fprintf(stderr, ", "); 2720c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt fprintf(stderr, "'%s'", command_line_args[i]); 2721c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 2722c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt fprintf(stderr, "],\n"); 2723c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt fprintf(stderr, " 'unsaved_files' : ["); 2724c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (unsigned i = 0; i != num_unsaved_files; ++i) { 2725c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (i) 2726c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt fprintf(stderr, ", "); 2727c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename, 2728c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsaved_files[i].Length); 2729c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 2730c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt fprintf(stderr, "],\n"); 27317dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt fprintf(stderr, " 'options' : %d,\n", options); 27327dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt fprintf(stderr, "}\n"); 27337dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 27347dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt return 0; 27357dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt } else if (getenv("LIBCLANG_RESOURCE_USAGE")) { 27367dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt PrintLibclangResourceUsage(PTUI.result); 27377dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt } 27387dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 27397dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt return PTUI.result; 27407dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt} 27417dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 27427dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidtunsigned clang_defaultSaveOptions(CXTranslationUnit TU) { 27437dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt return CXSaveTranslationUnit_None; 27447dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt} 27457dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 27467dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidtnamespace { 27477dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 27487dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidtstruct SaveTranslationUnitInfo { 27497dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt CXTranslationUnit TU; 27507dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt const char *FileName; 27517dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt unsigned options; 27527dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt CXSaveError result; 27537dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt}; 27547dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 27557dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt} 27567dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 27577dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidtstatic void clang_saveTranslationUnit_Impl(void *UserData) { 27587dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt SaveTranslationUnitInfo *STUI = 27597dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt static_cast<SaveTranslationUnitInfo*>(UserData); 27607dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 27617dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt CIndexer *CXXIdx = (CIndexer*)STUI->TU->CIdx; 27627dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing)) 27637dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt setThreadBackgroundPriority(); 27647dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 27657dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName); 27667dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None; 27677dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt} 27687dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 2769cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtint clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName, 2770cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt unsigned options) { 2771cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt LOG_FUNC_SECTION { 27727dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt *Log << TU << ' ' << FileName; 2773c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt } 27747dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 27757dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt if (!TU) 27767dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt return CXSaveError_InvalidTU; 2777cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2778cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 2779cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ASTUnit::ConcurrencyCheck Check(*CXXUnit); 2780cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!CXXUnit->hasSema()) 2781cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return CXSaveError_InvalidTU; 2782cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2783cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None }; 2784cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2785cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() || 2786cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt getenv("LIBCLANG_NOTHREADS")) { 278701904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt clang_saveTranslationUnit_Impl(&STUI); 2788cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2789cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (getenv("LIBCLANG_RESOURCE_USAGE")) 279001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt PrintLibclangResourceUsage(TU); 279101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt 279201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt return STUI.result; 2793cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2794cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2795cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt // We have an AST that has invalid nodes due to compiler errors. 2796cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt // Use a crash recovery thread for protection. 2797cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2798cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt llvm::CrashRecoveryContext CRC; 2799cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2800cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) { 2801cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt fprintf(stderr, "libclang: crash detected during AST saving: {\n"); 2802cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt fprintf(stderr, " 'filename' : '%s'\n", FileName); 2803fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt fprintf(stderr, " 'options' : %d,\n", options); 2804623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt fprintf(stderr, "}\n"); 2805fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2806623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt return CXSaveError_Unknown; 2807fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2808fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } else if (getenv("LIBCLANG_RESOURCE_USAGE")) { 2809fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt PrintLibclangResourceUsage(TU); 2810fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 2811fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2812fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return STUI.result; 2813fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 2814623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt 2815623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidtvoid clang_disposeTranslationUnit(CXTranslationUnit CTUnit) { 2816fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (CTUnit) { 2817623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt // If the translation unit has been marked as unsafe to free, just discard 2818fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt // it. 2819fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree()) 2820fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 2821fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2822fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt delete cxtu::getASTUnit(CTUnit); 2823fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt disposeCXStringPool(CTUnit->StringPool); 2824fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics); 2825fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool); 2826fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt delete static_cast<SimpleFormatContext*>(CTUnit->FormatContext); 2827fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt delete CTUnit; 2828fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 2829fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 2830fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2831fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtunsigned clang_defaultReparseOptions(CXTranslationUnit TU) { 2832fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return CXReparse_None; 2833fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 2834fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2835fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstruct ReparseTranslationUnitInfo { 2836fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt CXTranslationUnit TU; 2837fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt unsigned num_unsaved_files; 2838fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct CXUnsavedFile *unsaved_files; 2839fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt unsigned options; 2840fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int result; 2841fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}; 2842fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2843fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic void clang_reparseTranslationUnit_Impl(void *UserData) { 2844fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ReparseTranslationUnitInfo *RTUI = 2845fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt static_cast<ReparseTranslationUnitInfo*>(UserData); 2846fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt CXTranslationUnit TU = RTUI->TU; 28471846323989242844f0e857458a8939fa5836429cDmitry Shmidt if (!TU) 28481846323989242844f0e857458a8939fa5836429cDmitry Shmidt return; 2849fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 28501846323989242844f0e857458a8939fa5836429cDmitry Shmidt // Reset the associated diagnostics. 2851fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics); 2852fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt TU->Diagnostics = 0; 2853fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2854fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt unsigned num_unsaved_files = RTUI->num_unsaved_files; 2855fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files; 2856fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt unsigned options = RTUI->options; 2857fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt (void) options; 2858fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt RTUI->result = 1; 2859fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2860fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt CIndexer *CXXIdx = (CIndexer*)TU->CIdx; 2861fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing)) 2862fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt setThreadBackgroundPriority(); 2863fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2864fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 2865fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ASTUnit::ConcurrencyCheck Check(*CXXUnit); 2866fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2867fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt OwningPtr<std::vector<ASTUnit::RemappedFile> > 2868fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt RemappedFiles(new std::vector<ASTUnit::RemappedFile>()); 2869fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2870fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt // Recover resources if we crash before exiting this function. 2871fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt llvm::CrashRecoveryContextCleanupRegistrar< 2872fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get()); 2873fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2874fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt for (unsigned I = 0; I != num_unsaved_files; ++I) { 2875fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); 2876fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const llvm::MemoryBuffer *Buffer 2877fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); 2878fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename, 2879fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt Buffer)); 2880fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 2881fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2882fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0, 2883fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt RemappedFiles->size())) 2884fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt RTUI->result = 0; 2885cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 2886cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2887cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint clang_reparseTranslationUnit(CXTranslationUnit TU, 2888cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt unsigned num_unsaved_files, 2889cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt struct CXUnsavedFile *unsaved_files, 2890cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt unsigned options) { 2891cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt LOG_FUNC_SECTION { 2892cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt *Log << TU; 2893cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 2894cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2895cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files, 2896cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt options, 0 }; 2897cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2898cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (getenv("LIBCLANG_NOTHREADS")) { 2899cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt clang_reparseTranslationUnit_Impl(&RTUI); 2900cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return RTUI.result; 2901cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 2902cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2903cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt llvm::CrashRecoveryContext CRC; 2904cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2905cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) { 2906cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt fprintf(stderr, "libclang: crash detected during reparsing\n"); 2907cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt cxtu::getASTUnit(TU)->setUnsafeToFree(true); 2908cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 1; 2909cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } else if (getenv("LIBCLANG_RESOURCE_USAGE")) 2910cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt PrintLibclangResourceUsage(TU); 2911cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2912cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return RTUI.result; 2913cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 2914cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2915cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2916cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry ShmidtCXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) { 2917cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (!CTUnit) 2918cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return createCXString(""); 2919cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2920cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit); 2921cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return createCXString(CXXUnit->getOriginalSourceFileName(), true); 2922cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 2923cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2924cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry ShmidtCXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) { 2925cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 2926cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU); 2927cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 2928cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2929cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} // end: extern "C" 2930cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2931cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt//===----------------------------------------------------------------------===// 2932cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt// CXFile Operations. 2933cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt//===----------------------------------------------------------------------===// 2934cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 2935cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtextern "C" { 2936cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry ShmidtCXString clang_getFileName(CXFile SFile) { 29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!SFile) 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString((const char*)NULL); 29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FileEntry *FEnt = static_cast<FileEntry *>(SFile); 29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(FEnt->getName()); 29428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidttime_t clang_getFileTime(CXFile SFile) { 29451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!SFile) 29461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 29471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 29481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt FileEntry *FEnt = static_cast<FileEntry *>(SFile); 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FEnt->getModificationTime(); 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtCXFile clang_getFile(CXTranslationUnit TU, const char *file_name) { 29531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!TU) 29541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 29551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 295604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 29571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 29581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt FileManager &FMgr = CXXUnit->getFileManager(); 29591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return const_cast<FileEntry *>(FMgr.getFile(file_name)); 29601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 29611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 29621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtunsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) { 29631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!TU || !file) 29641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 29651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 29661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 29671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt FileEntry *FEnt = static_cast<FileEntry *>(file); 29681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return CXXUnit->getPreprocessor().getHeaderSearchInfo() 29691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt .isFileMultipleIncludeGuarded(FEnt); 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) { 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!file || !outID) 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef LLVM_ON_WIN32 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; // inodes not supported on windows. 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else 2979c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt FileEntry *FEnt = static_cast<FileEntry *>(file); 2980c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt outID->data[0] = FEnt->getDevice(); 2981c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt outID->data[1] = FEnt->getInode(); 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outID->data[2] = FEnt->getModificationTime(); 2983c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return 0; 2984c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt#endif 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} // end: extern "C" 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//===----------------------------------------------------------------------===// 2990fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt// CXCursor Operations. 2991fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt//===----------------------------------------------------------------------===// 2992fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2993fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic const Decl *getDeclFromExpr(const Stmt *E) { 2994fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) 2995fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return getDeclFromExpr(CE->getSubExpr()); 2996fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 2997fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E)) 2998fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return RefExpr->getDecl(); 2999fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) 3000fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return ME->getMemberDecl(); 3001fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E)) 3002fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return RE->getDecl(); 3003661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) { 3004661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (PRE->isExplicitProperty()) 3005661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return PRE->getExplicitProperty(); 3006fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt // It could be messaging both getter and setter as in: 3007661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt // ++myobj.myprop; 3008661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt // in which case prefer to associate the setter since it is less obvious 3009fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt // from inspecting the source that the setter is going to get called. 3010fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (PRE->isMessagingSetter()) 3011fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return PRE->getImplicitPropertySetter(); 3012fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return PRE->getImplicitPropertyGetter(); 3013661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 3014fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) 3015fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return getDeclFromExpr(POE->getSyntacticForm()); 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) 3017fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (Expr *Src = OVE->getSourceExpr()) 3018fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return getDeclFromExpr(Src); 3019fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3020fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (const CallExpr *CE = dyn_cast<CallExpr>(E)) 3021fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return getDeclFromExpr(CE->getCallee()); 3022fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E)) 3023fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (!CE->isElidable()) 3024fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return CE->getConstructor(); 3025fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E)) 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return OME->getMethodDecl(); 3027fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3028fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E)) 3029fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return PE->getProtocol(); 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const SubstNonTypeTemplateParmPackExpr *NTTP 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E)) 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NTTP->getParameterPack(); 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E)) 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) || 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt isa<ParmVarDecl>(SizeOfPack->getPack())) 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return SizeOfPack->getPack(); 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic SourceLocation getLocationFromExpr(const Expr *E) { 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return getLocationFromExpr(CE->getSubExpr()); 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return /*FIXME:*/Msg->getLeftLoc(); 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return DRE->getLocation(); 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const MemberExpr *Member = dyn_cast<MemberExpr>(E)) 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return Member->getMemberLoc(); 3051a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E)) 305261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return Ivar->getLocation(); 305361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E)) 305461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return SizeOfPack->getPackLoc(); 3055a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E)) 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return PropRef->getLocation(); 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return E->getLocStart(); 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern "C" { 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtunsigned clang_visitChildren(CXCursor parent, 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXCursorVisitor visitor, 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXClientData client_data) { 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data, 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /*VisitPreprocessorLast=*/false); 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return CursorVis.VisitChildren(parent); 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef __has_feature 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define __has_feature(x) 0 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if __has_feature(blocks) 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef enum CXChildVisitResult 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent); 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078b485b188f853a4ec5342c2ea49705b545b2caf3dJeff Johnsonstatic enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent, 3079d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt CXClientData client_data) { 3080d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data; 3081d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return block(cursor, parent); 3082d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 3083d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#else 3084d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt// If we are compiled with a compiler that doesn't have native blocks support, 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt// define and call the block manually, so the 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct _CXChildVisitResult 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *isa; 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int flags; 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reserved; 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor, 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXCursor); 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} *CXCursorVisitorBlock; 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent, 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXClientData client_data) { 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data; 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return block->invoke(block, cursor, parent); 30991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 31011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtunsigned clang_visitChildrenWithBlock(CXCursor parent, 31041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt CXCursorVisitorBlock block) { 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return clang_visitChildren(parent, visitWithBlock, block); 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic CXString getDeclSpelling(const Decl *D) { 31091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!D) 31101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString(""); 31111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const NamedDecl *ND = dyn_cast<NamedDecl>(D); 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ND) { 31141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (const ObjCPropertyImplDecl *PropImpl = 31151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dyn_cast<ObjCPropertyImplDecl>(D)) 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl()) 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(Property->getIdentifier()->getName()); 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D)) 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Module *Mod = ImportD->getImportedModule()) 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(Mod->getFullModuleName()); 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(""); 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(OMD->getSelector().getAsString()); 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND)) 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // No, this isn't the same as the code below. getIdentifier() is non-virtual 31311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // and returns different names. NamedDecl returns the class name and 31321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt // ObjCCategoryImplDecl returns the category name. 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(CIMP->getIdentifier()->getNameStart()); 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (isa<UsingDirectiveDecl>(D)) 31361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString(""); 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SmallString<1024> S; 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::raw_svector_ostream os(S); 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ND->printName(os); 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(os.str()); 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtCXString clang_getCursorSpelling(CXCursor C) { 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (clang_isTranslationUnit(C.kind)) 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return clang_getTranslationUnitSpelling(getCursorTU(C)); 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (clang_isReference(C.kind)) { 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (C.kind) { 31511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case CXCursor_ObjCSuperClassRef: { 31521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first; 31531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString(Super->getIdentifier()->getNameStart()); 31541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 31551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case CXCursor_ObjCClassRef: { 31561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; 31571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString(Class->getIdentifier()->getNameStart()); 31581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 31591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case CXCursor_ObjCProtocolRef: { 31601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first; 31611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt assert(OID && "getCursorSpelling(): Missing protocol decl"); 31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(OID->getIdentifier()->getNameStart()); 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CXCursor_CXXBaseSpecifier: { 31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); 31661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString(B->getType().getAsString()); 31671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CXCursor_TypeRef: { 316904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const TypeDecl *Type = getCursorTypeRef(C).first; 317004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt assert(Type && "Missing type decl"); 317104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 317204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return createCXString(getCursorContext(C).getTypeDeclType(Type). 317304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt getAsString()); 317404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 317504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case CXCursor_TemplateRef: { 317604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const TemplateDecl *Template = getCursorTemplateRef(C).first; 317704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt assert(Template && "Missing template decl"); 317804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 317904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return createCXString(Template->getNameAsString()); 318004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt } 318104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 318204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt case CXCursor_NamespaceRef: { 318304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt const NamedDecl *NS = getCursorNamespaceRef(C).first; 318404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt assert(NS && "Missing namespace decl"); 3185c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 318604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return createCXString(NS->getNameAsString()); 318704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 318804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 318904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case CXCursor_MemberRef: { 3190818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt const FieldDecl *Field = getCursorMemberRef(C).first; 3191818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt assert(Field && "Missing member decl"); 3192818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 3193818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return createCXString(Field->getNameAsString()); 3194818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 3195818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 3196818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt case CXCursor_LabelRef: { 3197818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt const LabelStmt *Label = getCursorLabelRef(C).first; 3198818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt assert(Label && "Missing label"); 3199818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 3200818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt return createCXString(Label->getName()); 3201818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt } 3202818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 3203818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt case CXCursor_OverloadedDeclRef: { 3204818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first; 3205818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (const Decl *D = Storage.dyn_cast<const Decl *>()) { 3206818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 320704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return createCXString(ND->getNameAsString()); 320804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return createCXString(""); 320904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 321004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>()) 321104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return createCXString(E->getName().getAsString()); 3212c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt OverloadedTemplateStorage *Ovl 32138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt = Storage.get<OverloadedTemplateStorage*>(); 3214c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (Ovl->size() == 0) 32158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(""); 32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString((*Ovl->begin())->getNameAsString()); 32178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CXCursor_VariableRef: { 32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const VarDecl *Var = getCursorVariableRef(C).first; 32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt assert(Var && "Missing variable decl"); 32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 322304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return createCXString(Var->getNameAsString()); 322404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 322504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 322604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt default: 32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString("<not implemented>"); 32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3230c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 3231c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (clang_isExpression(C.kind)) { 3232c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt const Decl *D = getDeclFromExpr(getCursorExpr(C)); 3233c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (D) 3234c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return getDeclSpelling(D); 3235c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return createCXString(""); 3236c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 3237fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3238fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (clang_isStatement(C.kind)) { 3239fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const Stmt *S = getCursorStmt(C); 3240623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) 3241623d63a3a443027e50efdaaec027befcc3882527Dmitry Shmidt return createCXString(Label->getName()); 3242fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 3243fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return createCXString(""); 3244fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 3245fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (C.kind == CXCursor_MacroExpansion) 32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(getCursorMacroExpansion(C).getName() 32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ->getNameStart()); 3249c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (C.kind == CXCursor_MacroDefinition) 325104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return createCXString(getCursorMacroDefinition(C)->getName() 325204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ->getNameStart()); 325304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 325404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (C.kind == CXCursor_InclusionDirective) 325504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return createCXString(getCursorInclusionDirective(C)->getFileName()); 325604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 325704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (clang_isDeclaration(C.kind)) 325804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return getDeclSpelling(getCursorDecl(C)); 325904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 326004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (C.kind == CXCursor_AnnotateAttr) { 326104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C)); 326204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return createCXString(AA->getAnnotation()); 326304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3265c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (C.kind == CXCursor_AsmLabelAttr) { 32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C)); 326704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return createCXString(AA->getLabel()); 32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(""); 32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtCXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, 32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned pieceIndex, 32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned options) { 32761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (clang_Cursor_isNull(C)) 32771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return clang_getNullRange(); 32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 327904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ASTContext &Ctx = getCursorContext(C); 328004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (clang_isStatement(C.kind)) { 32828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const Stmt *S = getCursorStmt(C); 32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) { 32848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pieceIndex > 0) 32851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return clang_getNullRange(); 32861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return cxloc::translateSourceRange(Ctx, Label->getIdentLoc()); 32878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 328804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 328904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return clang_getNullRange(); 32908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (C.kind == CXCursor_ObjCMessageExpr) { 32931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (const ObjCMessageExpr * 32941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) { 32951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (pieceIndex >= ME->getNumSelectorLocs()) 32961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return clang_getNullRange(); 32978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex)); 32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (C.kind == CXCursor_ObjCInstanceMethodDecl || 33021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt C.kind == CXCursor_ObjCClassMethodDecl) { 33031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (const ObjCMethodDecl * 33041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) { 33051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (pieceIndex >= MD->getNumSelectorLocs()) 33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return clang_getNullRange(); 33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex)); 33088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (C.kind == CXCursor_ObjCCategoryDecl || 33128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt C.kind == CXCursor_ObjCCategoryImplDecl) { 33138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pieceIndex > 0) 33148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return clang_getNullRange(); 33157dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt if (const ObjCCategoryDecl * 33167dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C))) 33177dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc()); 33187dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt if (const ObjCCategoryImplDecl * 33197dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C))) 33207dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc()); 33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (C.kind == CXCursor_ModuleImportDecl) { 33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pieceIndex > 0) 33258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return clang_getNullRange(); 33268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (const ImportDecl *ImportD = 33278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) { 33288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs(); 33298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!Locs.empty()) 33301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return cxloc::translateSourceRange(Ctx, 3331df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt SourceRange(Locs.front(), Locs.back())); 3332df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 3333df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt return clang_getNullRange(); 3334df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt } 3335df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt 3336df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt // FIXME: A CXCursor_InclusionDirective should give the location of the 33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // filename, but we don't keep track of this. 33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation 33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // but we don't keep track of this. 33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // FIXME: A CXCursor_AsmLabelAttr should give the location of the label 33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // but we don't keep track of this. 33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // Default handling, give the location of the cursor. 33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pieceIndex > 0) 33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return clang_getNullRange(); 33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CXSourceLocation CXLoc = clang_getCursorLocation(C); 33518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SourceLocation Loc = cxloc::translateSourceLocation(CXLoc); 33528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return cxloc::translateSourceRange(Ctx, Loc); 335301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt} 335401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt 335501904cfafd75a70b9f29c0220b90bdef45595491Dmitry ShmidtCXString clang_getCursorDisplayName(CXCursor C) { 335601904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt if (!clang_isDeclaration(C.kind)) 335701904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt return clang_getCursorSpelling(C); 335801904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt 335901904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt const Decl *D = getCursorDecl(C); 336001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt if (!D) 336101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt return createCXString(""); 336201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt 336301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy(); 336401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) 33656dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt D = FunTmpl->getTemplatedDecl(); 33666dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt 33676dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { 33686dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt SmallString<64> Str; 33696dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt llvm::raw_svector_ostream OS(Str); 33706dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt OS << *Function; 33716dc03bd757d3befd2c03a543a402338db03914d6Dmitry Shmidt if (Function->getPrimaryTemplate()) 337201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt OS << "<>"; 337301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt OS << "("; 33747832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) { 33757832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (I) 33767832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt OS << ", "; 33777832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt OS << Function->getParamDecl(I)->getType().getAsString(Policy); 33787832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt } 33797832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt 33807832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (Function->isVariadic()) { 33817832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt if (Function->getNumParams()) 33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << ", "; 3383bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt OS << "..."; 3384bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt } 33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << ")"; 33868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(OS.str()); 33878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 33887dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt 33897dba0e5708da7276a43a44cf479aa743564e15b9Dmitry Shmidt if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) { 33908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SmallString<64> Str; 33918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::raw_svector_ostream OS(Str); 33928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << *ClassTemplate; 33938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << "<"; 33948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TemplateParameterList *Params = ClassTemplate->getTemplateParameters(); 33958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (unsigned I = 0, N = Params->size(); I != N; ++I) { 33968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (I) 33978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << ", "; 33988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NamedDecl *Param = Params->getParam(I); 34008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (Param->getIdentifier()) { 34018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << Param->getIdentifier()->getName(); 34028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 34038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // There is no parameter name, which makes this tricky. Try to come up 34068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt // with something useful that isn't too long. 34078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) 34088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << (TTP->wasDeclaredWithTypename()? "typename" : "class"); 34098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (NonTypeTemplateParmDecl *NTTP 34108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt = dyn_cast<NonTypeTemplateParmDecl>(Param)) 34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << NTTP->getType().getAsString(Policy); 34128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << "template<...> class"; 34148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << ">"; 34178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString(OS.str()); 34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (const ClassTemplateSpecializationDecl *ClassSpec 34211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 342243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt // If the type was explicitly written, use that. 342343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten()) 34241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString(TSInfo->getType().getAsString(Policy)); 34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SmallString<64> Str; 34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt llvm::raw_svector_ostream OS(Str); 34288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << *ClassSpec; 34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OS << TemplateSpecializationType::PrintTemplateArgumentList( 34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ClassSpec->getTemplateArgs().data(), 34311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ClassSpec->getTemplateArgs().size(), 34321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt Policy); 34331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString(OS.str()); 34341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 34351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 34361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return clang_getCursorSpelling(C); 34371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 34381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 34391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtCXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { 34401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (Kind) { 34411846323989242844f0e857458a8939fa5836429cDmitry Shmidt case CXCursor_FunctionDecl: 34421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString("FunctionDecl"); 34431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case CXCursor_TypedefDecl: 34441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString("TypedefDecl"); 34451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case CXCursor_EnumDecl: 34461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString("EnumDecl"); 34471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case CXCursor_EnumConstantDecl: 34481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString("EnumConstantDecl"); 34491846323989242844f0e857458a8939fa5836429cDmitry Shmidt case CXCursor_StructDecl: 34501846323989242844f0e857458a8939fa5836429cDmitry Shmidt return createCXString("StructDecl"); 34511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case CXCursor_UnionDecl: 34529866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt return createCXString("UnionDecl"); 34539866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt case CXCursor_ClassDecl: 34549866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt return createCXString("ClassDecl"); 34559866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt case CXCursor_FieldDecl: 34569866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt return createCXString("FieldDecl"); 34571846323989242844f0e857458a8939fa5836429cDmitry Shmidt case CXCursor_VarDecl: 34581846323989242844f0e857458a8939fa5836429cDmitry Shmidt return createCXString("VarDecl"); 34591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case CXCursor_ParmDecl: 34601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString("ParmDecl"); 34611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case CXCursor_ObjCInterfaceDecl: 34621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString("ObjCInterfaceDecl"); 34631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case CXCursor_ObjCCategoryDecl: 34641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return createCXString("ObjCCategoryDecl"); 3465cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case CXCursor_ObjCProtocolDecl: 3466cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return createCXString("ObjCProtocolDecl"); 3467cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case CXCursor_ObjCPropertyDecl: 3468f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return createCXString("ObjCPropertyDecl"); 3469f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt case CXCursor_ObjCIvarDecl: 3470f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return createCXString("ObjCIvarDecl"); 3471f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt case CXCursor_ObjCInstanceMethodDecl: 3472f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return createCXString("ObjCInstanceMethodDecl"); 3473f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt case CXCursor_ObjCClassMethodDecl: 3474f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return createCXString("ObjCClassMethodDecl"); 3475f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt case CXCursor_ObjCImplementationDecl: 3476f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return createCXString("ObjCImplementationDecl"); 3477f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt case CXCursor_ObjCCategoryImplDecl: 34788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString("ObjCCategoryImplDecl"); 34798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CXCursor_CXXMethod: 34808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString("CXXMethod"); 34818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CXCursor_UnexposedDecl: 34828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return createCXString("UnexposedDecl"); 3483 case CXCursor_ObjCSuperClassRef: 3484 return createCXString("ObjCSuperClassRef"); 3485 case CXCursor_ObjCProtocolRef: 3486 return createCXString("ObjCProtocolRef"); 3487 case CXCursor_ObjCClassRef: 3488 return createCXString("ObjCClassRef"); 3489 case CXCursor_TypeRef: 3490 return createCXString("TypeRef"); 3491 case CXCursor_TemplateRef: 3492 return createCXString("TemplateRef"); 3493 case CXCursor_NamespaceRef: 3494 return createCXString("NamespaceRef"); 3495 case CXCursor_MemberRef: 3496 return createCXString("MemberRef"); 3497 case CXCursor_LabelRef: 3498 return createCXString("LabelRef"); 3499 case CXCursor_OverloadedDeclRef: 3500 return createCXString("OverloadedDeclRef"); 3501 case CXCursor_VariableRef: 3502 return createCXString("VariableRef"); 3503 case CXCursor_IntegerLiteral: 3504 return createCXString("IntegerLiteral"); 3505 case CXCursor_FloatingLiteral: 3506 return createCXString("FloatingLiteral"); 3507 case CXCursor_ImaginaryLiteral: 3508 return createCXString("ImaginaryLiteral"); 3509 case CXCursor_StringLiteral: 3510 return createCXString("StringLiteral"); 3511 case CXCursor_CharacterLiteral: 3512 return createCXString("CharacterLiteral"); 3513 case CXCursor_ParenExpr: 3514 return createCXString("ParenExpr"); 3515 case CXCursor_UnaryOperator: 3516 return createCXString("UnaryOperator"); 3517 case CXCursor_ArraySubscriptExpr: 3518 return createCXString("ArraySubscriptExpr"); 3519 case CXCursor_BinaryOperator: 3520 return createCXString("BinaryOperator"); 3521 case CXCursor_CompoundAssignOperator: 3522 return createCXString("CompoundAssignOperator"); 3523 case CXCursor_ConditionalOperator: 3524 return createCXString("ConditionalOperator"); 3525 case CXCursor_CStyleCastExpr: 3526 return createCXString("CStyleCastExpr"); 3527 case CXCursor_CompoundLiteralExpr: 3528 return createCXString("CompoundLiteralExpr"); 3529 case CXCursor_InitListExpr: 3530 return createCXString("InitListExpr"); 3531 case CXCursor_AddrLabelExpr: 3532 return createCXString("AddrLabelExpr"); 3533 case CXCursor_StmtExpr: 3534 return createCXString("StmtExpr"); 3535 case CXCursor_GenericSelectionExpr: 3536 return createCXString("GenericSelectionExpr"); 3537 case CXCursor_GNUNullExpr: 3538 return createCXString("GNUNullExpr"); 3539 case CXCursor_CXXStaticCastExpr: 3540 return createCXString("CXXStaticCastExpr"); 3541 case CXCursor_CXXDynamicCastExpr: 3542 return createCXString("CXXDynamicCastExpr"); 3543 case CXCursor_CXXReinterpretCastExpr: 3544 return createCXString("CXXReinterpretCastExpr"); 3545 case CXCursor_CXXConstCastExpr: 3546 return createCXString("CXXConstCastExpr"); 3547 case CXCursor_CXXFunctionalCastExpr: 3548 return createCXString("CXXFunctionalCastExpr"); 3549 case CXCursor_CXXTypeidExpr: 3550 return createCXString("CXXTypeidExpr"); 3551 case CXCursor_CXXBoolLiteralExpr: 3552 return createCXString("CXXBoolLiteralExpr"); 3553 case CXCursor_CXXNullPtrLiteralExpr: 3554 return createCXString("CXXNullPtrLiteralExpr"); 3555 case CXCursor_CXXThisExpr: 3556 return createCXString("CXXThisExpr"); 3557 case CXCursor_CXXThrowExpr: 3558 return createCXString("CXXThrowExpr"); 3559 case CXCursor_CXXNewExpr: 3560 return createCXString("CXXNewExpr"); 3561 case CXCursor_CXXDeleteExpr: 3562 return createCXString("CXXDeleteExpr"); 3563 case CXCursor_UnaryExpr: 3564 return createCXString("UnaryExpr"); 3565 case CXCursor_ObjCStringLiteral: 3566 return createCXString("ObjCStringLiteral"); 3567 case CXCursor_ObjCBoolLiteralExpr: 3568 return createCXString("ObjCBoolLiteralExpr"); 3569 case CXCursor_ObjCEncodeExpr: 3570 return createCXString("ObjCEncodeExpr"); 3571 case CXCursor_ObjCSelectorExpr: 3572 return createCXString("ObjCSelectorExpr"); 3573 case CXCursor_ObjCProtocolExpr: 3574 return createCXString("ObjCProtocolExpr"); 3575 case CXCursor_ObjCBridgedCastExpr: 3576 return createCXString("ObjCBridgedCastExpr"); 3577 case CXCursor_BlockExpr: 3578 return createCXString("BlockExpr"); 3579 case CXCursor_PackExpansionExpr: 3580 return createCXString("PackExpansionExpr"); 3581 case CXCursor_SizeOfPackExpr: 3582 return createCXString("SizeOfPackExpr"); 3583 case CXCursor_LambdaExpr: 3584 return createCXString("LambdaExpr"); 3585 case CXCursor_UnexposedExpr: 3586 return createCXString("UnexposedExpr"); 3587 case CXCursor_DeclRefExpr: 3588 return createCXString("DeclRefExpr"); 3589 case CXCursor_MemberRefExpr: 3590 return createCXString("MemberRefExpr"); 3591 case CXCursor_CallExpr: 3592 return createCXString("CallExpr"); 3593 case CXCursor_ObjCMessageExpr: 3594 return createCXString("ObjCMessageExpr"); 3595 case CXCursor_UnexposedStmt: 3596 return createCXString("UnexposedStmt"); 3597 case CXCursor_DeclStmt: 3598 return createCXString("DeclStmt"); 3599 case CXCursor_LabelStmt: 3600 return createCXString("LabelStmt"); 3601 case CXCursor_CompoundStmt: 3602 return createCXString("CompoundStmt"); 3603 case CXCursor_CaseStmt: 3604 return createCXString("CaseStmt"); 3605 case CXCursor_DefaultStmt: 3606 return createCXString("DefaultStmt"); 3607 case CXCursor_IfStmt: 3608 return createCXString("IfStmt"); 3609 case CXCursor_SwitchStmt: 3610 return createCXString("SwitchStmt"); 3611 case CXCursor_WhileStmt: 3612 return createCXString("WhileStmt"); 3613 case CXCursor_DoStmt: 3614 return createCXString("DoStmt"); 3615 case CXCursor_ForStmt: 3616 return createCXString("ForStmt"); 3617 case CXCursor_GotoStmt: 3618 return createCXString("GotoStmt"); 3619 case CXCursor_IndirectGotoStmt: 3620 return createCXString("IndirectGotoStmt"); 3621 case CXCursor_ContinueStmt: 3622 return createCXString("ContinueStmt"); 3623 case CXCursor_BreakStmt: 3624 return createCXString("BreakStmt"); 3625 case CXCursor_ReturnStmt: 3626 return createCXString("ReturnStmt"); 3627 case CXCursor_GCCAsmStmt: 3628 return createCXString("GCCAsmStmt"); 3629 case CXCursor_MSAsmStmt: 3630 return createCXString("MSAsmStmt"); 3631 case CXCursor_ObjCAtTryStmt: 3632 return createCXString("ObjCAtTryStmt"); 3633 case CXCursor_ObjCAtCatchStmt: 3634 return createCXString("ObjCAtCatchStmt"); 3635 case CXCursor_ObjCAtFinallyStmt: 3636 return createCXString("ObjCAtFinallyStmt"); 3637 case CXCursor_ObjCAtThrowStmt: 3638 return createCXString("ObjCAtThrowStmt"); 3639 case CXCursor_ObjCAtSynchronizedStmt: 3640 return createCXString("ObjCAtSynchronizedStmt"); 3641 case CXCursor_ObjCAutoreleasePoolStmt: 3642 return createCXString("ObjCAutoreleasePoolStmt"); 3643 case CXCursor_ObjCForCollectionStmt: 3644 return createCXString("ObjCForCollectionStmt"); 3645 case CXCursor_CXXCatchStmt: 3646 return createCXString("CXXCatchStmt"); 3647 case CXCursor_CXXTryStmt: 3648 return createCXString("CXXTryStmt"); 3649 case CXCursor_CXXForRangeStmt: 3650 return createCXString("CXXForRangeStmt"); 3651 case CXCursor_SEHTryStmt: 3652 return createCXString("SEHTryStmt"); 3653 case CXCursor_SEHExceptStmt: 3654 return createCXString("SEHExceptStmt"); 3655 case CXCursor_SEHFinallyStmt: 3656 return createCXString("SEHFinallyStmt"); 3657 case CXCursor_NullStmt: 3658 return createCXString("NullStmt"); 3659 case CXCursor_InvalidFile: 3660 return createCXString("InvalidFile"); 3661 case CXCursor_InvalidCode: 3662 return createCXString("InvalidCode"); 3663 case CXCursor_NoDeclFound: 3664 return createCXString("NoDeclFound"); 3665 case CXCursor_NotImplemented: 3666 return createCXString("NotImplemented"); 3667 case CXCursor_TranslationUnit: 3668 return createCXString("TranslationUnit"); 3669 case CXCursor_UnexposedAttr: 3670 return createCXString("UnexposedAttr"); 3671 case CXCursor_IBActionAttr: 3672 return createCXString("attribute(ibaction)"); 3673 case CXCursor_IBOutletAttr: 3674 return createCXString("attribute(iboutlet)"); 3675 case CXCursor_IBOutletCollectionAttr: 3676 return createCXString("attribute(iboutletcollection)"); 3677 case CXCursor_CXXFinalAttr: 3678 return createCXString("attribute(final)"); 3679 case CXCursor_CXXOverrideAttr: 3680 return createCXString("attribute(override)"); 3681 case CXCursor_AnnotateAttr: 3682 return createCXString("attribute(annotate)"); 3683 case CXCursor_AsmLabelAttr: 3684 return createCXString("asm label"); 3685 case CXCursor_PreprocessingDirective: 3686 return createCXString("preprocessing directive"); 3687 case CXCursor_MacroDefinition: 3688 return createCXString("macro definition"); 3689 case CXCursor_MacroExpansion: 3690 return createCXString("macro expansion"); 3691 case CXCursor_InclusionDirective: 3692 return createCXString("inclusion directive"); 3693 case CXCursor_Namespace: 3694 return createCXString("Namespace"); 3695 case CXCursor_LinkageSpec: 3696 return createCXString("LinkageSpec"); 3697 case CXCursor_CXXBaseSpecifier: 3698 return createCXString("C++ base class specifier"); 3699 case CXCursor_Constructor: 3700 return createCXString("CXXConstructor"); 3701 case CXCursor_Destructor: 3702 return createCXString("CXXDestructor"); 3703 case CXCursor_ConversionFunction: 3704 return createCXString("CXXConversion"); 3705 case CXCursor_TemplateTypeParameter: 3706 return createCXString("TemplateTypeParameter"); 3707 case CXCursor_NonTypeTemplateParameter: 3708 return createCXString("NonTypeTemplateParameter"); 3709 case CXCursor_TemplateTemplateParameter: 3710 return createCXString("TemplateTemplateParameter"); 3711 case CXCursor_FunctionTemplate: 3712 return createCXString("FunctionTemplate"); 3713 case CXCursor_ClassTemplate: 3714 return createCXString("ClassTemplate"); 3715 case CXCursor_ClassTemplatePartialSpecialization: 3716 return createCXString("ClassTemplatePartialSpecialization"); 3717 case CXCursor_NamespaceAlias: 3718 return createCXString("NamespaceAlias"); 3719 case CXCursor_UsingDirective: 3720 return createCXString("UsingDirective"); 3721 case CXCursor_UsingDeclaration: 3722 return createCXString("UsingDeclaration"); 3723 case CXCursor_TypeAliasDecl: 3724 return createCXString("TypeAliasDecl"); 3725 case CXCursor_ObjCSynthesizeDecl: 3726 return createCXString("ObjCSynthesizeDecl"); 3727 case CXCursor_ObjCDynamicDecl: 3728 return createCXString("ObjCDynamicDecl"); 3729 case CXCursor_CXXAccessSpecifier: 3730 return createCXString("CXXAccessSpecifier"); 3731 case CXCursor_ModuleImportDecl: 3732 return createCXString("ModuleImport"); 3733 } 3734 3735 llvm_unreachable("Unhandled CXCursorKind"); 3736} 3737 3738struct GetCursorData { 3739 SourceLocation TokenBeginLoc; 3740 bool PointsAtMacroArgExpansion; 3741 bool VisitedObjCPropertyImplDecl; 3742 SourceLocation VisitedDeclaratorDeclStartLoc; 3743 CXCursor &BestCursor; 3744 3745 GetCursorData(SourceManager &SM, 3746 SourceLocation tokenBegin, CXCursor &outputCursor) 3747 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) { 3748 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin); 3749 VisitedObjCPropertyImplDecl = false; 3750 } 3751}; 3752 3753static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, 3754 CXCursor parent, 3755 CXClientData client_data) { 3756 GetCursorData *Data = static_cast<GetCursorData *>(client_data); 3757 CXCursor *BestCursor = &Data->BestCursor; 3758 3759 // If we point inside a macro argument we should provide info of what the 3760 // token is so use the actual cursor, don't replace it with a macro expansion 3761 // cursor. 3762 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion) 3763 return CXChildVisit_Recurse; 3764 3765 if (clang_isDeclaration(cursor.kind)) { 3766 // Avoid having the implicit methods override the property decls. 3767 if (const ObjCMethodDecl *MD 3768 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) { 3769 if (MD->isImplicit()) 3770 return CXChildVisit_Break; 3771 3772 } else if (const ObjCInterfaceDecl *ID 3773 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) { 3774 // Check that when we have multiple @class references in the same line, 3775 // that later ones do not override the previous ones. 3776 // If we have: 3777 // @class Foo, Bar; 3778 // source ranges for both start at '@', so 'Bar' will end up overriding 3779 // 'Foo' even though the cursor location was at 'Foo'. 3780 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl || 3781 BestCursor->kind == CXCursor_ObjCClassRef) 3782 if (const ObjCInterfaceDecl *PrevID 3783 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){ 3784 if (PrevID != ID && 3785 !PrevID->isThisDeclarationADefinition() && 3786 !ID->isThisDeclarationADefinition()) 3787 return CXChildVisit_Break; 3788 } 3789 3790 } else if (const DeclaratorDecl *DD 3791 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) { 3792 SourceLocation StartLoc = DD->getSourceRange().getBegin(); 3793 // Check that when we have multiple declarators in the same line, 3794 // that later ones do not override the previous ones. 3795 // If we have: 3796 // int Foo, Bar; 3797 // source ranges for both start at 'int', so 'Bar' will end up overriding 3798 // 'Foo' even though the cursor location was at 'Foo'. 3799 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc) 3800 return CXChildVisit_Break; 3801 Data->VisitedDeclaratorDeclStartLoc = StartLoc; 3802 3803 } else if (const ObjCPropertyImplDecl *PropImp 3804 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) { 3805 (void)PropImp; 3806 // Check that when we have multiple @synthesize in the same line, 3807 // that later ones do not override the previous ones. 3808 // If we have: 3809 // @synthesize Foo, Bar; 3810 // source ranges for both start at '@', so 'Bar' will end up overriding 3811 // 'Foo' even though the cursor location was at 'Foo'. 3812 if (Data->VisitedObjCPropertyImplDecl) 3813 return CXChildVisit_Break; 3814 Data->VisitedObjCPropertyImplDecl = true; 3815 } 3816 } 3817 3818 if (clang_isExpression(cursor.kind) && 3819 clang_isDeclaration(BestCursor->kind)) { 3820 if (const Decl *D = getCursorDecl(*BestCursor)) { 3821 // Avoid having the cursor of an expression replace the declaration cursor 3822 // when the expression source range overlaps the declaration range. 3823 // This can happen for C++ constructor expressions whose range generally 3824 // include the variable declaration, e.g.: 3825 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor. 3826 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() && 3827 D->getLocation() == Data->TokenBeginLoc) 3828 return CXChildVisit_Break; 3829 } 3830 } 3831 3832 // If our current best cursor is the construction of a temporary object, 3833 // don't replace that cursor with a type reference, because we want 3834 // clang_getCursor() to point at the constructor. 3835 if (clang_isExpression(BestCursor->kind) && 3836 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) && 3837 cursor.kind == CXCursor_TypeRef) { 3838 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it 3839 // as having the actual point on the type reference. 3840 *BestCursor = getTypeRefedCallExprCursor(*BestCursor); 3841 return CXChildVisit_Recurse; 3842 } 3843 3844 *BestCursor = cursor; 3845 return CXChildVisit_Recurse; 3846} 3847 3848CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { 3849 if (!TU) 3850 return clang_getNullCursor(); 3851 3852 ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 3853 ASTUnit::ConcurrencyCheck Check(*CXXUnit); 3854 3855 SourceLocation SLoc = cxloc::translateSourceLocation(Loc); 3856 CXCursor Result = cxcursor::getCursor(TU, SLoc); 3857 3858 LOG_FUNC_SECTION { 3859 CXFile SearchFile; 3860 unsigned SearchLine, SearchColumn; 3861 CXFile ResultFile; 3862 unsigned ResultLine, ResultColumn; 3863 CXString SearchFileName, ResultFileName, KindSpelling, USR; 3864 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : ""; 3865 CXSourceLocation ResultLoc = clang_getCursorLocation(Result); 3866 3867 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0); 3868 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, 3869 &ResultColumn, 0); 3870 SearchFileName = clang_getFileName(SearchFile); 3871 ResultFileName = clang_getFileName(ResultFile); 3872 KindSpelling = clang_getCursorKindSpelling(Result.kind); 3873 USR = clang_getCursorUSR(Result); 3874 *Log << llvm::format("(%s:%d:%d) = %s", 3875 clang_getCString(SearchFileName), SearchLine, SearchColumn, 3876 clang_getCString(KindSpelling)) 3877 << llvm::format("(%s:%d:%d):%s%s", 3878 clang_getCString(ResultFileName), ResultLine, ResultColumn, 3879 clang_getCString(USR), IsDef); 3880 clang_disposeString(SearchFileName); 3881 clang_disposeString(ResultFileName); 3882 clang_disposeString(KindSpelling); 3883 clang_disposeString(USR); 3884 3885 CXCursor Definition = clang_getCursorDefinition(Result); 3886 if (!clang_equalCursors(Definition, clang_getNullCursor())) { 3887 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition); 3888 CXString DefinitionKindSpelling 3889 = clang_getCursorKindSpelling(Definition.kind); 3890 CXFile DefinitionFile; 3891 unsigned DefinitionLine, DefinitionColumn; 3892 clang_getFileLocation(DefinitionLoc, &DefinitionFile, 3893 &DefinitionLine, &DefinitionColumn, 0); 3894 CXString DefinitionFileName = clang_getFileName(DefinitionFile); 3895 *Log << llvm::format(" -> %s(%s:%d:%d)", 3896 clang_getCString(DefinitionKindSpelling), 3897 clang_getCString(DefinitionFileName), 3898 DefinitionLine, DefinitionColumn); 3899 clang_disposeString(DefinitionFileName); 3900 clang_disposeString(DefinitionKindSpelling); 3901 } 3902 } 3903 3904 return Result; 3905} 3906 3907CXCursor clang_getNullCursor(void) { 3908 return MakeCXCursorInvalid(CXCursor_InvalidFile); 3909} 3910 3911unsigned clang_equalCursors(CXCursor X, CXCursor Y) { 3912 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we 3913 // can't set consistently. For example, when visiting a DeclStmt we will set 3914 // it but we don't set it on the result of clang_getCursorDefinition for 3915 // a reference of the same declaration. 3916 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works 3917 // when visiting a DeclStmt currently, the AST should be enhanced to be able 3918 // to provide that kind of info. 3919 if (clang_isDeclaration(X.kind)) 3920 X.data[1] = 0; 3921 if (clang_isDeclaration(Y.kind)) 3922 Y.data[1] = 0; 3923 3924 return X == Y; 3925} 3926 3927unsigned clang_hashCursor(CXCursor C) { 3928 unsigned Index = 0; 3929 if (clang_isExpression(C.kind) || clang_isStatement(C.kind)) 3930 Index = 1; 3931 3932 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue( 3933 std::make_pair(C.kind, C.data[Index])); 3934} 3935 3936unsigned clang_isInvalid(enum CXCursorKind K) { 3937 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid; 3938} 3939 3940unsigned clang_isDeclaration(enum CXCursorKind K) { 3941 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) || 3942 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl); 3943} 3944 3945unsigned clang_isReference(enum CXCursorKind K) { 3946 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef; 3947} 3948 3949unsigned clang_isExpression(enum CXCursorKind K) { 3950 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr; 3951} 3952 3953unsigned clang_isStatement(enum CXCursorKind K) { 3954 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt; 3955} 3956 3957unsigned clang_isAttribute(enum CXCursorKind K) { 3958 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr; 3959} 3960 3961unsigned clang_isTranslationUnit(enum CXCursorKind K) { 3962 return K == CXCursor_TranslationUnit; 3963} 3964 3965unsigned clang_isPreprocessing(enum CXCursorKind K) { 3966 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing; 3967} 3968 3969unsigned clang_isUnexposed(enum CXCursorKind K) { 3970 switch (K) { 3971 case CXCursor_UnexposedDecl: 3972 case CXCursor_UnexposedExpr: 3973 case CXCursor_UnexposedStmt: 3974 case CXCursor_UnexposedAttr: 3975 return true; 3976 default: 3977 return false; 3978 } 3979} 3980 3981CXCursorKind clang_getCursorKind(CXCursor C) { 3982 return C.kind; 3983} 3984 3985CXSourceLocation clang_getCursorLocation(CXCursor C) { 3986 if (clang_isReference(C.kind)) { 3987 switch (C.kind) { 3988 case CXCursor_ObjCSuperClassRef: { 3989 std::pair<const ObjCInterfaceDecl *, SourceLocation> P 3990 = getCursorObjCSuperClassRef(C); 3991 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 3992 } 3993 3994 case CXCursor_ObjCProtocolRef: { 3995 std::pair<const ObjCProtocolDecl *, SourceLocation> P 3996 = getCursorObjCProtocolRef(C); 3997 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 3998 } 3999 4000 case CXCursor_ObjCClassRef: { 4001 std::pair<const ObjCInterfaceDecl *, SourceLocation> P 4002 = getCursorObjCClassRef(C); 4003 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 4004 } 4005 4006 case CXCursor_TypeRef: { 4007 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C); 4008 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 4009 } 4010 4011 case CXCursor_TemplateRef: { 4012 std::pair<const TemplateDecl *, SourceLocation> P = 4013 getCursorTemplateRef(C); 4014 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 4015 } 4016 4017 case CXCursor_NamespaceRef: { 4018 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C); 4019 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 4020 } 4021 4022 case CXCursor_MemberRef: { 4023 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C); 4024 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 4025 } 4026 4027 case CXCursor_VariableRef: { 4028 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C); 4029 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); 4030 } 4031 4032 case CXCursor_CXXBaseSpecifier: { 4033 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C); 4034 if (!BaseSpec) 4035 return clang_getNullLocation(); 4036 4037 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo()) 4038 return cxloc::translateSourceLocation(getCursorContext(C), 4039 TSInfo->getTypeLoc().getBeginLoc()); 4040 4041 return cxloc::translateSourceLocation(getCursorContext(C), 4042 BaseSpec->getLocStart()); 4043 } 4044 4045 case CXCursor_LabelRef: { 4046 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C); 4047 return cxloc::translateSourceLocation(getCursorContext(C), P.second); 4048 } 4049 4050 case CXCursor_OverloadedDeclRef: 4051 return cxloc::translateSourceLocation(getCursorContext(C), 4052 getCursorOverloadedDeclRef(C).second); 4053 4054 default: 4055 // FIXME: Need a way to enumerate all non-reference cases. 4056 llvm_unreachable("Missed a reference kind"); 4057 } 4058 } 4059 4060 if (clang_isExpression(C.kind)) 4061 return cxloc::translateSourceLocation(getCursorContext(C), 4062 getLocationFromExpr(getCursorExpr(C))); 4063 4064 if (clang_isStatement(C.kind)) 4065 return cxloc::translateSourceLocation(getCursorContext(C), 4066 getCursorStmt(C)->getLocStart()); 4067 4068 if (C.kind == CXCursor_PreprocessingDirective) { 4069 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin(); 4070 return cxloc::translateSourceLocation(getCursorContext(C), L); 4071 } 4072 4073 if (C.kind == CXCursor_MacroExpansion) { 4074 SourceLocation L 4075 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin(); 4076 return cxloc::translateSourceLocation(getCursorContext(C), L); 4077 } 4078 4079 if (C.kind == CXCursor_MacroDefinition) { 4080 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation(); 4081 return cxloc::translateSourceLocation(getCursorContext(C), L); 4082 } 4083 4084 if (C.kind == CXCursor_InclusionDirective) { 4085 SourceLocation L 4086 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin(); 4087 return cxloc::translateSourceLocation(getCursorContext(C), L); 4088 } 4089 4090 if (!clang_isDeclaration(C.kind)) 4091 return clang_getNullLocation(); 4092 4093 const Decl *D = getCursorDecl(C); 4094 if (!D) 4095 return clang_getNullLocation(); 4096 4097 SourceLocation Loc = D->getLocation(); 4098 // FIXME: Multiple variables declared in a single declaration 4099 // currently lack the information needed to correctly determine their 4100 // ranges when accounting for the type-specifier. We use context 4101 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, 4102 // and if so, whether it is the first decl. 4103 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 4104 if (!cxcursor::isFirstInDeclGroup(C)) 4105 Loc = VD->getLocation(); 4106 } 4107 4108 // For ObjC methods, give the start location of the method name. 4109 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 4110 Loc = MD->getSelectorStartLoc(); 4111 4112 return cxloc::translateSourceLocation(getCursorContext(C), Loc); 4113} 4114 4115} // end extern "C" 4116 4117CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) { 4118 assert(TU); 4119 4120 // Guard against an invalid SourceLocation, or we may assert in one 4121 // of the following calls. 4122 if (SLoc.isInvalid()) 4123 return clang_getNullCursor(); 4124 4125 ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 4126 4127 // Translate the given source location to make it point at the beginning of 4128 // the token under the cursor. 4129 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(), 4130 CXXUnit->getASTContext().getLangOpts()); 4131 4132 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound); 4133 if (SLoc.isValid()) { 4134 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result); 4135 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData, 4136 /*VisitPreprocessorLast=*/true, 4137 /*VisitIncludedEntities=*/false, 4138 SourceLocation(SLoc)); 4139 CursorVis.visitFileRegion(); 4140 } 4141 4142 return Result; 4143} 4144 4145static SourceRange getRawCursorExtent(CXCursor C) { 4146 if (clang_isReference(C.kind)) { 4147 switch (C.kind) { 4148 case CXCursor_ObjCSuperClassRef: 4149 return getCursorObjCSuperClassRef(C).second; 4150 4151 case CXCursor_ObjCProtocolRef: 4152 return getCursorObjCProtocolRef(C).second; 4153 4154 case CXCursor_ObjCClassRef: 4155 return getCursorObjCClassRef(C).second; 4156 4157 case CXCursor_TypeRef: 4158 return getCursorTypeRef(C).second; 4159 4160 case CXCursor_TemplateRef: 4161 return getCursorTemplateRef(C).second; 4162 4163 case CXCursor_NamespaceRef: 4164 return getCursorNamespaceRef(C).second; 4165 4166 case CXCursor_MemberRef: 4167 return getCursorMemberRef(C).second; 4168 4169 case CXCursor_CXXBaseSpecifier: 4170 return getCursorCXXBaseSpecifier(C)->getSourceRange(); 4171 4172 case CXCursor_LabelRef: 4173 return getCursorLabelRef(C).second; 4174 4175 case CXCursor_OverloadedDeclRef: 4176 return getCursorOverloadedDeclRef(C).second; 4177 4178 case CXCursor_VariableRef: 4179 return getCursorVariableRef(C).second; 4180 4181 default: 4182 // FIXME: Need a way to enumerate all non-reference cases. 4183 llvm_unreachable("Missed a reference kind"); 4184 } 4185 } 4186 4187 if (clang_isExpression(C.kind)) 4188 return getCursorExpr(C)->getSourceRange(); 4189 4190 if (clang_isStatement(C.kind)) 4191 return getCursorStmt(C)->getSourceRange(); 4192 4193 if (clang_isAttribute(C.kind)) 4194 return getCursorAttr(C)->getRange(); 4195 4196 if (C.kind == CXCursor_PreprocessingDirective) 4197 return cxcursor::getCursorPreprocessingDirective(C); 4198 4199 if (C.kind == CXCursor_MacroExpansion) { 4200 ASTUnit *TU = getCursorASTUnit(C); 4201 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange(); 4202 return TU->mapRangeFromPreamble(Range); 4203 } 4204 4205 if (C.kind == CXCursor_MacroDefinition) { 4206 ASTUnit *TU = getCursorASTUnit(C); 4207 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange(); 4208 return TU->mapRangeFromPreamble(Range); 4209 } 4210 4211 if (C.kind == CXCursor_InclusionDirective) { 4212 ASTUnit *TU = getCursorASTUnit(C); 4213 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange(); 4214 return TU->mapRangeFromPreamble(Range); 4215 } 4216 4217 if (C.kind == CXCursor_TranslationUnit) { 4218 ASTUnit *TU = getCursorASTUnit(C); 4219 FileID MainID = TU->getSourceManager().getMainFileID(); 4220 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID); 4221 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID); 4222 return SourceRange(Start, End); 4223 } 4224 4225 if (clang_isDeclaration(C.kind)) { 4226 const Decl *D = cxcursor::getCursorDecl(C); 4227 if (!D) 4228 return SourceRange(); 4229 4230 SourceRange R = D->getSourceRange(); 4231 // FIXME: Multiple variables declared in a single declaration 4232 // currently lack the information needed to correctly determine their 4233 // ranges when accounting for the type-specifier. We use context 4234 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, 4235 // and if so, whether it is the first decl. 4236 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 4237 if (!cxcursor::isFirstInDeclGroup(C)) 4238 R.setBegin(VD->getLocation()); 4239 } 4240 return R; 4241 } 4242 return SourceRange(); 4243} 4244 4245/// \brief Retrieves the "raw" cursor extent, which is then extended to include 4246/// the decl-specifier-seq for declarations. 4247static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) { 4248 if (clang_isDeclaration(C.kind)) { 4249 const Decl *D = cxcursor::getCursorDecl(C); 4250 if (!D) 4251 return SourceRange(); 4252 4253 SourceRange R = D->getSourceRange(); 4254 4255 // Adjust the start of the location for declarations preceded by 4256 // declaration specifiers. 4257 SourceLocation StartLoc; 4258 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { 4259 if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) 4260 StartLoc = TI->getTypeLoc().getLocStart(); 4261 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) { 4262 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo()) 4263 StartLoc = TI->getTypeLoc().getLocStart(); 4264 } 4265 4266 if (StartLoc.isValid() && R.getBegin().isValid() && 4267 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin())) 4268 R.setBegin(StartLoc); 4269 4270 // FIXME: Multiple variables declared in a single declaration 4271 // currently lack the information needed to correctly determine their 4272 // ranges when accounting for the type-specifier. We use context 4273 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, 4274 // and if so, whether it is the first decl. 4275 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 4276 if (!cxcursor::isFirstInDeclGroup(C)) 4277 R.setBegin(VD->getLocation()); 4278 } 4279 4280 return R; 4281 } 4282 4283 return getRawCursorExtent(C); 4284} 4285 4286extern "C" { 4287 4288CXSourceRange clang_getCursorExtent(CXCursor C) { 4289 SourceRange R = getRawCursorExtent(C); 4290 if (R.isInvalid()) 4291 return clang_getNullRange(); 4292 4293 return cxloc::translateSourceRange(getCursorContext(C), R); 4294} 4295 4296CXCursor clang_getCursorReferenced(CXCursor C) { 4297 if (clang_isInvalid(C.kind)) 4298 return clang_getNullCursor(); 4299 4300 CXTranslationUnit tu = getCursorTU(C); 4301 if (clang_isDeclaration(C.kind)) { 4302 const Decl *D = getCursorDecl(C); 4303 if (!D) 4304 return clang_getNullCursor(); 4305 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) 4306 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu); 4307 if (const ObjCPropertyImplDecl *PropImpl = 4308 dyn_cast<ObjCPropertyImplDecl>(D)) 4309 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl()) 4310 return MakeCXCursor(Property, tu); 4311 4312 return C; 4313 } 4314 4315 if (clang_isExpression(C.kind)) { 4316 const Expr *E = getCursorExpr(C); 4317 const Decl *D = getDeclFromExpr(E); 4318 if (D) { 4319 CXCursor declCursor = MakeCXCursor(D, tu); 4320 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C), 4321 declCursor); 4322 return declCursor; 4323 } 4324 4325 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E)) 4326 return MakeCursorOverloadedDeclRef(Ovl, tu); 4327 4328 return clang_getNullCursor(); 4329 } 4330 4331 if (clang_isStatement(C.kind)) { 4332 const Stmt *S = getCursorStmt(C); 4333 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S)) 4334 if (LabelDecl *label = Goto->getLabel()) 4335 if (LabelStmt *labelS = label->getStmt()) 4336 return MakeCXCursor(labelS, getCursorDecl(C), tu); 4337 4338 return clang_getNullCursor(); 4339 } 4340 4341 if (C.kind == CXCursor_MacroExpansion) { 4342 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition()) 4343 return MakeMacroDefinitionCursor(Def, tu); 4344 } 4345 4346 if (!clang_isReference(C.kind)) 4347 return clang_getNullCursor(); 4348 4349 switch (C.kind) { 4350 case CXCursor_ObjCSuperClassRef: 4351 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu); 4352 4353 case CXCursor_ObjCProtocolRef: { 4354 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first; 4355 if (const ObjCProtocolDecl *Def = Prot->getDefinition()) 4356 return MakeCXCursor(Def, tu); 4357 4358 return MakeCXCursor(Prot, tu); 4359 } 4360 4361 case CXCursor_ObjCClassRef: { 4362 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; 4363 if (const ObjCInterfaceDecl *Def = Class->getDefinition()) 4364 return MakeCXCursor(Def, tu); 4365 4366 return MakeCXCursor(Class, tu); 4367 } 4368 4369 case CXCursor_TypeRef: 4370 return MakeCXCursor(getCursorTypeRef(C).first, tu ); 4371 4372 case CXCursor_TemplateRef: 4373 return MakeCXCursor(getCursorTemplateRef(C).first, tu ); 4374 4375 case CXCursor_NamespaceRef: 4376 return MakeCXCursor(getCursorNamespaceRef(C).first, tu ); 4377 4378 case CXCursor_MemberRef: 4379 return MakeCXCursor(getCursorMemberRef(C).first, tu ); 4380 4381 case CXCursor_CXXBaseSpecifier: { 4382 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); 4383 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), 4384 tu )); 4385 } 4386 4387 case CXCursor_LabelRef: 4388 // FIXME: We end up faking the "parent" declaration here because we 4389 // don't want to make CXCursor larger. 4390 return MakeCXCursor(getCursorLabelRef(C).first, 4391 cxtu::getASTUnit(tu)->getASTContext() 4392 .getTranslationUnitDecl(), 4393 tu); 4394 4395 case CXCursor_OverloadedDeclRef: 4396 return C; 4397 4398 case CXCursor_VariableRef: 4399 return MakeCXCursor(getCursorVariableRef(C).first, tu); 4400 4401 default: 4402 // We would prefer to enumerate all non-reference cursor kinds here. 4403 llvm_unreachable("Unhandled reference cursor kind"); 4404 } 4405} 4406 4407CXCursor clang_getCursorDefinition(CXCursor C) { 4408 if (clang_isInvalid(C.kind)) 4409 return clang_getNullCursor(); 4410 4411 CXTranslationUnit TU = getCursorTU(C); 4412 4413 bool WasReference = false; 4414 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) { 4415 C = clang_getCursorReferenced(C); 4416 WasReference = true; 4417 } 4418 4419 if (C.kind == CXCursor_MacroExpansion) 4420 return clang_getCursorReferenced(C); 4421 4422 if (!clang_isDeclaration(C.kind)) 4423 return clang_getNullCursor(); 4424 4425 const Decl *D = getCursorDecl(C); 4426 if (!D) 4427 return clang_getNullCursor(); 4428 4429 switch (D->getKind()) { 4430 // Declaration kinds that don't really separate the notions of 4431 // declaration and definition. 4432 case Decl::Namespace: 4433 case Decl::Typedef: 4434 case Decl::TypeAlias: 4435 case Decl::TypeAliasTemplate: 4436 case Decl::TemplateTypeParm: 4437 case Decl::EnumConstant: 4438 case Decl::Field: 4439 case Decl::IndirectField: 4440 case Decl::ObjCIvar: 4441 case Decl::ObjCAtDefsField: 4442 case Decl::ImplicitParam: 4443 case Decl::ParmVar: 4444 case Decl::NonTypeTemplateParm: 4445 case Decl::TemplateTemplateParm: 4446 case Decl::ObjCCategoryImpl: 4447 case Decl::ObjCImplementation: 4448 case Decl::AccessSpec: 4449 case Decl::LinkageSpec: 4450 case Decl::ObjCPropertyImpl: 4451 case Decl::FileScopeAsm: 4452 case Decl::StaticAssert: 4453 case Decl::Block: 4454 case Decl::Label: // FIXME: Is this right?? 4455 case Decl::ClassScopeFunctionSpecialization: 4456 case Decl::Import: 4457 return C; 4458 4459 // Declaration kinds that don't make any sense here, but are 4460 // nonetheless harmless. 4461 case Decl::TranslationUnit: 4462 break; 4463 4464 // Declaration kinds for which the definition is not resolvable. 4465 case Decl::UnresolvedUsingTypename: 4466 case Decl::UnresolvedUsingValue: 4467 break; 4468 4469 case Decl::UsingDirective: 4470 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(), 4471 TU); 4472 4473 case Decl::NamespaceAlias: 4474 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU); 4475 4476 case Decl::Enum: 4477 case Decl::Record: 4478 case Decl::CXXRecord: 4479 case Decl::ClassTemplateSpecialization: 4480 case Decl::ClassTemplatePartialSpecialization: 4481 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition()) 4482 return MakeCXCursor(Def, TU); 4483 return clang_getNullCursor(); 4484 4485 case Decl::Function: 4486 case Decl::CXXMethod: 4487 case Decl::CXXConstructor: 4488 case Decl::CXXDestructor: 4489 case Decl::CXXConversion: { 4490 const FunctionDecl *Def = 0; 4491 if (cast<FunctionDecl>(D)->getBody(Def)) 4492 return MakeCXCursor(Def, TU); 4493 return clang_getNullCursor(); 4494 } 4495 4496 case Decl::Var: { 4497 // Ask the variable if it has a definition. 4498 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition()) 4499 return MakeCXCursor(Def, TU); 4500 return clang_getNullCursor(); 4501 } 4502 4503 case Decl::FunctionTemplate: { 4504 const FunctionDecl *Def = 0; 4505 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def)) 4506 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU); 4507 return clang_getNullCursor(); 4508 } 4509 4510 case Decl::ClassTemplate: { 4511 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl() 4512 ->getDefinition()) 4513 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(), 4514 TU); 4515 return clang_getNullCursor(); 4516 } 4517 4518 case Decl::Using: 4519 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), 4520 D->getLocation(), TU); 4521 4522 case Decl::UsingShadow: 4523 return clang_getCursorDefinition( 4524 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), 4525 TU)); 4526 4527 case Decl::ObjCMethod: { 4528 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D); 4529 if (Method->isThisDeclarationADefinition()) 4530 return C; 4531 4532 // Dig out the method definition in the associated 4533 // @implementation, if we have it. 4534 // FIXME: The ASTs should make finding the definition easier. 4535 if (const ObjCInterfaceDecl *Class 4536 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) 4537 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation()) 4538 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(), 4539 Method->isInstanceMethod())) 4540 if (Def->isThisDeclarationADefinition()) 4541 return MakeCXCursor(Def, TU); 4542 4543 return clang_getNullCursor(); 4544 } 4545 4546 case Decl::ObjCCategory: 4547 if (ObjCCategoryImplDecl *Impl 4548 = cast<ObjCCategoryDecl>(D)->getImplementation()) 4549 return MakeCXCursor(Impl, TU); 4550 return clang_getNullCursor(); 4551 4552 case Decl::ObjCProtocol: 4553 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition()) 4554 return MakeCXCursor(Def, TU); 4555 return clang_getNullCursor(); 4556 4557 case Decl::ObjCInterface: { 4558 // There are two notions of a "definition" for an Objective-C 4559 // class: the interface and its implementation. When we resolved a 4560 // reference to an Objective-C class, produce the @interface as 4561 // the definition; when we were provided with the interface, 4562 // produce the @implementation as the definition. 4563 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D); 4564 if (WasReference) { 4565 if (const ObjCInterfaceDecl *Def = IFace->getDefinition()) 4566 return MakeCXCursor(Def, TU); 4567 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation()) 4568 return MakeCXCursor(Impl, TU); 4569 return clang_getNullCursor(); 4570 } 4571 4572 case Decl::ObjCProperty: 4573 // FIXME: We don't really know where to find the 4574 // ObjCPropertyImplDecls that implement this property. 4575 return clang_getNullCursor(); 4576 4577 case Decl::ObjCCompatibleAlias: 4578 if (const ObjCInterfaceDecl *Class 4579 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface()) 4580 if (const ObjCInterfaceDecl *Def = Class->getDefinition()) 4581 return MakeCXCursor(Def, TU); 4582 4583 return clang_getNullCursor(); 4584 4585 case Decl::Friend: 4586 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl()) 4587 return clang_getCursorDefinition(MakeCXCursor(Friend, TU)); 4588 return clang_getNullCursor(); 4589 4590 case Decl::FriendTemplate: 4591 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl()) 4592 return clang_getCursorDefinition(MakeCXCursor(Friend, TU)); 4593 return clang_getNullCursor(); 4594 } 4595 4596 return clang_getNullCursor(); 4597} 4598 4599unsigned clang_isCursorDefinition(CXCursor C) { 4600 if (!clang_isDeclaration(C.kind)) 4601 return 0; 4602 4603 return clang_getCursorDefinition(C) == C; 4604} 4605 4606CXCursor clang_getCanonicalCursor(CXCursor C) { 4607 if (!clang_isDeclaration(C.kind)) 4608 return C; 4609 4610 if (const Decl *D = getCursorDecl(C)) { 4611 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) 4612 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl()) 4613 return MakeCXCursor(CatD, getCursorTU(C)); 4614 4615 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D)) 4616 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) 4617 return MakeCXCursor(IFD, getCursorTU(C)); 4618 4619 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C)); 4620 } 4621 4622 return C; 4623} 4624 4625int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) { 4626 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first; 4627} 4628 4629unsigned clang_getNumOverloadedDecls(CXCursor C) { 4630 if (C.kind != CXCursor_OverloadedDeclRef) 4631 return 0; 4632 4633 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first; 4634 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>()) 4635 return E->getNumDecls(); 4636 4637 if (OverloadedTemplateStorage *S 4638 = Storage.dyn_cast<OverloadedTemplateStorage*>()) 4639 return S->size(); 4640 4641 const Decl *D = Storage.get<const Decl *>(); 4642 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) 4643 return Using->shadow_size(); 4644 4645 return 0; 4646} 4647 4648CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) { 4649 if (cursor.kind != CXCursor_OverloadedDeclRef) 4650 return clang_getNullCursor(); 4651 4652 if (index >= clang_getNumOverloadedDecls(cursor)) 4653 return clang_getNullCursor(); 4654 4655 CXTranslationUnit TU = getCursorTU(cursor); 4656 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first; 4657 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>()) 4658 return MakeCXCursor(E->decls_begin()[index], TU); 4659 4660 if (OverloadedTemplateStorage *S 4661 = Storage.dyn_cast<OverloadedTemplateStorage*>()) 4662 return MakeCXCursor(S->begin()[index], TU); 4663 4664 const Decl *D = Storage.get<const Decl *>(); 4665 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) { 4666 // FIXME: This is, unfortunately, linear time. 4667 UsingDecl::shadow_iterator Pos = Using->shadow_begin(); 4668 std::advance(Pos, index); 4669 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU); 4670 } 4671 4672 return clang_getNullCursor(); 4673} 4674 4675void clang_getDefinitionSpellingAndExtent(CXCursor C, 4676 const char **startBuf, 4677 const char **endBuf, 4678 unsigned *startLine, 4679 unsigned *startColumn, 4680 unsigned *endLine, 4681 unsigned *endColumn) { 4682 assert(getCursorDecl(C) && "CXCursor has null decl"); 4683 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C)); 4684 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody()); 4685 4686 SourceManager &SM = FD->getASTContext().getSourceManager(); 4687 *startBuf = SM.getCharacterData(Body->getLBracLoc()); 4688 *endBuf = SM.getCharacterData(Body->getRBracLoc()); 4689 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc()); 4690 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc()); 4691 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc()); 4692 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc()); 4693} 4694 4695 4696CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags, 4697 unsigned PieceIndex) { 4698 RefNamePieces Pieces; 4699 4700 switch (C.kind) { 4701 case CXCursor_MemberRefExpr: 4702 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C))) 4703 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(), 4704 E->getQualifierLoc().getSourceRange()); 4705 break; 4706 4707 case CXCursor_DeclRefExpr: 4708 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) 4709 Pieces = buildPieces(NameFlags, false, E->getNameInfo(), 4710 E->getQualifierLoc().getSourceRange(), 4711 E->getOptionalExplicitTemplateArgs()); 4712 break; 4713 4714 case CXCursor_CallExpr: 4715 if (const CXXOperatorCallExpr *OCE = 4716 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) { 4717 const Expr *Callee = OCE->getCallee(); 4718 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) 4719 Callee = ICE->getSubExpr(); 4720 4721 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee)) 4722 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(), 4723 DRE->getQualifierLoc().getSourceRange()); 4724 } 4725 break; 4726 4727 default: 4728 break; 4729 } 4730 4731 if (Pieces.empty()) { 4732 if (PieceIndex == 0) 4733 return clang_getCursorExtent(C); 4734 } else if (PieceIndex < Pieces.size()) { 4735 SourceRange R = Pieces[PieceIndex]; 4736 if (R.isValid()) 4737 return cxloc::translateSourceRange(getCursorContext(C), R); 4738 } 4739 4740 return clang_getNullRange(); 4741} 4742 4743void clang_enableStackTraces(void) { 4744 llvm::sys::PrintStackTraceOnErrorSignal(); 4745} 4746 4747void clang_executeOnThread(void (*fn)(void*), void *user_data, 4748 unsigned stack_size) { 4749 llvm::llvm_execute_on_thread(fn, user_data, stack_size); 4750} 4751 4752} // end: extern "C" 4753 4754//===----------------------------------------------------------------------===// 4755// Token-based Operations. 4756//===----------------------------------------------------------------------===// 4757 4758/* CXToken layout: 4759 * int_data[0]: a CXTokenKind 4760 * int_data[1]: starting token location 4761 * int_data[2]: token length 4762 * int_data[3]: reserved 4763 * ptr_data: for identifiers and keywords, an IdentifierInfo*. 4764 * otherwise unused. 4765 */ 4766extern "C" { 4767 4768CXTokenKind clang_getTokenKind(CXToken CXTok) { 4769 return static_cast<CXTokenKind>(CXTok.int_data[0]); 4770} 4771 4772CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) { 4773 switch (clang_getTokenKind(CXTok)) { 4774 case CXToken_Identifier: 4775 case CXToken_Keyword: 4776 // We know we have an IdentifierInfo*, so use that. 4777 return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data) 4778 ->getNameStart()); 4779 4780 case CXToken_Literal: { 4781 // We have stashed the starting pointer in the ptr_data field. Use it. 4782 const char *Text = static_cast<const char *>(CXTok.ptr_data); 4783 return createCXString(StringRef(Text, CXTok.int_data[2])); 4784 } 4785 4786 case CXToken_Punctuation: 4787 case CXToken_Comment: 4788 break; 4789 } 4790 4791 // We have to find the starting buffer pointer the hard way, by 4792 // deconstructing the source location. 4793 ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 4794 if (!CXXUnit) 4795 return createCXString(""); 4796 4797 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]); 4798 std::pair<FileID, unsigned> LocInfo 4799 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc); 4800 bool Invalid = false; 4801 StringRef Buffer 4802 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); 4803 if (Invalid) 4804 return createCXString(""); 4805 4806 return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2])); 4807} 4808 4809CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) { 4810 ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 4811 if (!CXXUnit) 4812 return clang_getNullLocation(); 4813 4814 return cxloc::translateSourceLocation(CXXUnit->getASTContext(), 4815 SourceLocation::getFromRawEncoding(CXTok.int_data[1])); 4816} 4817 4818CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) { 4819 ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 4820 if (!CXXUnit) 4821 return clang_getNullRange(); 4822 4823 return cxloc::translateSourceRange(CXXUnit->getASTContext(), 4824 SourceLocation::getFromRawEncoding(CXTok.int_data[1])); 4825} 4826 4827static void getTokens(ASTUnit *CXXUnit, SourceRange Range, 4828 SmallVectorImpl<CXToken> &CXTokens) { 4829 SourceManager &SourceMgr = CXXUnit->getSourceManager(); 4830 std::pair<FileID, unsigned> BeginLocInfo 4831 = SourceMgr.getDecomposedLoc(Range.getBegin()); 4832 std::pair<FileID, unsigned> EndLocInfo 4833 = SourceMgr.getDecomposedLoc(Range.getEnd()); 4834 4835 // Cannot tokenize across files. 4836 if (BeginLocInfo.first != EndLocInfo.first) 4837 return; 4838 4839 // Create a lexer 4840 bool Invalid = false; 4841 StringRef Buffer 4842 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid); 4843 if (Invalid) 4844 return; 4845 4846 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), 4847 CXXUnit->getASTContext().getLangOpts(), 4848 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end()); 4849 Lex.SetCommentRetentionState(true); 4850 4851 // Lex tokens until we hit the end of the range. 4852 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second; 4853 Token Tok; 4854 bool previousWasAt = false; 4855 do { 4856 // Lex the next token 4857 Lex.LexFromRawLexer(Tok); 4858 if (Tok.is(tok::eof)) 4859 break; 4860 4861 // Initialize the CXToken. 4862 CXToken CXTok; 4863 4864 // - Common fields 4865 CXTok.int_data[1] = Tok.getLocation().getRawEncoding(); 4866 CXTok.int_data[2] = Tok.getLength(); 4867 CXTok.int_data[3] = 0; 4868 4869 // - Kind-specific fields 4870 if (Tok.isLiteral()) { 4871 CXTok.int_data[0] = CXToken_Literal; 4872 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData()); 4873 } else if (Tok.is(tok::raw_identifier)) { 4874 // Lookup the identifier to determine whether we have a keyword. 4875 IdentifierInfo *II 4876 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok); 4877 4878 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) { 4879 CXTok.int_data[0] = CXToken_Keyword; 4880 } 4881 else { 4882 CXTok.int_data[0] = Tok.is(tok::identifier) 4883 ? CXToken_Identifier 4884 : CXToken_Keyword; 4885 } 4886 CXTok.ptr_data = II; 4887 } else if (Tok.is(tok::comment)) { 4888 CXTok.int_data[0] = CXToken_Comment; 4889 CXTok.ptr_data = 0; 4890 } else { 4891 CXTok.int_data[0] = CXToken_Punctuation; 4892 CXTok.ptr_data = 0; 4893 } 4894 CXTokens.push_back(CXTok); 4895 previousWasAt = Tok.is(tok::at); 4896 } while (Lex.getBufferLocation() <= EffectiveBufferEnd); 4897} 4898 4899void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, 4900 CXToken **Tokens, unsigned *NumTokens) { 4901 LOG_FUNC_SECTION { 4902 *Log << TU << ' ' << Range; 4903 } 4904 4905 if (Tokens) 4906 *Tokens = 0; 4907 if (NumTokens) 4908 *NumTokens = 0; 4909 4910 ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 4911 if (!CXXUnit || !Tokens || !NumTokens) 4912 return; 4913 4914 ASTUnit::ConcurrencyCheck Check(*CXXUnit); 4915 4916 SourceRange R = cxloc::translateCXSourceRange(Range); 4917 if (R.isInvalid()) 4918 return; 4919 4920 SmallVector<CXToken, 32> CXTokens; 4921 getTokens(CXXUnit, R, CXTokens); 4922 4923 if (CXTokens.empty()) 4924 return; 4925 4926 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size()); 4927 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); 4928 *NumTokens = CXTokens.size(); 4929} 4930 4931void clang_disposeTokens(CXTranslationUnit TU, 4932 CXToken *Tokens, unsigned NumTokens) { 4933 free(Tokens); 4934} 4935 4936} // end: extern "C" 4937 4938//===----------------------------------------------------------------------===// 4939// Token annotation APIs. 4940//===----------------------------------------------------------------------===// 4941 4942static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, 4943 CXCursor parent, 4944 CXClientData client_data); 4945static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor, 4946 CXClientData client_data); 4947 4948namespace { 4949class AnnotateTokensWorker { 4950 CXToken *Tokens; 4951 CXCursor *Cursors; 4952 unsigned NumTokens; 4953 unsigned TokIdx; 4954 unsigned PreprocessingTokIdx; 4955 CursorVisitor AnnotateVis; 4956 SourceManager &SrcMgr; 4957 bool HasContextSensitiveKeywords; 4958 4959 struct PostChildrenInfo { 4960 CXCursor Cursor; 4961 SourceRange CursorRange; 4962 unsigned BeforeChildrenTokenIdx; 4963 }; 4964 SmallVector<PostChildrenInfo, 8> PostChildrenInfos; 4965 4966 bool MoreTokens() const { return TokIdx < NumTokens; } 4967 unsigned NextToken() const { return TokIdx; } 4968 void AdvanceToken() { ++TokIdx; } 4969 SourceLocation GetTokenLoc(unsigned tokI) { 4970 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]); 4971 } 4972 bool isFunctionMacroToken(unsigned tokI) const { 4973 return Tokens[tokI].int_data[3] != 0; 4974 } 4975 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const { 4976 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]); 4977 } 4978 4979 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange); 4980 void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult, 4981 SourceRange); 4982 4983public: 4984 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens, 4985 CXTranslationUnit TU, SourceRange RegionOfInterest) 4986 : Tokens(tokens), Cursors(cursors), 4987 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0), 4988 AnnotateVis(TU, 4989 AnnotateTokensVisitor, this, 4990 /*VisitPreprocessorLast=*/true, 4991 /*VisitIncludedEntities=*/false, 4992 RegionOfInterest, 4993 /*VisitDeclsOnly=*/false, 4994 AnnotateTokensPostChildrenVisitor), 4995 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()), 4996 HasContextSensitiveKeywords(false) { } 4997 4998 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); } 4999 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent); 5000 bool postVisitChildren(CXCursor cursor); 5001 void AnnotateTokens(); 5002 5003 /// \brief Determine whether the annotator saw any cursors that have 5004 /// context-sensitive keywords. 5005 bool hasContextSensitiveKeywords() const { 5006 return HasContextSensitiveKeywords; 5007 } 5008 5009 ~AnnotateTokensWorker() { 5010 assert(PostChildrenInfos.empty()); 5011 } 5012}; 5013} 5014 5015void AnnotateTokensWorker::AnnotateTokens() { 5016 // Walk the AST within the region of interest, annotating tokens 5017 // along the way. 5018 AnnotateVis.visitFileRegion(); 5019} 5020 5021static inline void updateCursorAnnotation(CXCursor &Cursor, 5022 const CXCursor &updateC) { 5023 if (clang_isInvalid(updateC.kind) || clang_isPreprocessing(Cursor.kind)) 5024 return; 5025 Cursor = updateC; 5026} 5027 5028/// \brief It annotates and advances tokens with a cursor until the comparison 5029//// between the cursor location and the source range is the same as 5030/// \arg compResult. 5031/// 5032/// Pass RangeBefore to annotate tokens with a cursor until a range is reached. 5033/// Pass RangeOverlap to annotate tokens inside a range. 5034void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC, 5035 RangeComparisonResult compResult, 5036 SourceRange range) { 5037 while (MoreTokens()) { 5038 const unsigned I = NextToken(); 5039 if (isFunctionMacroToken(I)) 5040 return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range); 5041 5042 SourceLocation TokLoc = GetTokenLoc(I); 5043 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) { 5044 updateCursorAnnotation(Cursors[I], updateC); 5045 AdvanceToken(); 5046 continue; 5047 } 5048 break; 5049 } 5050} 5051 5052/// \brief Special annotation handling for macro argument tokens. 5053void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens( 5054 CXCursor updateC, 5055 RangeComparisonResult compResult, 5056 SourceRange range) { 5057 assert(MoreTokens()); 5058 assert(isFunctionMacroToken(NextToken()) && 5059 "Should be called only for macro arg tokens"); 5060 5061 // This works differently than annotateAndAdvanceTokens; because expanded 5062 // macro arguments can have arbitrary translation-unit source order, we do not 5063 // advance the token index one by one until a token fails the range test. 5064 // We only advance once past all of the macro arg tokens if all of them 5065 // pass the range test. If one of them fails we keep the token index pointing 5066 // at the start of the macro arg tokens so that the failing token will be 5067 // annotated by a subsequent annotation try. 5068 5069 bool atLeastOneCompFail = false; 5070 5071 unsigned I = NextToken(); 5072 for (; I < NumTokens && isFunctionMacroToken(I); ++I) { 5073 SourceLocation TokLoc = getFunctionMacroTokenLoc(I); 5074 if (TokLoc.isFileID()) 5075 continue; // not macro arg token, it's parens or comma. 5076 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) { 5077 if (clang_isInvalid(clang_getCursorKind(Cursors[I]))) 5078 Cursors[I] = updateC; 5079 } else 5080 atLeastOneCompFail = true; 5081 } 5082 5083 if (!atLeastOneCompFail) 5084 TokIdx = I; // All of the tokens were handled, advance beyond all of them. 5085} 5086 5087enum CXChildVisitResult 5088AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { 5089 SourceRange cursorRange = getRawCursorExtent(cursor); 5090 if (cursorRange.isInvalid()) 5091 return CXChildVisit_Recurse; 5092 5093 if (!HasContextSensitiveKeywords) { 5094 // Objective-C properties can have context-sensitive keywords. 5095 if (cursor.kind == CXCursor_ObjCPropertyDecl) { 5096 if (const ObjCPropertyDecl *Property 5097 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor))) 5098 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0; 5099 } 5100 // Objective-C methods can have context-sensitive keywords. 5101 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl || 5102 cursor.kind == CXCursor_ObjCClassMethodDecl) { 5103 if (const ObjCMethodDecl *Method 5104 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) { 5105 if (Method->getObjCDeclQualifier()) 5106 HasContextSensitiveKeywords = true; 5107 else { 5108 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(), 5109 PEnd = Method->param_end(); 5110 P != PEnd; ++P) { 5111 if ((*P)->getObjCDeclQualifier()) { 5112 HasContextSensitiveKeywords = true; 5113 break; 5114 } 5115 } 5116 } 5117 } 5118 } 5119 // C++ methods can have context-sensitive keywords. 5120 else if (cursor.kind == CXCursor_CXXMethod) { 5121 if (const CXXMethodDecl *Method 5122 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) { 5123 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>()) 5124 HasContextSensitiveKeywords = true; 5125 } 5126 } 5127 // C++ classes can have context-sensitive keywords. 5128 else if (cursor.kind == CXCursor_StructDecl || 5129 cursor.kind == CXCursor_ClassDecl || 5130 cursor.kind == CXCursor_ClassTemplate || 5131 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) { 5132 if (const Decl *D = getCursorDecl(cursor)) 5133 if (D->hasAttr<FinalAttr>()) 5134 HasContextSensitiveKeywords = true; 5135 } 5136 } 5137 5138 if (clang_isPreprocessing(cursor.kind)) { 5139 // Items in the preprocessing record are kept separate from items in 5140 // declarations, so we keep a separate token index. 5141 unsigned SavedTokIdx = TokIdx; 5142 TokIdx = PreprocessingTokIdx; 5143 5144 // Skip tokens up until we catch up to the beginning of the preprocessing 5145 // entry. 5146 while (MoreTokens()) { 5147 const unsigned I = NextToken(); 5148 SourceLocation TokLoc = GetTokenLoc(I); 5149 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 5150 case RangeBefore: 5151 AdvanceToken(); 5152 continue; 5153 case RangeAfter: 5154 case RangeOverlap: 5155 break; 5156 } 5157 break; 5158 } 5159 5160 // Look at all of the tokens within this range. 5161 while (MoreTokens()) { 5162 const unsigned I = NextToken(); 5163 SourceLocation TokLoc = GetTokenLoc(I); 5164 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) { 5165 case RangeBefore: 5166 llvm_unreachable("Infeasible"); 5167 case RangeAfter: 5168 break; 5169 case RangeOverlap: 5170 // We may have already annotated macro names inside macro definitions. 5171 if (Cursors[I].kind != CXCursor_MacroExpansion) 5172 Cursors[I] = cursor; 5173 AdvanceToken(); 5174 // For macro expansions, just note where the beginning of the macro 5175 // expansion occurs. 5176 if (cursor.kind == CXCursor_MacroExpansion) 5177 break; 5178 continue; 5179 } 5180 break; 5181 } 5182 5183 // Save the preprocessing token index; restore the non-preprocessing 5184 // token index. 5185 PreprocessingTokIdx = TokIdx; 5186 TokIdx = SavedTokIdx; 5187 return CXChildVisit_Recurse; 5188 } 5189 5190 if (cursorRange.isInvalid()) 5191 return CXChildVisit_Continue; 5192 5193 const enum CXCursorKind cursorK = clang_getCursorKind(cursor); 5194 const enum CXCursorKind K = clang_getCursorKind(parent); 5195 const CXCursor updateC = 5196 (clang_isInvalid(K) || K == CXCursor_TranslationUnit) 5197 ? clang_getNullCursor() : parent; 5198 5199 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange); 5200 5201 // Avoid having the cursor of an expression "overwrite" the annotation of the 5202 // variable declaration that it belongs to. 5203 // This can happen for C++ constructor expressions whose range generally 5204 // include the variable declaration, e.g.: 5205 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor. 5206 if (clang_isExpression(cursorK)) { 5207 const Expr *E = getCursorExpr(cursor); 5208 if (const Decl *D = getCursorParentDecl(cursor)) { 5209 const unsigned I = NextToken(); 5210 if (E->getLocStart().isValid() && D->getLocation().isValid() && 5211 E->getLocStart() == D->getLocation() && 5212 E->getLocStart() == GetTokenLoc(I)) { 5213 updateCursorAnnotation(Cursors[I], updateC); 5214 AdvanceToken(); 5215 } 5216 } 5217 } 5218 5219 // Before recursing into the children keep some state that we are going 5220 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some 5221 // extra work after the child nodes are visited. 5222 // Note that we don't call VisitChildren here to avoid traversing statements 5223 // code-recursively which can blow the stack. 5224 5225 PostChildrenInfo Info; 5226 Info.Cursor = cursor; 5227 Info.CursorRange = cursorRange; 5228 Info.BeforeChildrenTokenIdx = NextToken(); 5229 PostChildrenInfos.push_back(Info); 5230 5231 return CXChildVisit_Recurse; 5232} 5233 5234bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) { 5235 if (PostChildrenInfos.empty()) 5236 return false; 5237 const PostChildrenInfo &Info = PostChildrenInfos.back(); 5238 if (!clang_equalCursors(Info.Cursor, cursor)) 5239 return false; 5240 5241 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx; 5242 const unsigned AfterChildren = NextToken(); 5243 SourceRange cursorRange = Info.CursorRange; 5244 5245 // Scan the tokens that are at the end of the cursor, but are not captured 5246 // but the child cursors. 5247 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange); 5248 5249 // Scan the tokens that are at the beginning of the cursor, but are not 5250 // capture by the child cursors. 5251 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) { 5252 if (!clang_isInvalid(clang_getCursorKind(Cursors[I]))) 5253 break; 5254 5255 Cursors[I] = cursor; 5256 } 5257 5258 PostChildrenInfos.pop_back(); 5259 return false; 5260} 5261 5262static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, 5263 CXCursor parent, 5264 CXClientData client_data) { 5265 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent); 5266} 5267 5268static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor, 5269 CXClientData client_data) { 5270 return static_cast<AnnotateTokensWorker*>(client_data)-> 5271 postVisitChildren(cursor); 5272} 5273 5274namespace { 5275 5276/// \brief Uses the macro expansions in the preprocessing record to find 5277/// and mark tokens that are macro arguments. This info is used by the 5278/// AnnotateTokensWorker. 5279class MarkMacroArgTokensVisitor { 5280 SourceManager &SM; 5281 CXToken *Tokens; 5282 unsigned NumTokens; 5283 unsigned CurIdx; 5284 5285public: 5286 MarkMacroArgTokensVisitor(SourceManager &SM, 5287 CXToken *tokens, unsigned numTokens) 5288 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { } 5289 5290 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) { 5291 if (cursor.kind != CXCursor_MacroExpansion) 5292 return CXChildVisit_Continue; 5293 5294 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange(); 5295 if (macroRange.getBegin() == macroRange.getEnd()) 5296 return CXChildVisit_Continue; // it's not a function macro. 5297 5298 for (; CurIdx < NumTokens; ++CurIdx) { 5299 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx), 5300 macroRange.getBegin())) 5301 break; 5302 } 5303 5304 if (CurIdx == NumTokens) 5305 return CXChildVisit_Break; 5306 5307 for (; CurIdx < NumTokens; ++CurIdx) { 5308 SourceLocation tokLoc = getTokenLoc(CurIdx); 5309 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd())) 5310 break; 5311 5312 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc)); 5313 } 5314 5315 if (CurIdx == NumTokens) 5316 return CXChildVisit_Break; 5317 5318 return CXChildVisit_Continue; 5319 } 5320 5321private: 5322 SourceLocation getTokenLoc(unsigned tokI) { 5323 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]); 5324 } 5325 5326 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) { 5327 // The third field is reserved and currently not used. Use it here 5328 // to mark macro arg expanded tokens with their expanded locations. 5329 Tokens[tokI].int_data[3] = loc.getRawEncoding(); 5330 } 5331}; 5332 5333} // end anonymous namespace 5334 5335static CXChildVisitResult 5336MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent, 5337 CXClientData client_data) { 5338 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor, 5339 parent); 5340} 5341 5342namespace { 5343 struct clang_annotateTokens_Data { 5344 CXTranslationUnit TU; 5345 ASTUnit *CXXUnit; 5346 CXToken *Tokens; 5347 unsigned NumTokens; 5348 CXCursor *Cursors; 5349 }; 5350} 5351 5352/// \brief Used by \c annotatePreprocessorTokens. 5353/// \returns true if lexing was finished, false otherwise. 5354static bool lexNext(Lexer &Lex, Token &Tok, 5355 unsigned &NextIdx, unsigned NumTokens) { 5356 if (NextIdx >= NumTokens) 5357 return true; 5358 5359 ++NextIdx; 5360 Lex.LexFromRawLexer(Tok); 5361 if (Tok.is(tok::eof)) 5362 return true; 5363 5364 return false; 5365} 5366 5367static void annotatePreprocessorTokens(CXTranslationUnit TU, 5368 SourceRange RegionOfInterest, 5369 CXCursor *Cursors, 5370 CXToken *Tokens, 5371 unsigned NumTokens) { 5372 ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 5373 5374 Preprocessor &PP = CXXUnit->getPreprocessor(); 5375 SourceManager &SourceMgr = CXXUnit->getSourceManager(); 5376 std::pair<FileID, unsigned> BeginLocInfo 5377 = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin()); 5378 std::pair<FileID, unsigned> EndLocInfo 5379 = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd()); 5380 5381 if (BeginLocInfo.first != EndLocInfo.first) 5382 return; 5383 5384 StringRef Buffer; 5385 bool Invalid = false; 5386 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid); 5387 if (Buffer.empty() || Invalid) 5388 return; 5389 5390 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), 5391 CXXUnit->getASTContext().getLangOpts(), 5392 Buffer.begin(), Buffer.data() + BeginLocInfo.second, 5393 Buffer.end()); 5394 Lex.SetCommentRetentionState(true); 5395 5396 unsigned NextIdx = 0; 5397 // Lex tokens in raw mode until we hit the end of the range, to avoid 5398 // entering #includes or expanding macros. 5399 while (true) { 5400 Token Tok; 5401 if (lexNext(Lex, Tok, NextIdx, NumTokens)) 5402 break; 5403 unsigned TokIdx = NextIdx-1; 5404 assert(Tok.getLocation() == 5405 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1])); 5406 5407 reprocess: 5408 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) { 5409 // We have found a preprocessing directive. Annotate the tokens 5410 // appropriately. 5411 // 5412 // FIXME: Some simple tests here could identify macro definitions and 5413 // #undefs, to provide specific cursor kinds for those. 5414 5415 SourceLocation BeginLoc = Tok.getLocation(); 5416 if (lexNext(Lex, Tok, NextIdx, NumTokens)) 5417 break; 5418 5419 MacroInfo *MI = 0; 5420 if (Tok.is(tok::raw_identifier) && 5421 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") { 5422 if (lexNext(Lex, Tok, NextIdx, NumTokens)) 5423 break; 5424 5425 if (Tok.is(tok::raw_identifier)) { 5426 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength()); 5427 IdentifierInfo &II = PP.getIdentifierTable().get(Name); 5428 SourceLocation MappedTokLoc = 5429 CXXUnit->mapLocationToPreamble(Tok.getLocation()); 5430 MI = getMacroInfo(II, MappedTokLoc, TU); 5431 } 5432 } 5433 5434 bool finished = false; 5435 do { 5436 if (lexNext(Lex, Tok, NextIdx, NumTokens)) { 5437 finished = true; 5438 break; 5439 } 5440 // If we are in a macro definition, check if the token was ever a 5441 // macro name and annotate it if that's the case. 5442 if (MI) { 5443 SourceLocation SaveLoc = Tok.getLocation(); 5444 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc)); 5445 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU); 5446 Tok.setLocation(SaveLoc); 5447 if (MacroDef) 5448 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef, 5449 Tok.getLocation(), TU); 5450 } 5451 } while (!Tok.isAtStartOfLine()); 5452 5453 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2; 5454 assert(TokIdx <= LastIdx); 5455 SourceLocation EndLoc = 5456 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]); 5457 CXCursor Cursor = 5458 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU); 5459 5460 for (; TokIdx <= LastIdx; ++TokIdx) 5461 updateCursorAnnotation(Cursors[TokIdx], Cursor); 5462 5463 if (finished) 5464 break; 5465 goto reprocess; 5466 } 5467 } 5468} 5469 5470// This gets run a separate thread to avoid stack blowout. 5471static void clang_annotateTokensImpl(void *UserData) { 5472 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU; 5473 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit; 5474 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens; 5475 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens; 5476 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors; 5477 5478 CIndexer *CXXIdx = (CIndexer*)TU->CIdx; 5479 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing)) 5480 setThreadBackgroundPriority(); 5481 5482 // Determine the region of interest, which contains all of the tokens. 5483 SourceRange RegionOfInterest; 5484 RegionOfInterest.setBegin( 5485 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0]))); 5486 RegionOfInterest.setEnd( 5487 cxloc::translateSourceLocation(clang_getTokenLocation(TU, 5488 Tokens[NumTokens-1]))); 5489 5490 // Relex the tokens within the source range to look for preprocessing 5491 // directives. 5492 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens); 5493 5494 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) { 5495 // Search and mark tokens that are macro argument expansions. 5496 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), 5497 Tokens, NumTokens); 5498 CursorVisitor MacroArgMarker(TU, 5499 MarkMacroArgTokensVisitorDelegate, &Visitor, 5500 /*VisitPreprocessorLast=*/true, 5501 /*VisitIncludedEntities=*/false, 5502 RegionOfInterest); 5503 MacroArgMarker.visitPreprocessedEntitiesInRegion(); 5504 } 5505 5506 // Annotate all of the source locations in the region of interest that map to 5507 // a specific cursor. 5508 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest); 5509 5510 // FIXME: We use a ridiculous stack size here because the data-recursion 5511 // algorithm uses a large stack frame than the non-data recursive version, 5512 // and AnnotationTokensWorker currently transforms the data-recursion 5513 // algorithm back into a traditional recursion by explicitly calling 5514 // VisitChildren(). We will need to remove this explicit recursive call. 5515 W.AnnotateTokens(); 5516 5517 // If we ran into any entities that involve context-sensitive keywords, 5518 // take another pass through the tokens to mark them as such. 5519 if (W.hasContextSensitiveKeywords()) { 5520 for (unsigned I = 0; I != NumTokens; ++I) { 5521 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier) 5522 continue; 5523 5524 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) { 5525 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data); 5526 if (const ObjCPropertyDecl *Property 5527 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) { 5528 if (Property->getPropertyAttributesAsWritten() != 0 && 5529 llvm::StringSwitch<bool>(II->getName()) 5530 .Case("readonly", true) 5531 .Case("assign", true) 5532 .Case("unsafe_unretained", true) 5533 .Case("readwrite", true) 5534 .Case("retain", true) 5535 .Case("copy", true) 5536 .Case("nonatomic", true) 5537 .Case("atomic", true) 5538 .Case("getter", true) 5539 .Case("setter", true) 5540 .Case("strong", true) 5541 .Case("weak", true) 5542 .Default(false)) 5543 Tokens[I].int_data[0] = CXToken_Keyword; 5544 } 5545 continue; 5546 } 5547 5548 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl || 5549 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) { 5550 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data); 5551 if (llvm::StringSwitch<bool>(II->getName()) 5552 .Case("in", true) 5553 .Case("out", true) 5554 .Case("inout", true) 5555 .Case("oneway", true) 5556 .Case("bycopy", true) 5557 .Case("byref", true) 5558 .Default(false)) 5559 Tokens[I].int_data[0] = CXToken_Keyword; 5560 continue; 5561 } 5562 5563 if (Cursors[I].kind == CXCursor_CXXFinalAttr || 5564 Cursors[I].kind == CXCursor_CXXOverrideAttr) { 5565 Tokens[I].int_data[0] = CXToken_Keyword; 5566 continue; 5567 } 5568 } 5569 } 5570} 5571 5572extern "C" { 5573 5574void clang_annotateTokens(CXTranslationUnit TU, 5575 CXToken *Tokens, unsigned NumTokens, 5576 CXCursor *Cursors) { 5577 if (NumTokens == 0 || !Tokens || !Cursors) { 5578 LOG_FUNC_SECTION { *Log << "<null input>"; } 5579 return; 5580 } 5581 5582 LOG_FUNC_SECTION { 5583 *Log << TU << ' '; 5584 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]); 5585 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]); 5586 *Log << clang_getRange(bloc, eloc); 5587 } 5588 5589 // Any token we don't specifically annotate will have a NULL cursor. 5590 CXCursor C = clang_getNullCursor(); 5591 for (unsigned I = 0; I != NumTokens; ++I) 5592 Cursors[I] = C; 5593 5594 ASTUnit *CXXUnit = cxtu::getASTUnit(TU); 5595 if (!CXXUnit) 5596 return; 5597 5598 ASTUnit::ConcurrencyCheck Check(*CXXUnit); 5599 5600 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors }; 5601 llvm::CrashRecoveryContext CRC; 5602 if (!RunSafely(CRC, clang_annotateTokensImpl, &data, 5603 GetSafetyThreadStackSize() * 2)) { 5604 fprintf(stderr, "libclang: crash detected while annotating tokens\n"); 5605 } 5606} 5607 5608} // end: extern "C" 5609 5610//===----------------------------------------------------------------------===// 5611// Operations for querying linkage of a cursor. 5612//===----------------------------------------------------------------------===// 5613 5614extern "C" { 5615CXLinkageKind clang_getCursorLinkage(CXCursor cursor) { 5616 if (!clang_isDeclaration(cursor.kind)) 5617 return CXLinkage_Invalid; 5618 5619 const Decl *D = cxcursor::getCursorDecl(cursor); 5620 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D)) 5621 switch (ND->getLinkage()) { 5622 case NoLinkage: return CXLinkage_NoLinkage; 5623 case InternalLinkage: return CXLinkage_Internal; 5624 case UniqueExternalLinkage: return CXLinkage_UniqueExternal; 5625 case ExternalLinkage: return CXLinkage_External; 5626 }; 5627 5628 return CXLinkage_Invalid; 5629} 5630} // end: extern "C" 5631 5632//===----------------------------------------------------------------------===// 5633// Operations for querying language of a cursor. 5634//===----------------------------------------------------------------------===// 5635 5636static CXLanguageKind getDeclLanguage(const Decl *D) { 5637 if (!D) 5638 return CXLanguage_C; 5639 5640 switch (D->getKind()) { 5641 default: 5642 break; 5643 case Decl::ImplicitParam: 5644 case Decl::ObjCAtDefsField: 5645 case Decl::ObjCCategory: 5646 case Decl::ObjCCategoryImpl: 5647 case Decl::ObjCCompatibleAlias: 5648 case Decl::ObjCImplementation: 5649 case Decl::ObjCInterface: 5650 case Decl::ObjCIvar: 5651 case Decl::ObjCMethod: 5652 case Decl::ObjCProperty: 5653 case Decl::ObjCPropertyImpl: 5654 case Decl::ObjCProtocol: 5655 return CXLanguage_ObjC; 5656 case Decl::CXXConstructor: 5657 case Decl::CXXConversion: 5658 case Decl::CXXDestructor: 5659 case Decl::CXXMethod: 5660 case Decl::CXXRecord: 5661 case Decl::ClassTemplate: 5662 case Decl::ClassTemplatePartialSpecialization: 5663 case Decl::ClassTemplateSpecialization: 5664 case Decl::Friend: 5665 case Decl::FriendTemplate: 5666 case Decl::FunctionTemplate: 5667 case Decl::LinkageSpec: 5668 case Decl::Namespace: 5669 case Decl::NamespaceAlias: 5670 case Decl::NonTypeTemplateParm: 5671 case Decl::StaticAssert: 5672 case Decl::TemplateTemplateParm: 5673 case Decl::TemplateTypeParm: 5674 case Decl::UnresolvedUsingTypename: 5675 case Decl::UnresolvedUsingValue: 5676 case Decl::Using: 5677 case Decl::UsingDirective: 5678 case Decl::UsingShadow: 5679 return CXLanguage_CPlusPlus; 5680 } 5681 5682 return CXLanguage_C; 5683} 5684 5685extern "C" { 5686 5687enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) { 5688 if (clang_isDeclaration(cursor.kind)) 5689 if (const Decl *D = cxcursor::getCursorDecl(cursor)) { 5690 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()) 5691 return CXAvailability_Available; 5692 5693 switch (D->getAvailability()) { 5694 case AR_Available: 5695 case AR_NotYetIntroduced: 5696 return CXAvailability_Available; 5697 5698 case AR_Deprecated: 5699 return CXAvailability_Deprecated; 5700 5701 case AR_Unavailable: 5702 return CXAvailability_NotAvailable; 5703 } 5704 } 5705 5706 return CXAvailability_Available; 5707} 5708 5709static CXVersion convertVersion(VersionTuple In) { 5710 CXVersion Out = { -1, -1, -1 }; 5711 if (In.empty()) 5712 return Out; 5713 5714 Out.Major = In.getMajor(); 5715 5716 if (llvm::Optional<unsigned> Minor = In.getMinor()) 5717 Out.Minor = *Minor; 5718 else 5719 return Out; 5720 5721 if (llvm::Optional<unsigned> Subminor = In.getSubminor()) 5722 Out.Subminor = *Subminor; 5723 5724 return Out; 5725} 5726 5727int clang_getCursorPlatformAvailability(CXCursor cursor, 5728 int *always_deprecated, 5729 CXString *deprecated_message, 5730 int *always_unavailable, 5731 CXString *unavailable_message, 5732 CXPlatformAvailability *availability, 5733 int availability_size) { 5734 if (always_deprecated) 5735 *always_deprecated = 0; 5736 if (deprecated_message) 5737 *deprecated_message = cxstring::createCXString("", /*DupString=*/false); 5738 if (always_unavailable) 5739 *always_unavailable = 0; 5740 if (unavailable_message) 5741 *unavailable_message = cxstring::createCXString("", /*DupString=*/false); 5742 5743 if (!clang_isDeclaration(cursor.kind)) 5744 return 0; 5745 5746 const Decl *D = cxcursor::getCursorDecl(cursor); 5747 if (!D) 5748 return 0; 5749 5750 int N = 0; 5751 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd; 5752 ++A) { 5753 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) { 5754 if (always_deprecated) 5755 *always_deprecated = 1; 5756 if (deprecated_message) 5757 *deprecated_message = cxstring::createCXString(Deprecated->getMessage()); 5758 continue; 5759 } 5760 5761 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) { 5762 if (always_unavailable) 5763 *always_unavailable = 1; 5764 if (unavailable_message) { 5765 *unavailable_message 5766 = cxstring::createCXString(Unavailable->getMessage()); 5767 } 5768 continue; 5769 } 5770 5771 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) { 5772 if (N < availability_size) { 5773 availability[N].Platform 5774 = cxstring::createCXString(Avail->getPlatform()->getName()); 5775 availability[N].Introduced = convertVersion(Avail->getIntroduced()); 5776 availability[N].Deprecated = convertVersion(Avail->getDeprecated()); 5777 availability[N].Obsoleted = convertVersion(Avail->getObsoleted()); 5778 availability[N].Unavailable = Avail->getUnavailable(); 5779 availability[N].Message = cxstring::createCXString(Avail->getMessage()); 5780 } 5781 ++N; 5782 } 5783 } 5784 5785 return N; 5786} 5787 5788void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) { 5789 clang_disposeString(availability->Platform); 5790 clang_disposeString(availability->Message); 5791} 5792 5793CXLanguageKind clang_getCursorLanguage(CXCursor cursor) { 5794 if (clang_isDeclaration(cursor.kind)) 5795 return getDeclLanguage(cxcursor::getCursorDecl(cursor)); 5796 5797 return CXLanguage_Invalid; 5798} 5799 5800 /// \brief If the given cursor is the "templated" declaration 5801 /// descibing a class or function template, return the class or 5802 /// function template. 5803static const Decl *maybeGetTemplateCursor(const Decl *D) { 5804 if (!D) 5805 return 0; 5806 5807 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 5808 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate()) 5809 return FunTmpl; 5810 5811 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) 5812 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate()) 5813 return ClassTmpl; 5814 5815 return D; 5816} 5817 5818CXCursor clang_getCursorSemanticParent(CXCursor cursor) { 5819 if (clang_isDeclaration(cursor.kind)) { 5820 if (const Decl *D = getCursorDecl(cursor)) { 5821 const DeclContext *DC = D->getDeclContext(); 5822 if (!DC) 5823 return clang_getNullCursor(); 5824 5825 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)), 5826 getCursorTU(cursor)); 5827 } 5828 } 5829 5830 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) { 5831 if (const Decl *D = getCursorDecl(cursor)) 5832 return MakeCXCursor(D, getCursorTU(cursor)); 5833 } 5834 5835 return clang_getNullCursor(); 5836} 5837 5838CXCursor clang_getCursorLexicalParent(CXCursor cursor) { 5839 if (clang_isDeclaration(cursor.kind)) { 5840 if (const Decl *D = getCursorDecl(cursor)) { 5841 const DeclContext *DC = D->getLexicalDeclContext(); 5842 if (!DC) 5843 return clang_getNullCursor(); 5844 5845 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)), 5846 getCursorTU(cursor)); 5847 } 5848 } 5849 5850 // FIXME: Note that we can't easily compute the lexical context of a 5851 // statement or expression, so we return nothing. 5852 return clang_getNullCursor(); 5853} 5854 5855CXFile clang_getIncludedFile(CXCursor cursor) { 5856 if (cursor.kind != CXCursor_InclusionDirective) 5857 return 0; 5858 5859 const InclusionDirective *ID = getCursorInclusionDirective(cursor); 5860 return const_cast<FileEntry *>(ID->getFile()); 5861} 5862 5863CXSourceRange clang_Cursor_getCommentRange(CXCursor C) { 5864 if (!clang_isDeclaration(C.kind)) 5865 return clang_getNullRange(); 5866 5867 const Decl *D = getCursorDecl(C); 5868 ASTContext &Context = getCursorContext(C); 5869 const RawComment *RC = Context.getRawCommentForAnyRedecl(D); 5870 if (!RC) 5871 return clang_getNullRange(); 5872 5873 return cxloc::translateSourceRange(Context, RC->getSourceRange()); 5874} 5875 5876CXString clang_Cursor_getRawCommentText(CXCursor C) { 5877 if (!clang_isDeclaration(C.kind)) 5878 return createCXString((const char *) NULL); 5879 5880 const Decl *D = getCursorDecl(C); 5881 ASTContext &Context = getCursorContext(C); 5882 const RawComment *RC = Context.getRawCommentForAnyRedecl(D); 5883 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) : 5884 StringRef(); 5885 5886 // Don't duplicate the string because RawText points directly into source 5887 // code. 5888 return createCXString(RawText, false); 5889} 5890 5891CXString clang_Cursor_getBriefCommentText(CXCursor C) { 5892 if (!clang_isDeclaration(C.kind)) 5893 return createCXString((const char *) NULL); 5894 5895 const Decl *D = getCursorDecl(C); 5896 const ASTContext &Context = getCursorContext(C); 5897 const RawComment *RC = Context.getRawCommentForAnyRedecl(D); 5898 5899 if (RC) { 5900 StringRef BriefText = RC->getBriefText(Context); 5901 5902 // Don't duplicate the string because RawComment ensures that this memory 5903 // will not go away. 5904 return createCXString(BriefText, false); 5905 } 5906 5907 return createCXString((const char *) NULL); 5908} 5909 5910CXComment clang_Cursor_getParsedComment(CXCursor C) { 5911 if (!clang_isDeclaration(C.kind)) 5912 return cxcomment::createCXComment(NULL, NULL); 5913 5914 const Decl *D = getCursorDecl(C); 5915 const ASTContext &Context = getCursorContext(C); 5916 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL); 5917 5918 return cxcomment::createCXComment(FC, getCursorTU(C)); 5919} 5920 5921CXModule clang_Cursor_getModule(CXCursor C) { 5922 if (C.kind == CXCursor_ModuleImportDecl) { 5923 if (const ImportDecl *ImportD = 5924 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) 5925 return ImportD->getImportedModule(); 5926 } 5927 5928 return 0; 5929} 5930 5931CXModule clang_Module_getParent(CXModule CXMod) { 5932 if (!CXMod) 5933 return 0; 5934 Module *Mod = static_cast<Module*>(CXMod); 5935 return Mod->Parent; 5936} 5937 5938CXString clang_Module_getName(CXModule CXMod) { 5939 if (!CXMod) 5940 return createCXString(""); 5941 Module *Mod = static_cast<Module*>(CXMod); 5942 return createCXString(Mod->Name); 5943} 5944 5945CXString clang_Module_getFullName(CXModule CXMod) { 5946 if (!CXMod) 5947 return createCXString(""); 5948 Module *Mod = static_cast<Module*>(CXMod); 5949 return createCXString(Mod->getFullModuleName()); 5950} 5951 5952unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) { 5953 if (!CXMod) 5954 return 0; 5955 Module *Mod = static_cast<Module*>(CXMod); 5956 return Mod->TopHeaders.size(); 5957} 5958 5959CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) { 5960 if (!CXMod) 5961 return 0; 5962 Module *Mod = static_cast<Module*>(CXMod); 5963 5964 if (Index < Mod->TopHeaders.size()) 5965 return const_cast<FileEntry *>(Mod->TopHeaders[Index]); 5966 5967 return 0; 5968} 5969 5970} // end: extern "C" 5971 5972//===----------------------------------------------------------------------===// 5973// C++ AST instrospection. 5974//===----------------------------------------------------------------------===// 5975 5976extern "C" { 5977unsigned clang_CXXMethod_isStatic(CXCursor C) { 5978 if (!clang_isDeclaration(C.kind)) 5979 return 0; 5980 5981 const CXXMethodDecl *Method = 0; 5982 const Decl *D = cxcursor::getCursorDecl(C); 5983 if (const FunctionTemplateDecl *FunTmpl = 5984 dyn_cast_or_null<FunctionTemplateDecl>(D)) 5985 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); 5986 else 5987 Method = dyn_cast_or_null<CXXMethodDecl>(D); 5988 return (Method && Method->isStatic()) ? 1 : 0; 5989} 5990 5991unsigned clang_CXXMethod_isVirtual(CXCursor C) { 5992 if (!clang_isDeclaration(C.kind)) 5993 return 0; 5994 5995 const CXXMethodDecl *Method = 0; 5996 const Decl *D = cxcursor::getCursorDecl(C); 5997 if (const FunctionTemplateDecl *FunTmpl = 5998 dyn_cast_or_null<FunctionTemplateDecl>(D)) 5999 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); 6000 else 6001 Method = dyn_cast_or_null<CXXMethodDecl>(D); 6002 return (Method && Method->isVirtual()) ? 1 : 0; 6003} 6004} // end: extern "C" 6005 6006//===----------------------------------------------------------------------===// 6007// Attribute introspection. 6008//===----------------------------------------------------------------------===// 6009 6010extern "C" { 6011CXType clang_getIBOutletCollectionType(CXCursor C) { 6012 if (C.kind != CXCursor_IBOutletCollectionAttr) 6013 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C)); 6014 6015 const IBOutletCollectionAttr *A = 6016 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C)); 6017 6018 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C)); 6019} 6020} // end: extern "C" 6021 6022//===----------------------------------------------------------------------===// 6023// Inspecting memory usage. 6024//===----------------------------------------------------------------------===// 6025 6026typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries; 6027 6028static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries, 6029 enum CXTUResourceUsageKind k, 6030 unsigned long amount) { 6031 CXTUResourceUsageEntry entry = { k, amount }; 6032 entries.push_back(entry); 6033} 6034 6035extern "C" { 6036 6037const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) { 6038 const char *str = ""; 6039 switch (kind) { 6040 case CXTUResourceUsage_AST: 6041 str = "ASTContext: expressions, declarations, and types"; 6042 break; 6043 case CXTUResourceUsage_Identifiers: 6044 str = "ASTContext: identifiers"; 6045 break; 6046 case CXTUResourceUsage_Selectors: 6047 str = "ASTContext: selectors"; 6048 break; 6049 case CXTUResourceUsage_GlobalCompletionResults: 6050 str = "Code completion: cached global results"; 6051 break; 6052 case CXTUResourceUsage_SourceManagerContentCache: 6053 str = "SourceManager: content cache allocator"; 6054 break; 6055 case CXTUResourceUsage_AST_SideTables: 6056 str = "ASTContext: side tables"; 6057 break; 6058 case CXTUResourceUsage_SourceManager_Membuffer_Malloc: 6059 str = "SourceManager: malloc'ed memory buffers"; 6060 break; 6061 case CXTUResourceUsage_SourceManager_Membuffer_MMap: 6062 str = "SourceManager: mmap'ed memory buffers"; 6063 break; 6064 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc: 6065 str = "ExternalASTSource: malloc'ed memory buffers"; 6066 break; 6067 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap: 6068 str = "ExternalASTSource: mmap'ed memory buffers"; 6069 break; 6070 case CXTUResourceUsage_Preprocessor: 6071 str = "Preprocessor: malloc'ed memory"; 6072 break; 6073 case CXTUResourceUsage_PreprocessingRecord: 6074 str = "Preprocessor: PreprocessingRecord"; 6075 break; 6076 case CXTUResourceUsage_SourceManager_DataStructures: 6077 str = "SourceManager: data structures and tables"; 6078 break; 6079 case CXTUResourceUsage_Preprocessor_HeaderSearch: 6080 str = "Preprocessor: header search tables"; 6081 break; 6082 } 6083 return str; 6084} 6085 6086CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) { 6087 if (!TU) { 6088 CXTUResourceUsage usage = { (void*) 0, 0, 0 }; 6089 return usage; 6090 } 6091 6092 ASTUnit *astUnit = cxtu::getASTUnit(TU); 6093 OwningPtr<MemUsageEntries> entries(new MemUsageEntries()); 6094 ASTContext &astContext = astUnit->getASTContext(); 6095 6096 // How much memory is used by AST nodes and types? 6097 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST, 6098 (unsigned long) astContext.getASTAllocatedMemory()); 6099 6100 // How much memory is used by identifiers? 6101 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers, 6102 (unsigned long) astContext.Idents.getAllocator().getTotalMemory()); 6103 6104 // How much memory is used for selectors? 6105 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors, 6106 (unsigned long) astContext.Selectors.getTotalMemory()); 6107 6108 // How much memory is used by ASTContext's side tables? 6109 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables, 6110 (unsigned long) astContext.getSideTableAllocatedMemory()); 6111 6112 // How much memory is used for caching global code completion results? 6113 unsigned long completionBytes = 0; 6114 if (GlobalCodeCompletionAllocator *completionAllocator = 6115 astUnit->getCachedCompletionAllocator().getPtr()) { 6116 completionBytes = completionAllocator->getTotalMemory(); 6117 } 6118 createCXTUResourceUsageEntry(*entries, 6119 CXTUResourceUsage_GlobalCompletionResults, 6120 completionBytes); 6121 6122 // How much memory is being used by SourceManager's content cache? 6123 createCXTUResourceUsageEntry(*entries, 6124 CXTUResourceUsage_SourceManagerContentCache, 6125 (unsigned long) astContext.getSourceManager().getContentCacheSize()); 6126 6127 // How much memory is being used by the MemoryBuffer's in SourceManager? 6128 const SourceManager::MemoryBufferSizes &srcBufs = 6129 astUnit->getSourceManager().getMemoryBufferSizes(); 6130 6131 createCXTUResourceUsageEntry(*entries, 6132 CXTUResourceUsage_SourceManager_Membuffer_Malloc, 6133 (unsigned long) srcBufs.malloc_bytes); 6134 createCXTUResourceUsageEntry(*entries, 6135 CXTUResourceUsage_SourceManager_Membuffer_MMap, 6136 (unsigned long) srcBufs.mmap_bytes); 6137 createCXTUResourceUsageEntry(*entries, 6138 CXTUResourceUsage_SourceManager_DataStructures, 6139 (unsigned long) astContext.getSourceManager() 6140 .getDataStructureSizes()); 6141 6142 // How much memory is being used by the ExternalASTSource? 6143 if (ExternalASTSource *esrc = astContext.getExternalSource()) { 6144 const ExternalASTSource::MemoryBufferSizes &sizes = 6145 esrc->getMemoryBufferSizes(); 6146 6147 createCXTUResourceUsageEntry(*entries, 6148 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc, 6149 (unsigned long) sizes.malloc_bytes); 6150 createCXTUResourceUsageEntry(*entries, 6151 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap, 6152 (unsigned long) sizes.mmap_bytes); 6153 } 6154 6155 // How much memory is being used by the Preprocessor? 6156 Preprocessor &pp = astUnit->getPreprocessor(); 6157 createCXTUResourceUsageEntry(*entries, 6158 CXTUResourceUsage_Preprocessor, 6159 pp.getTotalMemory()); 6160 6161 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) { 6162 createCXTUResourceUsageEntry(*entries, 6163 CXTUResourceUsage_PreprocessingRecord, 6164 pRec->getTotalMemory()); 6165 } 6166 6167 createCXTUResourceUsageEntry(*entries, 6168 CXTUResourceUsage_Preprocessor_HeaderSearch, 6169 pp.getHeaderSearchInfo().getTotalMemory()); 6170 6171 CXTUResourceUsage usage = { (void*) entries.get(), 6172 (unsigned) entries->size(), 6173 entries->size() ? &(*entries)[0] : 0 }; 6174 entries.take(); 6175 return usage; 6176} 6177 6178void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) { 6179 if (usage.data) 6180 delete (MemUsageEntries*) usage.data; 6181} 6182 6183} // end extern "C" 6184 6185void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) { 6186 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU); 6187 for (unsigned I = 0; I != Usage.numEntries; ++I) 6188 fprintf(stderr, " %s: %lu\n", 6189 clang_getTUResourceUsageName(Usage.entries[I].kind), 6190 Usage.entries[I].amount); 6191 6192 clang_disposeCXTUResourceUsage(Usage); 6193} 6194 6195//===----------------------------------------------------------------------===// 6196// Misc. utility functions. 6197//===----------------------------------------------------------------------===// 6198 6199/// Default to using an 8 MB stack size on "safety" threads. 6200static unsigned SafetyStackThreadSize = 8 << 20; 6201 6202namespace clang { 6203 6204bool RunSafely(llvm::CrashRecoveryContext &CRC, 6205 void (*Fn)(void*), void *UserData, 6206 unsigned Size) { 6207 if (!Size) 6208 Size = GetSafetyThreadStackSize(); 6209 if (Size) 6210 return CRC.RunSafelyOnThread(Fn, UserData, Size); 6211 return CRC.RunSafely(Fn, UserData); 6212} 6213 6214unsigned GetSafetyThreadStackSize() { 6215 return SafetyStackThreadSize; 6216} 6217 6218void SetSafetyThreadStackSize(unsigned Value) { 6219 SafetyStackThreadSize = Value; 6220} 6221 6222} 6223 6224void clang::setThreadBackgroundPriority() { 6225 if (getenv("LIBCLANG_BGPRIO_DISABLE")) 6226 return; 6227 6228 // FIXME: Move to llvm/Support and make it cross-platform. 6229#ifdef __APPLE__ 6230 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG); 6231#endif 6232} 6233 6234void cxindex::printDiagsToStderr(ASTUnit *Unit) { 6235 if (!Unit) 6236 return; 6237 6238 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), 6239 DEnd = Unit->stored_diag_end(); 6240 D != DEnd; ++D) { 6241 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts()); 6242 CXString Msg = clang_formatDiagnostic(&Diag, 6243 clang_defaultDiagnosticDisplayOptions()); 6244 fprintf(stderr, "%s\n", clang_getCString(Msg)); 6245 clang_disposeString(Msg); 6246 } 6247#ifdef LLVM_ON_WIN32 6248 // On Windows, force a flush, since there may be multiple copies of 6249 // stderr and stdout in the file system, all with different buffers 6250 // but writing to the same device. 6251 fflush(stderr); 6252#endif 6253} 6254 6255MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II, 6256 SourceLocation MacroDefLoc, 6257 CXTranslationUnit TU){ 6258 if (MacroDefLoc.isInvalid() || !TU) 6259 return 0; 6260 if (!II.hadMacroDefinition()) 6261 return 0; 6262 6263 ASTUnit *Unit = cxtu::getASTUnit(TU); 6264 Preprocessor &PP = Unit->getPreprocessor(); 6265 MacroInfo *MI = PP.getMacroInfoHistory(&II); 6266 while (MI) { 6267 if (MacroDefLoc == MI->getDefinitionLoc()) 6268 return MI; 6269 MI = MI->getPreviousDefinition(); 6270 } 6271 6272 return 0; 6273} 6274 6275const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef, 6276 CXTranslationUnit TU) { 6277 if (!MacroDef || !TU) 6278 return 0; 6279 const IdentifierInfo *II = MacroDef->getName(); 6280 if (!II) 6281 return 0; 6282 6283 return getMacroInfo(*II, MacroDef->getLocation(), TU); 6284} 6285 6286MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, 6287 const Token &Tok, 6288 CXTranslationUnit TU) { 6289 if (!MI || !TU) 6290 return 0; 6291 if (Tok.isNot(tok::raw_identifier)) 6292 return 0; 6293 6294 if (MI->getNumTokens() == 0) 6295 return 0; 6296 SourceRange DefRange(MI->getReplacementToken(0).getLocation(), 6297 MI->getDefinitionEndLoc()); 6298 ASTUnit *Unit = cxtu::getASTUnit(TU); 6299 6300 // Check that the token is inside the definition and not its argument list. 6301 SourceManager &SM = Unit->getSourceManager(); 6302 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin())) 6303 return 0; 6304 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation())) 6305 return 0; 6306 6307 Preprocessor &PP = Unit->getPreprocessor(); 6308 PreprocessingRecord *PPRec = PP.getPreprocessingRecord(); 6309 if (!PPRec) 6310 return 0; 6311 6312 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength()); 6313 IdentifierInfo &II = PP.getIdentifierTable().get(Name); 6314 if (!II.hadMacroDefinition()) 6315 return 0; 6316 6317 // Check that the identifier is not one of the macro arguments. 6318 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end()) 6319 return 0; 6320 6321 MacroInfo *InnerMI = PP.getMacroInfoHistory(&II); 6322 if (!InnerMI) 6323 return 0; 6324 6325 return PPRec->findMacroDefinition(InnerMI); 6326} 6327 6328MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, 6329 SourceLocation Loc, 6330 CXTranslationUnit TU) { 6331 if (Loc.isInvalid() || !MI || !TU) 6332 return 0; 6333 6334 if (MI->getNumTokens() == 0) 6335 return 0; 6336 ASTUnit *Unit = cxtu::getASTUnit(TU); 6337 Preprocessor &PP = Unit->getPreprocessor(); 6338 if (!PP.getPreprocessingRecord()) 6339 return 0; 6340 Loc = Unit->getSourceManager().getSpellingLoc(Loc); 6341 Token Tok; 6342 if (PP.getRawToken(Loc, Tok)) 6343 return 0; 6344 6345 return checkForMacroInMacroDefinition(MI, Tok, TU); 6346} 6347 6348extern "C" { 6349 6350CXString clang_getClangVersion() { 6351 return createCXString(getClangFullVersion()); 6352} 6353 6354} // end: extern "C" 6355 6356Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) { 6357 if (TU) { 6358 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) { 6359 LogOS << '<' << Unit->getMainFileName() << '>'; 6360 return *this; 6361 } 6362 } 6363 6364 LogOS << "<NULL TU>"; 6365 return *this; 6366} 6367 6368Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) { 6369 CXFile File; 6370 unsigned Line, Column; 6371 clang_getFileLocation(Loc, &File, &Line, &Column, 0); 6372 CXString FileName = clang_getFileName(File); 6373 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column); 6374 clang_disposeString(FileName); 6375 return *this; 6376} 6377 6378Logger &cxindex::Logger::operator<<(CXSourceRange range) { 6379 CXSourceLocation BLoc = clang_getRangeStart(range); 6380 CXSourceLocation ELoc = clang_getRangeEnd(range); 6381 6382 CXFile BFile; 6383 unsigned BLine, BColumn; 6384 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0); 6385 6386 CXFile EFile; 6387 unsigned ELine, EColumn; 6388 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0); 6389 6390 CXString BFileName = clang_getFileName(BFile); 6391 if (BFile == EFile) { 6392 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName), 6393 BLine, BColumn, ELine, EColumn); 6394 } else { 6395 CXString EFileName = clang_getFileName(EFile); 6396 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), 6397 BLine, BColumn) 6398 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), 6399 ELine, EColumn); 6400 clang_disposeString(EFileName); 6401 } 6402 clang_disposeString(BFileName); 6403 return *this; 6404} 6405 6406Logger &cxindex::Logger::operator<<(CXString Str) { 6407 *this << clang_getCString(Str); 6408 return *this; 6409} 6410 6411Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) { 6412 LogOS << Fmt; 6413 return *this; 6414} 6415 6416cxindex::Logger::~Logger() { 6417 LogOS.flush(); 6418 6419 llvm::sys::ScopedLock L(EnableMultithreadingMutex); 6420 6421 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime(); 6422 6423 raw_ostream &OS = llvm::errs(); 6424 OS << "[libclang:" << Name << ':'; 6425 6426 // FIXME: Portability. 6427#if HAVE_PTHREAD_H && __APPLE__ 6428 mach_port_t tid = pthread_mach_thread_np(pthread_self()); 6429 OS << tid << ':'; 6430#endif 6431 6432 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime(); 6433 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime()); 6434 OS << Msg.str() << '\n'; 6435 6436 if (Trace) { 6437 llvm::sys::PrintStackTrace(stderr); 6438 OS << "--------------------------------------------------\n"; 6439 } 6440} 6441