diff options
author | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
commit | c72c57c9e9b69944e3e009cd5e209634839581d3 (patch) | |
tree | 4fc2f184c499d106f29a386c452b49e5197bf63d /tools/libclang/CIndex.cpp | |
parent | 5b20025c30d23d521e12c1f33ec8fa6b821952cd (diff) | |
download | FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.zip FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.tar.gz |
Vendor import of clang trunk r178860:
http://llvm.org/svn/llvm-project/cfe/trunk@178860
Diffstat (limited to 'tools/libclang/CIndex.cpp')
-rw-r--r-- | tools/libclang/CIndex.cpp | 1826 |
1 files changed, 1077 insertions, 749 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 3a6c408..a81f1e4 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -13,56 +13,63 @@ //===----------------------------------------------------------------------===// #include "CIndexer.h" +#include "CIndexDiagnostic.h" +#include "CLog.h" #include "CXComment.h" #include "CXCursor.h" -#include "CXTranslationUnit.h" +#include "CXSourceLocation.h" #include "CXString.h" +#include "CXTranslationUnit.h" #include "CXType.h" -#include "CXSourceLocation.h" -#include "CIndexDiagnostic.h" #include "CursorVisitor.h" - -#include "clang/Basic/Version.h" - +#include "SimpleFormatContext.h" #include "clang/AST/StmtVisitor.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/Version.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Lex/Lexer.h" #include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/Lexer.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Lex/Preprocessor.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/SaveAndRestore.h" +#include "llvm/Config/config.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/CrashRecoveryContext.h" -#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Format.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Timer.h" #include "llvm/Support/Mutex.h" +#include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Program.h" +#include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/Signals.h" #include "llvm/Support/Threading.h" -#include "llvm/Support/Compiler.h" +#include "llvm/Support/Timer.h" +#include "llvm/Support/raw_ostream.h" + +#if HAVE_PTHREAD_H +#include <pthread.h> +#endif using namespace clang; using namespace clang::cxcursor; -using namespace clang::cxstring; using namespace clang::cxtu; using namespace clang::cxindex; -CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *TU) { - if (!TU) +CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) { + if (!AU) return 0; CXTranslationUnit D = new CXTranslationUnitImpl(); D->CIdx = CIdx; - D->TUData = TU; - D->StringPool = createCXStringPool(); + D->TheASTUnit = AU; + D->StringPool = new cxstring::CXStringPool(); D->Diagnostics = 0; D->OverridenCursorsPool = createOverridenCXCursorsPool(); + D->FormatContext = 0; + D->FormatInMemoryUniqueId = 0; return D; } @@ -122,9 +129,11 @@ CXSourceRange cxloc::translateSourceRange(const SourceManager &SM, EndLoc = EndLoc.getLocWithOffset(Length); } - CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts }, - R.getBegin().getRawEncoding(), - EndLoc.getRawEncoding() }; + CXSourceRange Result = { + { &SM, &LangOpts }, + R.getBegin().getRawEncoding(), + EndLoc.getRawEncoding() + }; return Result; } @@ -155,7 +164,7 @@ bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) { return false; if (clang_isDeclaration(Cursor.kind)) { - Decl *D = getCursorDecl(Cursor); + const Decl *D = getCursorDecl(Cursor); if (!D) { assert(0 && "Invalid declaration cursor"); return true; // abort. @@ -214,11 +223,11 @@ static bool visitPreprocessedEntitiesInRange(SourceRange R, PPRec, FID); } -void CursorVisitor::visitFileRegion() { +bool CursorVisitor::visitFileRegion() { if (RegionOfInterest.isInvalid()) - return; + return false; - ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData); + ASTUnit *Unit = cxtu::getASTUnit(TU); SourceManager &SM = Unit->getSourceManager(); std::pair<FileID, unsigned> @@ -234,7 +243,7 @@ void CursorVisitor::visitFileRegion() { assert(Begin.first == End.first); if (Begin.second > End.second) - return; + return false; FileID File = Begin.first; unsigned Offset = Begin.second; @@ -242,12 +251,15 @@ void CursorVisitor::visitFileRegion() { if (!VisitDeclsOnly && !VisitPreprocessorLast) if (visitPreprocessedEntitiesInRegion()) - return; // visitation break. + return true; // visitation break. - visitDeclsFromFileRegion(File, Offset, Length); + if (visitDeclsFromFileRegion(File, Offset, Length)) + return true; // visitation break. if (!VisitDeclsOnly && VisitPreprocessorLast) - visitPreprocessedEntitiesInRegion(); + return visitPreprocessedEntitiesInRegion(); + + return false; } static bool isInLexicalContext(Decl *D, DeclContext *DC) { @@ -262,9 +274,9 @@ static bool isInLexicalContext(Decl *D, DeclContext *DC) { return false; } -void CursorVisitor::visitDeclsFromFileRegion(FileID File, +bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length) { - ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData); + ASTUnit *Unit = cxtu::getASTUnit(TU); SourceManager &SM = Unit->getSourceManager(); SourceRange Range = RegionOfInterest; @@ -277,7 +289,7 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File, bool Invalid = false; const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid); if (Invalid) - return; + return false; SourceLocation Outer; if (SLEntry.isFile()) @@ -285,7 +297,7 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File, else Outer = SLEntry.getExpansion().getExpansionLocStart(); if (Outer.isInvalid()) - return; + return false; llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer); Length = 0; @@ -328,11 +340,11 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File, } if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true)) - break; + return true; // visitation break. } if (VisitedAtLeastOnce) - return; + return false; // No Decls overlapped with the range. Move up the lexical context until there // is a context that contains the range or we reach the translation unit @@ -347,12 +359,14 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File, break; if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) { - Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true); - break; + if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true)) + return true; // visitation break. } DC = D->getLexicalDeclContext(); } + + return false; } bool CursorVisitor::visitPreprocessedEntitiesInRegion() { @@ -453,7 +467,7 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) { SetParentRAII SetParent(Parent, StmtParent, Cursor); if (clang_isDeclaration(Cursor.kind)) { - Decl *D = getCursorDecl(Cursor); + Decl *D = const_cast<Decl *>(getCursorDecl(Cursor)); if (!D) return false; @@ -461,22 +475,22 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) { } if (clang_isStatement(Cursor.kind)) { - if (Stmt *S = getCursorStmt(Cursor)) + if (const Stmt *S = getCursorStmt(Cursor)) return Visit(S); return false; } if (clang_isExpression(Cursor.kind)) { - if (Expr *E = getCursorExpr(Cursor)) + if (const Expr *E = getCursorExpr(Cursor)) return Visit(E); return false; } if (clang_isTranslationUnit(Cursor.kind)) { - CXTranslationUnit tu = getCursorTU(Cursor); - ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData); + CXTranslationUnit TU = getCursorTU(Cursor); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast }; for (unsigned I = 0; I != 2; ++I) { @@ -486,7 +500,7 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) { for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(), TLEnd = CXXUnit->top_level_end(); TL != TLEnd; ++TL) { - if (Visit(MakeCXCursor(*TL, tu, RegionOfInterest), true)) + if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true)) return true; } } else if (VisitDeclContext( @@ -504,7 +518,7 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) { } if (Cursor.kind == CXCursor_CXXBaseSpecifier) { - if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) { + if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) { if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) { return Visit(BaseTSInfo->getTypeLoc()); } @@ -512,13 +526,27 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) { } if (Cursor.kind == CXCursor_IBOutletCollectionAttr) { - IBOutletCollectionAttr *A = + const IBOutletCollectionAttr *A = cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor)); if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>()) return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(), A->getInterfaceLoc(), TU)); } + // If pointing inside a macro definition, check if the token is an identifier + // that was ever defined as a macro. In such a case, create a "pseudo" macro + // expansion cursor for that token. + SourceLocation BeginLoc = RegionOfInterest.getBegin(); + if (Cursor.kind == CXCursor_MacroDefinition && + BeginLoc == RegionOfInterest.getEnd()) { + SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc); + const MacroInfo *MI = + getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU); + if (MacroDefinition *MacroDef = + checkForMacroInMacroDefinition(MI, Loc, TU)) + return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU)); + } + // Nothing to visit at the moment. return false; } @@ -534,16 +562,16 @@ bool CursorVisitor::VisitBlockDecl(BlockDecl *B) { return false; } -llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) { +Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) { if (RegionOfInterest.isValid()) { SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager()); if (Range.isInvalid()) - return llvm::Optional<bool>(); + return None; switch (CompareRegionOfInterest(Range)) { case RangeBefore: // This declaration comes before the region of interest; skip it. - return llvm::Optional<bool>(); + return None; case RangeAfter: // This declaration comes after the region of interest; we're done. @@ -594,7 +622,7 @@ bool CursorVisitor::VisitDeclContext(DeclContext *DC) { Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU); } - const llvm::Optional<bool> &V = shouldVisitCursor(Cursor); + const Optional<bool> &V = shouldVisitCursor(Cursor); if (!V.hasValue()) continue; if (!V.getValue()) @@ -648,10 +676,10 @@ bool CursorVisitor::VisitClassTemplateSpecializationDecl( // Visit the template arguments used in the specialization. if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) { TypeLoc TL = SpecType->getTypeLoc(); - if (TemplateSpecializationTypeLoc *TSTLoc - = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) { - for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I) - if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I))) + if (TemplateSpecializationTypeLoc TSTLoc = + TL.getAs<TemplateSpecializationTypeLoc>()) { + for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I) + if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I))) return true; } } @@ -727,12 +755,12 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { // Visit the function declaration's syntactic components in the order // written. This requires a bit of work. TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); - FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL); + FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>(); // If we have a function declared directly (without the use of a typedef), // visit just the return type. Otherwise, just visit the function's type // now. - if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) || + if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) || (!FTL && Visit(TL))) return true; @@ -748,7 +776,7 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { // FIXME: Visit explicitly-specified template arguments! // Visit the function parameters, if we have a function type. - if (FTL && VisitFunctionTypeLoc(*FTL, true)) + if (FTL && VisitFunctionTypeLoc(FTL, true)) return true; // FIXME: Attributes? @@ -958,7 +986,7 @@ bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) { for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(), E = DeclsInContainer.end(); I != E; ++I) { CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest); - const llvm::Optional<bool> &V = shouldVisitCursor(Cursor); + const Optional<bool> &V = shouldVisitCursor(Cursor); if (!V.hasValue()) continue; if (!V.getValue()) @@ -1369,6 +1397,14 @@ bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { case BuiltinType::Void: case BuiltinType::NullPtr: case BuiltinType::Dependent: + case BuiltinType::OCLImage1d: + case BuiltinType::OCLImage1dArray: + case BuiltinType::OCLImage1dBuffer: + case BuiltinType::OCLImage2d: + case BuiltinType::OCLImage2dArray: + case BuiltinType::OCLImage3d: + case BuiltinType::OCLSampler: + case BuiltinType::OCLEvent: #define BUILTIN_TYPE(Id, SingletonId) #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id: #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id: @@ -1629,9 +1665,10 @@ namespace { #define DEF_JOB(NAME, DATA, KIND)\ class NAME : public VisitorJob {\ public:\ - NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \ + NAME(const DATA *d, CXCursor parent) : \ + VisitorJob(parent, VisitorJob::KIND, d) {} \ static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\ - DATA *get() const { return static_cast<DATA*>(data[0]); }\ + const DATA *get() const { return static_cast<const DATA*>(data[0]); }\ }; DEF_JOB(StmtVisit, Stmt, StmtVisitKind) @@ -1647,13 +1684,13 @@ DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind) class DeclVisit : public VisitorJob { public: - DeclVisit(Decl *d, CXCursor parent, bool isFirst) : + DeclVisit(const Decl *D, CXCursor parent, bool isFirst) : VisitorJob(parent, VisitorJob::DeclVisitKind, - d, isFirst ? (void*) 1 : (void*) 0) {} + D, isFirst ? (void*) 1 : (void*) 0) {} static bool classof(const VisitorJob *VJ) { return VJ->getKind() == DeclVisitKind; } - Decl *get() const { return static_cast<Decl*>(data[0]); } + const Decl *get() const { return static_cast<const Decl *>(data[0]); } bool isFirst() const { return data[1] ? true : false; } }; class TypeLocVisit : public VisitorJob { @@ -1668,7 +1705,7 @@ public: TypeLoc get() const { QualType T = QualType::getFromOpaquePtr(data[0]); - return TypeLoc(T, data[1]); + return TypeLoc(T, const_cast<void *>(data[1])); } }; @@ -1681,7 +1718,9 @@ public: static bool classof(const VisitorJob *VJ) { return VJ->getKind() == VisitorJob::LabelRefVisitKind; } - LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); } + const LabelDecl *get() const { + return static_cast<const LabelDecl *>(data[0]); + } SourceLocation getLoc() const { return SourceLocation::getFromPtrEncoding(data[1]); } }; @@ -1698,20 +1737,22 @@ public: } NestedNameSpecifierLoc get() const { - return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]), - data[1]); + return NestedNameSpecifierLoc( + const_cast<NestedNameSpecifier *>( + static_cast<const NestedNameSpecifier *>(data[0])), + const_cast<void *>(data[1])); } }; class DeclarationNameInfoVisit : public VisitorJob { public: - DeclarationNameInfoVisit(Stmt *S, CXCursor parent) + DeclarationNameInfoVisit(const Stmt *S, CXCursor parent) : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {} static bool classof(const VisitorJob *VJ) { return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind; } DeclarationNameInfo get() const { - Stmt *S = static_cast<Stmt*>(data[0]); + const Stmt *S = static_cast<const Stmt *>(data[0]); switch (S->getStmtClass()) { default: llvm_unreachable("Unhandled Stmt"); @@ -1726,85 +1767,85 @@ public: }; class MemberRefVisit : public VisitorJob { public: - MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent) + MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent) : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D, L.getPtrEncoding()) {} static bool classof(const VisitorJob *VJ) { return VJ->getKind() == VisitorJob::MemberRefVisitKind; } - FieldDecl *get() const { - return static_cast<FieldDecl*>(data[0]); + const FieldDecl *get() const { + return static_cast<const FieldDecl *>(data[0]); } SourceLocation getLoc() const { return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]); } }; -class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> { +class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> { VisitorWorkList &WL; CXCursor Parent; public: EnqueueVisitor(VisitorWorkList &wl, CXCursor parent) : WL(wl), Parent(parent) {} - void VisitAddrLabelExpr(AddrLabelExpr *E); - void VisitBlockExpr(BlockExpr *B); - void VisitCompoundLiteralExpr(CompoundLiteralExpr *E); - void VisitCompoundStmt(CompoundStmt *S); - void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ } - void VisitMSDependentExistsStmt(MSDependentExistsStmt *S); - void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); - void VisitCXXNewExpr(CXXNewExpr *E); - void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); - void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E); - void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); - void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E); - void VisitCXXTypeidExpr(CXXTypeidExpr *E); - void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E); - void VisitCXXUuidofExpr(CXXUuidofExpr *E); - void VisitCXXCatchStmt(CXXCatchStmt *S); - void VisitDeclRefExpr(DeclRefExpr *D); - void VisitDeclStmt(DeclStmt *S); - void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); - void VisitDesignatedInitExpr(DesignatedInitExpr *E); - void VisitExplicitCastExpr(ExplicitCastExpr *E); - void VisitForStmt(ForStmt *FS); - void VisitGotoStmt(GotoStmt *GS); - void VisitIfStmt(IfStmt *If); - void VisitInitListExpr(InitListExpr *IE); - void VisitMemberExpr(MemberExpr *M); - void VisitOffsetOfExpr(OffsetOfExpr *E); - void VisitObjCEncodeExpr(ObjCEncodeExpr *E); - void VisitObjCMessageExpr(ObjCMessageExpr *M); - void VisitOverloadExpr(OverloadExpr *E); - void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E); - void VisitStmt(Stmt *S); - void VisitSwitchStmt(SwitchStmt *S); - void VisitWhileStmt(WhileStmt *W); - void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E); - void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E); - void VisitTypeTraitExpr(TypeTraitExpr *E); - void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E); - void VisitExpressionTraitExpr(ExpressionTraitExpr *E); - void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U); - void VisitVAArgExpr(VAArgExpr *E); - void VisitSizeOfPackExpr(SizeOfPackExpr *E); - void VisitPseudoObjectExpr(PseudoObjectExpr *E); - void VisitOpaqueValueExpr(OpaqueValueExpr *E); - void VisitLambdaExpr(LambdaExpr *E); - + void VisitAddrLabelExpr(const AddrLabelExpr *E); + void VisitBlockExpr(const BlockExpr *B); + void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); + void VisitCompoundStmt(const CompoundStmt *S); + void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ } + void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S); + void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E); + void VisitCXXNewExpr(const CXXNewExpr *E); + void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E); + void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E); + void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E); + void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E); + void VisitCXXTypeidExpr(const CXXTypeidExpr *E); + void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E); + void VisitCXXUuidofExpr(const CXXUuidofExpr *E); + void VisitCXXCatchStmt(const CXXCatchStmt *S); + void VisitDeclRefExpr(const DeclRefExpr *D); + void VisitDeclStmt(const DeclStmt *S); + void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E); + void VisitDesignatedInitExpr(const DesignatedInitExpr *E); + void VisitExplicitCastExpr(const ExplicitCastExpr *E); + void VisitForStmt(const ForStmt *FS); + void VisitGotoStmt(const GotoStmt *GS); + void VisitIfStmt(const IfStmt *If); + void VisitInitListExpr(const InitListExpr *IE); + void VisitMemberExpr(const MemberExpr *M); + void VisitOffsetOfExpr(const OffsetOfExpr *E); + void VisitObjCEncodeExpr(const ObjCEncodeExpr *E); + void VisitObjCMessageExpr(const ObjCMessageExpr *M); + void VisitOverloadExpr(const OverloadExpr *E); + void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E); + void VisitStmt(const Stmt *S); + void VisitSwitchStmt(const SwitchStmt *S); + void VisitWhileStmt(const WhileStmt *W); + void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E); + void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E); + void VisitTypeTraitExpr(const TypeTraitExpr *E); + void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E); + void VisitExpressionTraitExpr(const ExpressionTraitExpr *E); + void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U); + void VisitVAArgExpr(const VAArgExpr *E); + void VisitSizeOfPackExpr(const SizeOfPackExpr *E); + void VisitPseudoObjectExpr(const PseudoObjectExpr *E); + void VisitOpaqueValueExpr(const OpaqueValueExpr *E); + void VisitLambdaExpr(const LambdaExpr *E); + private: - void AddDeclarationNameInfo(Stmt *S); + void AddDeclarationNameInfo(const Stmt *S); void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier); void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A); - void AddMemberRef(FieldDecl *D, SourceLocation L); - void AddStmt(Stmt *S); - void AddDecl(Decl *D, bool isFirst = true); + void AddMemberRef(const FieldDecl *D, SourceLocation L); + void AddStmt(const Stmt *S); + void AddDecl(const Decl *D, bool isFirst = true); void AddTypeLoc(TypeSourceInfo *TI); - void EnqueueChildren(Stmt *S); + void EnqueueChildren(const Stmt *S); }; } // end anonyous namespace -void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) { +void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) { // 'S' should always be non-null, since it comes from the // statement we are visiting. WL.push_back(DeclarationNameInfoVisit(S, Parent)); @@ -1816,21 +1857,20 @@ EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) { WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent)); } -void EnqueueVisitor::AddStmt(Stmt *S) { +void EnqueueVisitor::AddStmt(const Stmt *S) { if (S) WL.push_back(StmtVisit(S, Parent)); } -void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) { +void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) { if (D) WL.push_back(DeclVisit(D, Parent, isFirst)); } void EnqueueVisitor:: AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) { if (A) - WL.push_back(ExplicitTemplateArgsVisit( - const_cast<ASTTemplateArgumentListInfo*>(A), Parent)); + WL.push_back(ExplicitTemplateArgsVisit(A, Parent)); } -void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) { +void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) { if (D) WL.push_back(MemberRefVisit(D, L, Parent)); } @@ -1838,9 +1878,9 @@ void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) { if (TI) WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent)); } -void EnqueueVisitor::EnqueueChildren(Stmt *S) { +void EnqueueVisitor::EnqueueChildren(const Stmt *S) { unsigned size = WL.size(); - for (Stmt::child_range Child = S->children(); Child; ++Child) { + for (Stmt::const_child_range Child = S->children(); Child; ++Child) { AddStmt(*Child); } if (size == WL.size()) @@ -1850,24 +1890,24 @@ void EnqueueVisitor::EnqueueChildren(Stmt *S) { VisitorWorkList::iterator I = WL.begin() + size, E = WL.end(); std::reverse(I, E); } -void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) { +void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) { WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent)); } -void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) { +void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) { AddDecl(B->getBlockDecl()); } -void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { +void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { EnqueueChildren(E); AddTypeLoc(E->getTypeSourceInfo()); } -void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) { - for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(), +void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) { + for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(), E = S->body_rend(); I != E; ++I) { AddStmt(*I); } } void EnqueueVisitor:: -VisitMSDependentExistsStmt(MSDependentExistsStmt *S) { +VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) { AddStmt(S->getSubStmt()); AddDeclarationNameInfo(S); if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc()) @@ -1875,7 +1915,7 @@ VisitMSDependentExistsStmt(MSDependentExistsStmt *S) { } void EnqueueVisitor:: -VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) { +VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) { AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs()); AddDeclarationNameInfo(E); if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc()) @@ -1883,7 +1923,7 @@ VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) { if (!E->isImplicitAccess()) AddStmt(E->getBase()); } -void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) { +void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) { // Enqueue the initializer , if any. AddStmt(E->getInitializer()); // Enqueue the array size, if any. @@ -1894,13 +1934,14 @@ void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) { for (unsigned I = E->getNumPlacementArgs(); I > 0; --I) AddStmt(E->getPlacementArg(I-1)); } -void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) { +void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) { for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I) AddStmt(CE->getArg(I-1)); AddStmt(CE->getCallee()); AddStmt(CE->getArg(0)); } -void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { +void EnqueueVisitor::VisitCXXPseudoDestructorExpr( + const CXXPseudoDestructorExpr *E) { // Visit the name of the type being destroyed. AddTypeLoc(E->getDestroyedTypeInfo()); // Visit the scope type that looks disturbingly like the nested-name-specifier @@ -1912,50 +1953,53 @@ void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { // Visit base expression. AddStmt(E->getBase()); } -void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { +void EnqueueVisitor::VisitCXXScalarValueInitExpr( + const CXXScalarValueInitExpr *E) { AddTypeLoc(E->getTypeSourceInfo()); } -void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { +void EnqueueVisitor::VisitCXXTemporaryObjectExpr( + const CXXTemporaryObjectExpr *E) { EnqueueChildren(E); AddTypeLoc(E->getTypeSourceInfo()); } -void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) { +void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) { EnqueueChildren(E); if (E->isTypeOperand()) AddTypeLoc(E->getTypeOperandSourceInfo()); } -void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr - *E) { +void EnqueueVisitor::VisitCXXUnresolvedConstructExpr( + const CXXUnresolvedConstructExpr *E) { EnqueueChildren(E); AddTypeLoc(E->getTypeSourceInfo()); } -void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) { +void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { EnqueueChildren(E); if (E->isTypeOperand()) AddTypeLoc(E->getTypeOperandSourceInfo()); } -void EnqueueVisitor::VisitCXXCatchStmt(CXXCatchStmt *S) { +void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) { EnqueueChildren(S); AddDecl(S->getExceptionDecl()); } -void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) { +void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) { if (DR->hasExplicitTemplateArgs()) { AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs()); } WL.push_back(DeclRefExprParts(DR, Parent)); } -void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { +void EnqueueVisitor::VisitDependentScopeDeclRefExpr( + const DependentScopeDeclRefExpr *E) { AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs()); AddDeclarationNameInfo(E); AddNestedNameSpecifierLoc(E->getQualifierLoc()); } -void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) { +void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) { unsigned size = WL.size(); bool isFirst = true; - for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); + for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); D != DEnd; ++D) { AddDecl(*D, isFirst); isFirst = false; @@ -1967,10 +2011,10 @@ void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) { VisitorWorkList::iterator I = WL.begin() + size, E = WL.end(); std::reverse(I, E); } -void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) { +void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) { AddStmt(E->getInit()); typedef DesignatedInitExpr::Designator Designator; - for (DesignatedInitExpr::reverse_designators_iterator + for (DesignatedInitExpr::const_reverse_designators_iterator D = E->designators_rbegin(), DEnd = E->designators_rend(); D != DEnd; ++D) { if (D->isFieldDesignator()) { @@ -1987,33 +2031,33 @@ void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) { AddStmt(E->getArrayRangeStart(*D)); } } -void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) { +void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) { EnqueueChildren(E); AddTypeLoc(E->getTypeInfoAsWritten()); } -void EnqueueVisitor::VisitForStmt(ForStmt *FS) { +void EnqueueVisitor::VisitForStmt(const ForStmt *FS) { AddStmt(FS->getBody()); AddStmt(FS->getInc()); AddStmt(FS->getCond()); AddDecl(FS->getConditionVariable()); AddStmt(FS->getInit()); } -void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) { +void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) { WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent)); } -void EnqueueVisitor::VisitIfStmt(IfStmt *If) { +void EnqueueVisitor::VisitIfStmt(const IfStmt *If) { AddStmt(If->getElse()); AddStmt(If->getThen()); AddStmt(If->getCond()); AddDecl(If->getConditionVariable()); } -void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) { +void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) { // We care about the syntactic form of the initializer list, only. if (InitListExpr *Syntactic = IE->getSyntacticForm()) IE = Syntactic; EnqueueChildren(IE); } -void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) { +void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) { WL.push_back(MemberExprParts(M, Parent)); // If the base of the member access expression is an implicit 'this', don't @@ -2023,14 +2067,14 @@ void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) { if (!M->isImplicitAccess()) AddStmt(M->getBase()); } -void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { +void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { AddTypeLoc(E->getEncodedTypeSourceInfo()); } -void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) { +void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) { EnqueueChildren(M); AddTypeLoc(M->getClassReceiverTypeInfo()); } -void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) { +void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) { // Visit the components of the offsetof expression. for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) { typedef OffsetOfExpr::OffsetOfNode OffsetOfNode; @@ -2050,81 +2094,81 @@ void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) { // Visit the type into which we're computing the offset. AddTypeLoc(E->getTypeSourceInfo()); } -void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) { +void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) { AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs()); WL.push_back(OverloadExprParts(E, Parent)); } void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr( - UnaryExprOrTypeTraitExpr *E) { + const UnaryExprOrTypeTraitExpr *E) { EnqueueChildren(E); if (E->isArgumentType()) AddTypeLoc(E->getArgumentTypeInfo()); } -void EnqueueVisitor::VisitStmt(Stmt *S) { +void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); } -void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) { +void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) { AddStmt(S->getBody()); AddStmt(S->getCond()); AddDecl(S->getConditionVariable()); } -void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) { +void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) { AddStmt(W->getBody()); AddStmt(W->getCond()); AddDecl(W->getConditionVariable()); } -void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { +void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) { AddTypeLoc(E->getQueriedTypeSourceInfo()); } -void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { +void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) { AddTypeLoc(E->getRhsTypeSourceInfo()); AddTypeLoc(E->getLhsTypeSourceInfo()); } -void EnqueueVisitor::VisitTypeTraitExpr(TypeTraitExpr *E) { +void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) { for (unsigned I = E->getNumArgs(); I > 0; --I) AddTypeLoc(E->getArg(I-1)); } -void EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { +void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) { AddTypeLoc(E->getQueriedTypeSourceInfo()); } -void EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { +void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) { EnqueueChildren(E); } -void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) { +void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) { VisitOverloadExpr(U); if (!U->isImplicitAccess()) AddStmt(U->getBase()); } -void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) { +void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) { AddStmt(E->getSubExpr()); AddTypeLoc(E->getWrittenTypeInfo()); } -void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) { +void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) { WL.push_back(SizeOfPackExprParts(E, Parent)); } -void EnqueueVisitor::VisitOpaqueValueExpr(OpaqueValueExpr *E) { +void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) { // If the opaque value has a source expression, just transparently // visit that. This is useful for (e.g.) pseudo-object expressions. if (Expr *SourceExpr = E->getSourceExpr()) return Visit(SourceExpr); } -void EnqueueVisitor::VisitLambdaExpr(LambdaExpr *E) { +void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) { AddStmt(E->getBody()); WL.push_back(LambdaExprParts(E, Parent)); } -void EnqueueVisitor::VisitPseudoObjectExpr(PseudoObjectExpr *E) { +void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) { // Treat the expression like its syntactic form. Visit(E->getSyntacticForm()); } -void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) { +void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) { EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S); } @@ -2148,7 +2192,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { switch (LI.getKind()) { case VisitorJob::DeclVisitKind: { - Decl *D = cast<DeclVisit>(&LI)->get(); + const Decl *D = cast<DeclVisit>(&LI)->get(); if (!D) continue; @@ -2177,7 +2221,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { continue; } case VisitorJob::LabelRefVisitKind: { - LabelDecl *LS = cast<LabelRefVisit>(&LI)->get(); + const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get(); if (LabelStmt *stmt = LS->getStmt()) { if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(), TU))) { @@ -2207,7 +2251,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { continue; } case VisitorJob::StmtVisitKind: { - Stmt *S = cast<StmtVisit>(&LI)->get(); + const Stmt *S = cast<StmtVisit>(&LI)->get(); if (!S) continue; @@ -2228,7 +2272,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { } case VisitorJob::MemberExprPartsKind: { // Handle the other pieces in the MemberExpr besides the base. - MemberExpr *M = cast<MemberExprParts>(&LI)->get(); + const MemberExpr *M = cast<MemberExprParts>(&LI)->get(); // Visit the nested-name-specifier if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc()) @@ -2251,7 +2295,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { continue; } case VisitorJob::DeclRefExprPartsKind: { - DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get(); + const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get(); // Visit nested-name-specifier, if present. if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc()) if (VisitNestedNameSpecifierLoc(QualifierLoc)) @@ -2262,7 +2306,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { continue; } case VisitorJob::OverloadExprPartsKind: { - OverloadExpr *O = cast<OverloadExprParts>(&LI)->get(); + const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get(); // Visit the nested-name-specifier. if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc()) if (VisitNestedNameSpecifierLoc(QualifierLoc)) @@ -2276,7 +2320,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { continue; } case VisitorJob::SizeOfPackExprPartsKind: { - SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get(); + const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get(); NamedDecl *Pack = E->getPack(); if (isa<TemplateTypeParmDecl>(Pack)) { if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack), @@ -2301,7 +2345,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { case VisitorJob::LambdaExprPartsKind: { // Visit captures. - LambdaExpr *E = cast<LambdaExprParts>(&LI)->get(); + const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get(); for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(), CEnd = E->explicit_capture_end(); C != CEnd; ++C) { @@ -2321,8 +2365,8 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { // Visit the whole type. if (Visit(TL)) return true; - } else if (isa<FunctionProtoTypeLoc>(TL)) { - FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL); + } else if (FunctionProtoTypeLoc Proto = + TL.getAs<FunctionProtoTypeLoc>()) { if (E->hasExplicitParameters()) { // Visit parameters. for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) @@ -2347,7 +2391,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { return false; } -bool CursorVisitor::Visit(Stmt *S) { +bool CursorVisitor::Visit(const Stmt *S) { VisitorWorkList *WL = 0; if (!WorkListFreeList.empty()) { WL = WorkListFreeList.back(); @@ -2365,7 +2409,7 @@ bool CursorVisitor::Visit(Stmt *S) { } namespace { -typedef llvm::SmallVector<SourceRange, 4> RefNamePieces; +typedef SmallVector<SourceRange, 4> RefNamePieces; RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr, const DeclarationNameInfo &NI, const SourceRange &QLoc, @@ -2412,7 +2456,8 @@ RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr, static llvm::sys::Mutex EnableMultithreadingMutex; static bool EnabledMultithreading; -static void fatal_error_handler(void *user_data, const std::string& reason) { +static void fatal_error_handler(void *user_data, const std::string& reason, + bool gen_crash_diag) { // Write the result out to stderr avoiding errs() because raw_ostreams can // call report_fatal_error. fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str()); @@ -2486,7 +2531,6 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx, CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); FileSystemOptions FileSystemOpts; - FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory(); IntrusiveRefCntPtr<DiagnosticsEngine> Diags; ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts, @@ -2560,9 +2604,7 @@ static void clang_parseTranslationUnit_Impl(void *UserData) { // Configure the diagnostics. IntrusiveRefCntPtr<DiagnosticsEngine> - Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions, - num_command_line_args, - command_line_args)); + Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); // Recover resources if we crash before exiting this function. llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, @@ -2662,6 +2704,12 @@ CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx, struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files, unsigned options) { + LOG_FUNC_SECTION { + *Log << source_filename << ": "; + for (int i = 0; i != num_command_line_args; ++i) + *Log << command_line_args[i] << " "; + } + ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args, num_command_line_args, unsaved_files, num_unsaved_files, options, 0 }; @@ -2715,20 +2763,24 @@ static void clang_saveTranslationUnit_Impl(void *UserData) { SaveTranslationUnitInfo *STUI = static_cast<SaveTranslationUnitInfo*>(UserData); - CIndexer *CXXIdx = (CIndexer*)STUI->TU->CIdx; + CIndexer *CXXIdx = STUI->TU->CIdx; if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing)) setThreadBackgroundPriority(); - bool hadError = static_cast<ASTUnit *>(STUI->TU->TUData)->Save(STUI->FileName); + bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName); STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None; } int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName, unsigned options) { + LOG_FUNC_SECTION { + *Log << TU << ' ' << FileName; + } + if (!TU) return CXSaveError_InvalidTU; - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); ASTUnit::ConcurrencyCheck Check(*CXXUnit); if (!CXXUnit->hasSema()) return CXSaveError_InvalidTU; @@ -2769,13 +2821,14 @@ void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) { if (CTUnit) { // If the translation unit has been marked as unsafe to free, just discard // it. - if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree()) + if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree()) return; - delete static_cast<ASTUnit *>(CTUnit->TUData); - disposeCXStringPool(CTUnit->StringPool); + delete cxtu::getASTUnit(CTUnit); + delete CTUnit->StringPool; delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics); disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool); + delete CTUnit->FormatContext; delete CTUnit; } } @@ -2796,6 +2849,8 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) { ReparseTranslationUnitInfo *RTUI = static_cast<ReparseTranslationUnitInfo*>(UserData); CXTranslationUnit TU = RTUI->TU; + if (!TU) + return; // Reset the associated diagnostics. delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics); @@ -2807,14 +2862,11 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) { (void) options; RTUI->result = 1; - if (!TU) - return; - - CIndexer *CXXIdx = (CIndexer*)TU->CIdx; + CIndexer *CXXIdx = TU->CIdx; if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing)) setThreadBackgroundPriority(); - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); ASTUnit::ConcurrencyCheck Check(*CXXUnit); OwningPtr<std::vector<ASTUnit::RemappedFile> > @@ -2841,6 +2893,10 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU, unsigned num_unsaved_files, struct CXUnsavedFile *unsaved_files, unsigned options) { + LOG_FUNC_SECTION { + *Log << TU; + } + ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files, options, 0 }; @@ -2853,7 +2909,7 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU, if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) { fprintf(stderr, "libclang: crash detected during reparsing\n"); - static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true); + cxtu::getASTUnit(TU)->setUnsafeToFree(true); return 1; } else if (getenv("LIBCLANG_RESOURCE_USAGE")) PrintLibclangResourceUsage(TU); @@ -2864,14 +2920,17 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU, CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) { if (!CTUnit) - return createCXString(""); + return cxstring::createEmpty(); - ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData); - return createCXString(CXXUnit->getOriginalSourceFileName(), true); + ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit); + return cxstring::createDup(CXXUnit->getOriginalSourceFileName()); } CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) { - ASTUnit *CXXUnit = static_cast<ASTUnit*>(TU->TUData); + if (!TU) + return clang_getNullCursor(); + + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU); } @@ -2884,10 +2943,10 @@ CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) { extern "C" { CXString clang_getFileName(CXFile SFile) { if (!SFile) - return createCXString((const char*)NULL); + return cxstring::createNull(); FileEntry *FEnt = static_cast<FileEntry *>(SFile); - return createCXString(FEnt->getName()); + return cxstring::createRef(FEnt->getName()); } time_t clang_getFileTime(CXFile SFile) { @@ -2898,43 +2957,58 @@ time_t clang_getFileTime(CXFile SFile) { return FEnt->getModificationTime(); } -CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) { - if (!tu) +CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) { + if (!TU) return 0; - ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); FileManager &FMgr = CXXUnit->getFileManager(); return const_cast<FileEntry *>(FMgr.getFile(file_name)); } -unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file) { - if (!tu || !file) +unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) { + if (!TU || !file) return 0; - ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); FileEntry *FEnt = static_cast<FileEntry *>(file); return CXXUnit->getPreprocessor().getHeaderSearchInfo() .isFileMultipleIncludeGuarded(FEnt); } +int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) { + if (!file || !outID) + return 1; + +#ifdef LLVM_ON_WIN32 + return 1; // inodes not supported on windows. +#else + FileEntry *FEnt = static_cast<FileEntry *>(file); + outID->data[0] = FEnt->getDevice(); + outID->data[1] = FEnt->getInode(); + outID->data[2] = FEnt->getModificationTime(); + return 0; +#endif +} + } // end: extern "C" //===----------------------------------------------------------------------===// // CXCursor Operations. //===----------------------------------------------------------------------===// -static Decl *getDeclFromExpr(Stmt *E) { - if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) +static const Decl *getDeclFromExpr(const Stmt *E) { + if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) return getDeclFromExpr(CE->getSubExpr()); - if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E)) + if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E)) return RefExpr->getDecl(); - if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) + if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) return ME->getMemberDecl(); - if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E)) + if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E)) return RE->getDecl(); - if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) { + if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) { if (PRE->isExplicitProperty()) return PRE->getExplicitProperty(); // It could be messaging both getter and setter as in: @@ -2945,26 +3019,26 @@ static Decl *getDeclFromExpr(Stmt *E) { return PRE->getImplicitPropertySetter(); return PRE->getImplicitPropertyGetter(); } - if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) + if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) return getDeclFromExpr(POE->getSyntacticForm()); - if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) + if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) if (Expr *Src = OVE->getSourceExpr()) return getDeclFromExpr(Src); - if (CallExpr *CE = dyn_cast<CallExpr>(E)) + if (const CallExpr *CE = dyn_cast<CallExpr>(E)) return getDeclFromExpr(CE->getCallee()); - if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E)) + if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E)) if (!CE->isElidable()) return CE->getConstructor(); - if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E)) + if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E)) return OME->getMethodDecl(); - if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E)) + if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E)) return PE->getProtocol(); - if (SubstNonTypeTemplateParmPackExpr *NTTP + if (const SubstNonTypeTemplateParmPackExpr *NTTP = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E)) return NTTP->getParameterPack(); - if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E)) + if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E)) if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) || isa<ParmVarDecl>(SizeOfPack->getPack())) return SizeOfPack->getPack(); @@ -2972,21 +3046,21 @@ static Decl *getDeclFromExpr(Stmt *E) { return 0; } -static SourceLocation getLocationFromExpr(Expr *E) { - if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) +static SourceLocation getLocationFromExpr(const Expr *E) { + if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) return getLocationFromExpr(CE->getSubExpr()); - if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) + if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) return /*FIXME:*/Msg->getLeftLoc(); - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) + if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) return DRE->getLocation(); - if (MemberExpr *Member = dyn_cast<MemberExpr>(E)) + if (const MemberExpr *Member = dyn_cast<MemberExpr>(E)) return Member->getMemberLoc(); - if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E)) + if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E)) return Ivar->getLocation(); - if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E)) + if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E)) return SizeOfPack->getPackLoc(); - if (ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E)) + if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E)) return PropRef->getLocation(); return E->getLocStart(); @@ -3039,169 +3113,169 @@ unsigned clang_visitChildrenWithBlock(CXCursor parent, return clang_visitChildren(parent, visitWithBlock, block); } -static CXString getDeclSpelling(Decl *D) { +static CXString getDeclSpelling(const Decl *D) { if (!D) - return createCXString(""); + return cxstring::createEmpty(); - NamedDecl *ND = dyn_cast<NamedDecl>(D); + const NamedDecl *ND = dyn_cast<NamedDecl>(D); if (!ND) { - if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D)) + if (const ObjCPropertyImplDecl *PropImpl = + dyn_cast<ObjCPropertyImplDecl>(D)) if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl()) - return createCXString(Property->getIdentifier()->getName()); + return cxstring::createDup(Property->getIdentifier()->getName()); - if (ImportDecl *ImportD = dyn_cast<ImportDecl>(D)) + if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D)) if (Module *Mod = ImportD->getImportedModule()) - return createCXString(Mod->getFullModuleName()); + return cxstring::createDup(Mod->getFullModuleName()); - return createCXString(""); + return cxstring::createEmpty(); } - if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) - return createCXString(OMD->getSelector().getAsString()); + if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) + return cxstring::createDup(OMD->getSelector().getAsString()); - if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND)) + if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND)) // No, this isn't the same as the code below. getIdentifier() is non-virtual // and returns different names. NamedDecl returns the class name and // ObjCCategoryImplDecl returns the category name. - return createCXString(CIMP->getIdentifier()->getNameStart()); + return cxstring::createRef(CIMP->getIdentifier()->getNameStart()); if (isa<UsingDirectiveDecl>(D)) - return createCXString(""); + return cxstring::createEmpty(); SmallString<1024> S; llvm::raw_svector_ostream os(S); ND->printName(os); - return createCXString(os.str()); + return cxstring::createDup(os.str()); } CXString clang_getCursorSpelling(CXCursor C) { if (clang_isTranslationUnit(C.kind)) - return clang_getTranslationUnitSpelling( - static_cast<CXTranslationUnit>(C.data[2])); + return clang_getTranslationUnitSpelling(getCursorTU(C)); if (clang_isReference(C.kind)) { switch (C.kind) { case CXCursor_ObjCSuperClassRef: { - ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first; - return createCXString(Super->getIdentifier()->getNameStart()); + const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first; + return cxstring::createRef(Super->getIdentifier()->getNameStart()); } case CXCursor_ObjCClassRef: { - ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; - return createCXString(Class->getIdentifier()->getNameStart()); + const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; + return cxstring::createRef(Class->getIdentifier()->getNameStart()); } case CXCursor_ObjCProtocolRef: { - ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first; + const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first; assert(OID && "getCursorSpelling(): Missing protocol decl"); - return createCXString(OID->getIdentifier()->getNameStart()); + return cxstring::createRef(OID->getIdentifier()->getNameStart()); } case CXCursor_CXXBaseSpecifier: { - CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); - return createCXString(B->getType().getAsString()); + const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); + return cxstring::createDup(B->getType().getAsString()); } case CXCursor_TypeRef: { - TypeDecl *Type = getCursorTypeRef(C).first; + const TypeDecl *Type = getCursorTypeRef(C).first; assert(Type && "Missing type decl"); - return createCXString(getCursorContext(C).getTypeDeclType(Type). + return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type). getAsString()); } case CXCursor_TemplateRef: { - TemplateDecl *Template = getCursorTemplateRef(C).first; + const TemplateDecl *Template = getCursorTemplateRef(C).first; assert(Template && "Missing template decl"); - return createCXString(Template->getNameAsString()); + return cxstring::createDup(Template->getNameAsString()); } case CXCursor_NamespaceRef: { - NamedDecl *NS = getCursorNamespaceRef(C).first; + const NamedDecl *NS = getCursorNamespaceRef(C).first; assert(NS && "Missing namespace decl"); - return createCXString(NS->getNameAsString()); + return cxstring::createDup(NS->getNameAsString()); } case CXCursor_MemberRef: { - FieldDecl *Field = getCursorMemberRef(C).first; + const FieldDecl *Field = getCursorMemberRef(C).first; assert(Field && "Missing member decl"); - return createCXString(Field->getNameAsString()); + return cxstring::createDup(Field->getNameAsString()); } case CXCursor_LabelRef: { - LabelStmt *Label = getCursorLabelRef(C).first; + const LabelStmt *Label = getCursorLabelRef(C).first; assert(Label && "Missing label"); - return createCXString(Label->getName()); + return cxstring::createRef(Label->getName()); } case CXCursor_OverloadedDeclRef: { OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first; - if (Decl *D = Storage.dyn_cast<Decl *>()) { - if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) - return createCXString(ND->getNameAsString()); - return createCXString(""); + if (const Decl *D = Storage.dyn_cast<const Decl *>()) { + if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) + return cxstring::createDup(ND->getNameAsString()); + return cxstring::createEmpty(); } - if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) - return createCXString(E->getName().getAsString()); + if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>()) + return cxstring::createDup(E->getName().getAsString()); OverloadedTemplateStorage *Ovl = Storage.get<OverloadedTemplateStorage*>(); if (Ovl->size() == 0) - return createCXString(""); - return createCXString((*Ovl->begin())->getNameAsString()); + return cxstring::createEmpty(); + return cxstring::createDup((*Ovl->begin())->getNameAsString()); } case CXCursor_VariableRef: { - VarDecl *Var = getCursorVariableRef(C).first; + const VarDecl *Var = getCursorVariableRef(C).first; assert(Var && "Missing variable decl"); - return createCXString(Var->getNameAsString()); + return cxstring::createDup(Var->getNameAsString()); } default: - return createCXString("<not implemented>"); + return cxstring::createRef("<not implemented>"); } } if (clang_isExpression(C.kind)) { - Decl *D = getDeclFromExpr(getCursorExpr(C)); + const Decl *D = getDeclFromExpr(getCursorExpr(C)); if (D) return getDeclSpelling(D); - return createCXString(""); + return cxstring::createEmpty(); } if (clang_isStatement(C.kind)) { - Stmt *S = getCursorStmt(C); - if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) - return createCXString(Label->getName()); + const Stmt *S = getCursorStmt(C); + if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) + return cxstring::createRef(Label->getName()); - return createCXString(""); + return cxstring::createEmpty(); } if (C.kind == CXCursor_MacroExpansion) - return createCXString(getCursorMacroExpansion(C)->getName() + return cxstring::createRef(getCursorMacroExpansion(C).getName() ->getNameStart()); if (C.kind == CXCursor_MacroDefinition) - return createCXString(getCursorMacroDefinition(C)->getName() + return cxstring::createRef(getCursorMacroDefinition(C)->getName() ->getNameStart()); if (C.kind == CXCursor_InclusionDirective) - return createCXString(getCursorInclusionDirective(C)->getFileName()); + return cxstring::createDup(getCursorInclusionDirective(C)->getFileName()); if (clang_isDeclaration(C.kind)) return getDeclSpelling(getCursorDecl(C)); if (C.kind == CXCursor_AnnotateAttr) { - AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C)); - return createCXString(AA->getAnnotation()); + const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C)); + return cxstring::createDup(AA->getAnnotation()); } if (C.kind == CXCursor_AsmLabelAttr) { - AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C)); - return createCXString(AA->getLabel()); + const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C)); + return cxstring::createDup(AA->getLabel()); } - return createCXString(""); + return cxstring::createEmpty(); } CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, @@ -3213,8 +3287,8 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, ASTContext &Ctx = getCursorContext(C); if (clang_isStatement(C.kind)) { - Stmt *S = getCursorStmt(C); - if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) { + const Stmt *S = getCursorStmt(C); + if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) { if (pieceIndex > 0) return clang_getNullRange(); return cxloc::translateSourceRange(Ctx, Label->getIdentLoc()); @@ -3224,7 +3298,7 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, } if (C.kind == CXCursor_ObjCMessageExpr) { - if (ObjCMessageExpr * + if (const ObjCMessageExpr * ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) { if (pieceIndex >= ME->getNumSelectorLocs()) return clang_getNullRange(); @@ -3234,7 +3308,7 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, if (C.kind == CXCursor_ObjCInstanceMethodDecl || C.kind == CXCursor_ObjCClassMethodDecl) { - if (ObjCMethodDecl * + if (const ObjCMethodDecl * MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) { if (pieceIndex >= MD->getNumSelectorLocs()) return clang_getNullRange(); @@ -3246,10 +3320,10 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, C.kind == CXCursor_ObjCCategoryImplDecl) { if (pieceIndex > 0) return clang_getNullRange(); - if (ObjCCategoryDecl * + if (const ObjCCategoryDecl * CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C))) return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc()); - if (ObjCCategoryImplDecl * + if (const ObjCCategoryImplDecl * CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C))) return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc()); } @@ -3257,7 +3331,8 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, if (C.kind == CXCursor_ModuleImportDecl) { if (pieceIndex > 0) return clang_getNullRange(); - if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) { + if (const ImportDecl *ImportD = + dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) { ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs(); if (!Locs.empty()) return cxloc::translateSourceRange(Ctx, @@ -3289,15 +3364,15 @@ CXString clang_getCursorDisplayName(CXCursor C) { if (!clang_isDeclaration(C.kind)) return clang_getCursorSpelling(C); - Decl *D = getCursorDecl(C); + const Decl *D = getCursorDecl(C); if (!D) - return createCXString(""); + return cxstring::createEmpty(); PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy(); - if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) + if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) D = FunTmpl->getTemplatedDecl(); - if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { + if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { SmallString<64> Str; llvm::raw_svector_ostream OS(Str); OS << *Function; @@ -3316,10 +3391,10 @@ CXString clang_getCursorDisplayName(CXCursor C) { OS << "..."; } OS << ")"; - return createCXString(OS.str()); + return cxstring::createDup(OS.str()); } - if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) { + if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) { SmallString<64> Str; llvm::raw_svector_ostream OS(Str); OS << *ClassTemplate; @@ -3347,23 +3422,23 @@ CXString clang_getCursorDisplayName(CXCursor C) { } OS << ">"; - return createCXString(OS.str()); + return cxstring::createDup(OS.str()); } - if (ClassTemplateSpecializationDecl *ClassSpec + if (const ClassTemplateSpecializationDecl *ClassSpec = dyn_cast<ClassTemplateSpecializationDecl>(D)) { // If the type was explicitly written, use that. if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten()) - return createCXString(TSInfo->getType().getAsString(Policy)); + return cxstring::createDup(TSInfo->getType().getAsString(Policy)); - SmallString<64> Str; + SmallString<128> Str; llvm::raw_svector_ostream OS(Str); OS << *ClassSpec; - OS << TemplateSpecializationType::PrintTemplateArgumentList( + TemplateSpecializationType::PrintTemplateArgumentList(OS, ClassSpec->getTemplateArgs().data(), ClassSpec->getTemplateArgs().size(), Policy); - return createCXString(OS.str()); + return cxstring::createDup(OS.str()); } return clang_getCursorSpelling(C); @@ -3372,297 +3447,297 @@ CXString clang_getCursorDisplayName(CXCursor C) { CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { switch (Kind) { case CXCursor_FunctionDecl: - return createCXString("FunctionDecl"); + return cxstring::createRef("FunctionDecl"); case CXCursor_TypedefDecl: - return createCXString("TypedefDecl"); + return cxstring::createRef("TypedefDecl"); case CXCursor_EnumDecl: - return createCXString("EnumDecl"); + return cxstring::createRef("EnumDecl"); case CXCursor_EnumConstantDecl: - return createCXString("EnumConstantDecl"); + return cxstring::createRef("EnumConstantDecl"); case CXCursor_StructDecl: - return createCXString("StructDecl"); + return cxstring::createRef("StructDecl"); case CXCursor_UnionDecl: - return createCXString("UnionDecl"); + return cxstring::createRef("UnionDecl"); case CXCursor_ClassDecl: - return createCXString("ClassDecl"); + return cxstring::createRef("ClassDecl"); case CXCursor_FieldDecl: - return createCXString("FieldDecl"); + return cxstring::createRef("FieldDecl"); case CXCursor_VarDecl: - return createCXString("VarDecl"); + return cxstring::createRef("VarDecl"); case CXCursor_ParmDecl: - return createCXString("ParmDecl"); + return cxstring::createRef("ParmDecl"); case CXCursor_ObjCInterfaceDecl: - return createCXString("ObjCInterfaceDecl"); + return cxstring::createRef("ObjCInterfaceDecl"); case CXCursor_ObjCCategoryDecl: - return createCXString("ObjCCategoryDecl"); + return cxstring::createRef("ObjCCategoryDecl"); case CXCursor_ObjCProtocolDecl: - return createCXString("ObjCProtocolDecl"); + return cxstring::createRef("ObjCProtocolDecl"); case CXCursor_ObjCPropertyDecl: - return createCXString("ObjCPropertyDecl"); + return cxstring::createRef("ObjCPropertyDecl"); case CXCursor_ObjCIvarDecl: - return createCXString("ObjCIvarDecl"); + return cxstring::createRef("ObjCIvarDecl"); case CXCursor_ObjCInstanceMethodDecl: - return createCXString("ObjCInstanceMethodDecl"); + return cxstring::createRef("ObjCInstanceMethodDecl"); case CXCursor_ObjCClassMethodDecl: - return createCXString("ObjCClassMethodDecl"); + return cxstring::createRef("ObjCClassMethodDecl"); case CXCursor_ObjCImplementationDecl: - return createCXString("ObjCImplementationDecl"); + return cxstring::createRef("ObjCImplementationDecl"); case CXCursor_ObjCCategoryImplDecl: - return createCXString("ObjCCategoryImplDecl"); + return cxstring::createRef("ObjCCategoryImplDecl"); case CXCursor_CXXMethod: - return createCXString("CXXMethod"); + return cxstring::createRef("CXXMethod"); case CXCursor_UnexposedDecl: - return createCXString("UnexposedDecl"); + return cxstring::createRef("UnexposedDecl"); case CXCursor_ObjCSuperClassRef: - return createCXString("ObjCSuperClassRef"); + return cxstring::createRef("ObjCSuperClassRef"); case CXCursor_ObjCProtocolRef: - return createCXString("ObjCProtocolRef"); + return cxstring::createRef("ObjCProtocolRef"); case CXCursor_ObjCClassRef: - return createCXString("ObjCClassRef"); + return cxstring::createRef("ObjCClassRef"); case CXCursor_TypeRef: - return createCXString("TypeRef"); + return cxstring::createRef("TypeRef"); case CXCursor_TemplateRef: - return createCXString("TemplateRef"); + return cxstring::createRef("TemplateRef"); case CXCursor_NamespaceRef: - return createCXString("NamespaceRef"); + return cxstring::createRef("NamespaceRef"); case CXCursor_MemberRef: - return createCXString("MemberRef"); + return cxstring::createRef("MemberRef"); case CXCursor_LabelRef: - return createCXString("LabelRef"); + return cxstring::createRef("LabelRef"); case CXCursor_OverloadedDeclRef: - return createCXString("OverloadedDeclRef"); + return cxstring::createRef("OverloadedDeclRef"); case CXCursor_VariableRef: - return createCXString("VariableRef"); + return cxstring::createRef("VariableRef"); case CXCursor_IntegerLiteral: - return createCXString("IntegerLiteral"); + return cxstring::createRef("IntegerLiteral"); case CXCursor_FloatingLiteral: - return createCXString("FloatingLiteral"); + return cxstring::createRef("FloatingLiteral"); case CXCursor_ImaginaryLiteral: - return createCXString("ImaginaryLiteral"); + return cxstring::createRef("ImaginaryLiteral"); case CXCursor_StringLiteral: - return createCXString("StringLiteral"); + return cxstring::createRef("StringLiteral"); case CXCursor_CharacterLiteral: - return createCXString("CharacterLiteral"); + return cxstring::createRef("CharacterLiteral"); case CXCursor_ParenExpr: - return createCXString("ParenExpr"); + return cxstring::createRef("ParenExpr"); case CXCursor_UnaryOperator: - return createCXString("UnaryOperator"); + return cxstring::createRef("UnaryOperator"); case CXCursor_ArraySubscriptExpr: - return createCXString("ArraySubscriptExpr"); + return cxstring::createRef("ArraySubscriptExpr"); case CXCursor_BinaryOperator: - return createCXString("BinaryOperator"); + return cxstring::createRef("BinaryOperator"); case CXCursor_CompoundAssignOperator: - return createCXString("CompoundAssignOperator"); + return cxstring::createRef("CompoundAssignOperator"); case CXCursor_ConditionalOperator: - return createCXString("ConditionalOperator"); + return cxstring::createRef("ConditionalOperator"); case CXCursor_CStyleCastExpr: - return createCXString("CStyleCastExpr"); + return cxstring::createRef("CStyleCastExpr"); case CXCursor_CompoundLiteralExpr: - return createCXString("CompoundLiteralExpr"); + return cxstring::createRef("CompoundLiteralExpr"); case CXCursor_InitListExpr: - return createCXString("InitListExpr"); + return cxstring::createRef("InitListExpr"); case CXCursor_AddrLabelExpr: - return createCXString("AddrLabelExpr"); + return cxstring::createRef("AddrLabelExpr"); case CXCursor_StmtExpr: - return createCXString("StmtExpr"); + return cxstring::createRef("StmtExpr"); case CXCursor_GenericSelectionExpr: - return createCXString("GenericSelectionExpr"); + return cxstring::createRef("GenericSelectionExpr"); case CXCursor_GNUNullExpr: - return createCXString("GNUNullExpr"); + return cxstring::createRef("GNUNullExpr"); case CXCursor_CXXStaticCastExpr: - return createCXString("CXXStaticCastExpr"); + return cxstring::createRef("CXXStaticCastExpr"); case CXCursor_CXXDynamicCastExpr: - return createCXString("CXXDynamicCastExpr"); + return cxstring::createRef("CXXDynamicCastExpr"); case CXCursor_CXXReinterpretCastExpr: - return createCXString("CXXReinterpretCastExpr"); + return cxstring::createRef("CXXReinterpretCastExpr"); case CXCursor_CXXConstCastExpr: - return createCXString("CXXConstCastExpr"); + return cxstring::createRef("CXXConstCastExpr"); case CXCursor_CXXFunctionalCastExpr: - return createCXString("CXXFunctionalCastExpr"); + return cxstring::createRef("CXXFunctionalCastExpr"); case CXCursor_CXXTypeidExpr: - return createCXString("CXXTypeidExpr"); + return cxstring::createRef("CXXTypeidExpr"); case CXCursor_CXXBoolLiteralExpr: - return createCXString("CXXBoolLiteralExpr"); + return cxstring::createRef("CXXBoolLiteralExpr"); case CXCursor_CXXNullPtrLiteralExpr: - return createCXString("CXXNullPtrLiteralExpr"); + return cxstring::createRef("CXXNullPtrLiteralExpr"); case CXCursor_CXXThisExpr: - return createCXString("CXXThisExpr"); + return cxstring::createRef("CXXThisExpr"); case CXCursor_CXXThrowExpr: - return createCXString("CXXThrowExpr"); + return cxstring::createRef("CXXThrowExpr"); case CXCursor_CXXNewExpr: - return createCXString("CXXNewExpr"); + return cxstring::createRef("CXXNewExpr"); case CXCursor_CXXDeleteExpr: - return createCXString("CXXDeleteExpr"); + return cxstring::createRef("CXXDeleteExpr"); case CXCursor_UnaryExpr: - return createCXString("UnaryExpr"); + return cxstring::createRef("UnaryExpr"); case CXCursor_ObjCStringLiteral: - return createCXString("ObjCStringLiteral"); + return cxstring::createRef("ObjCStringLiteral"); case CXCursor_ObjCBoolLiteralExpr: - return createCXString("ObjCBoolLiteralExpr"); + return cxstring::createRef("ObjCBoolLiteralExpr"); case CXCursor_ObjCEncodeExpr: - return createCXString("ObjCEncodeExpr"); + return cxstring::createRef("ObjCEncodeExpr"); case CXCursor_ObjCSelectorExpr: - return createCXString("ObjCSelectorExpr"); + return cxstring::createRef("ObjCSelectorExpr"); case CXCursor_ObjCProtocolExpr: - return createCXString("ObjCProtocolExpr"); + return cxstring::createRef("ObjCProtocolExpr"); case CXCursor_ObjCBridgedCastExpr: - return createCXString("ObjCBridgedCastExpr"); + return cxstring::createRef("ObjCBridgedCastExpr"); case CXCursor_BlockExpr: - return createCXString("BlockExpr"); + return cxstring::createRef("BlockExpr"); case CXCursor_PackExpansionExpr: - return createCXString("PackExpansionExpr"); + return cxstring::createRef("PackExpansionExpr"); case CXCursor_SizeOfPackExpr: - return createCXString("SizeOfPackExpr"); + return cxstring::createRef("SizeOfPackExpr"); case CXCursor_LambdaExpr: - return createCXString("LambdaExpr"); + return cxstring::createRef("LambdaExpr"); case CXCursor_UnexposedExpr: - return createCXString("UnexposedExpr"); + return cxstring::createRef("UnexposedExpr"); case CXCursor_DeclRefExpr: - return createCXString("DeclRefExpr"); + return cxstring::createRef("DeclRefExpr"); case CXCursor_MemberRefExpr: - return createCXString("MemberRefExpr"); + return cxstring::createRef("MemberRefExpr"); case CXCursor_CallExpr: - return createCXString("CallExpr"); + return cxstring::createRef("CallExpr"); case CXCursor_ObjCMessageExpr: - return createCXString("ObjCMessageExpr"); + return cxstring::createRef("ObjCMessageExpr"); case CXCursor_UnexposedStmt: - return createCXString("UnexposedStmt"); + return cxstring::createRef("UnexposedStmt"); case CXCursor_DeclStmt: - return createCXString("DeclStmt"); + return cxstring::createRef("DeclStmt"); case CXCursor_LabelStmt: - return createCXString("LabelStmt"); + return cxstring::createRef("LabelStmt"); case CXCursor_CompoundStmt: - return createCXString("CompoundStmt"); + return cxstring::createRef("CompoundStmt"); case CXCursor_CaseStmt: - return createCXString("CaseStmt"); + return cxstring::createRef("CaseStmt"); case CXCursor_DefaultStmt: - return createCXString("DefaultStmt"); + return cxstring::createRef("DefaultStmt"); case CXCursor_IfStmt: - return createCXString("IfStmt"); + return cxstring::createRef("IfStmt"); case CXCursor_SwitchStmt: - return createCXString("SwitchStmt"); + return cxstring::createRef("SwitchStmt"); case CXCursor_WhileStmt: - return createCXString("WhileStmt"); + return cxstring::createRef("WhileStmt"); case CXCursor_DoStmt: - return createCXString("DoStmt"); + return cxstring::createRef("DoStmt"); case CXCursor_ForStmt: - return createCXString("ForStmt"); + return cxstring::createRef("ForStmt"); case CXCursor_GotoStmt: - return createCXString("GotoStmt"); + return cxstring::createRef("GotoStmt"); case CXCursor_IndirectGotoStmt: - return createCXString("IndirectGotoStmt"); + return cxstring::createRef("IndirectGotoStmt"); case CXCursor_ContinueStmt: - return createCXString("ContinueStmt"); + return cxstring::createRef("ContinueStmt"); case CXCursor_BreakStmt: - return createCXString("BreakStmt"); + return cxstring::createRef("BreakStmt"); case CXCursor_ReturnStmt: - return createCXString("ReturnStmt"); + return cxstring::createRef("ReturnStmt"); case CXCursor_GCCAsmStmt: - return createCXString("GCCAsmStmt"); + return cxstring::createRef("GCCAsmStmt"); case CXCursor_MSAsmStmt: - return createCXString("MSAsmStmt"); + return cxstring::createRef("MSAsmStmt"); case CXCursor_ObjCAtTryStmt: - return createCXString("ObjCAtTryStmt"); + return cxstring::createRef("ObjCAtTryStmt"); case CXCursor_ObjCAtCatchStmt: - return createCXString("ObjCAtCatchStmt"); + return cxstring::createRef("ObjCAtCatchStmt"); case CXCursor_ObjCAtFinallyStmt: - return createCXString("ObjCAtFinallyStmt"); + return cxstring::createRef("ObjCAtFinallyStmt"); case CXCursor_ObjCAtThrowStmt: - return createCXString("ObjCAtThrowStmt"); + return cxstring::createRef("ObjCAtThrowStmt"); case CXCursor_ObjCAtSynchronizedStmt: - return createCXString("ObjCAtSynchronizedStmt"); + return cxstring::createRef("ObjCAtSynchronizedStmt"); case CXCursor_ObjCAutoreleasePoolStmt: - return createCXString("ObjCAutoreleasePoolStmt"); + return cxstring::createRef("ObjCAutoreleasePoolStmt"); case CXCursor_ObjCForCollectionStmt: - return createCXString("ObjCForCollectionStmt"); + return cxstring::createRef("ObjCForCollectionStmt"); case CXCursor_CXXCatchStmt: - return createCXString("CXXCatchStmt"); + return cxstring::createRef("CXXCatchStmt"); case CXCursor_CXXTryStmt: - return createCXString("CXXTryStmt"); + return cxstring::createRef("CXXTryStmt"); case CXCursor_CXXForRangeStmt: - return createCXString("CXXForRangeStmt"); + return cxstring::createRef("CXXForRangeStmt"); case CXCursor_SEHTryStmt: - return createCXString("SEHTryStmt"); + return cxstring::createRef("SEHTryStmt"); case CXCursor_SEHExceptStmt: - return createCXString("SEHExceptStmt"); + return cxstring::createRef("SEHExceptStmt"); case CXCursor_SEHFinallyStmt: - return createCXString("SEHFinallyStmt"); + return cxstring::createRef("SEHFinallyStmt"); case CXCursor_NullStmt: - return createCXString("NullStmt"); + return cxstring::createRef("NullStmt"); case CXCursor_InvalidFile: - return createCXString("InvalidFile"); + return cxstring::createRef("InvalidFile"); case CXCursor_InvalidCode: - return createCXString("InvalidCode"); + return cxstring::createRef("InvalidCode"); case CXCursor_NoDeclFound: - return createCXString("NoDeclFound"); + return cxstring::createRef("NoDeclFound"); case CXCursor_NotImplemented: - return createCXString("NotImplemented"); + return cxstring::createRef("NotImplemented"); case CXCursor_TranslationUnit: - return createCXString("TranslationUnit"); + return cxstring::createRef("TranslationUnit"); case CXCursor_UnexposedAttr: - return createCXString("UnexposedAttr"); + return cxstring::createRef("UnexposedAttr"); case CXCursor_IBActionAttr: - return createCXString("attribute(ibaction)"); + return cxstring::createRef("attribute(ibaction)"); case CXCursor_IBOutletAttr: - return createCXString("attribute(iboutlet)"); + return cxstring::createRef("attribute(iboutlet)"); case CXCursor_IBOutletCollectionAttr: - return createCXString("attribute(iboutletcollection)"); + return cxstring::createRef("attribute(iboutletcollection)"); case CXCursor_CXXFinalAttr: - return createCXString("attribute(final)"); + return cxstring::createRef("attribute(final)"); case CXCursor_CXXOverrideAttr: - return createCXString("attribute(override)"); + return cxstring::createRef("attribute(override)"); case CXCursor_AnnotateAttr: - return createCXString("attribute(annotate)"); + return cxstring::createRef("attribute(annotate)"); case CXCursor_AsmLabelAttr: - return createCXString("asm label"); + return cxstring::createRef("asm label"); case CXCursor_PreprocessingDirective: - return createCXString("preprocessing directive"); + return cxstring::createRef("preprocessing directive"); case CXCursor_MacroDefinition: - return createCXString("macro definition"); + return cxstring::createRef("macro definition"); case CXCursor_MacroExpansion: - return createCXString("macro expansion"); + return cxstring::createRef("macro expansion"); case CXCursor_InclusionDirective: - return createCXString("inclusion directive"); + return cxstring::createRef("inclusion directive"); case CXCursor_Namespace: - return createCXString("Namespace"); + return cxstring::createRef("Namespace"); case CXCursor_LinkageSpec: - return createCXString("LinkageSpec"); + return cxstring::createRef("LinkageSpec"); case CXCursor_CXXBaseSpecifier: - return createCXString("C++ base class specifier"); + return cxstring::createRef("C++ base class specifier"); case CXCursor_Constructor: - return createCXString("CXXConstructor"); + return cxstring::createRef("CXXConstructor"); case CXCursor_Destructor: - return createCXString("CXXDestructor"); + return cxstring::createRef("CXXDestructor"); case CXCursor_ConversionFunction: - return createCXString("CXXConversion"); + return cxstring::createRef("CXXConversion"); case CXCursor_TemplateTypeParameter: - return createCXString("TemplateTypeParameter"); + return cxstring::createRef("TemplateTypeParameter"); case CXCursor_NonTypeTemplateParameter: - return createCXString("NonTypeTemplateParameter"); + return cxstring::createRef("NonTypeTemplateParameter"); case CXCursor_TemplateTemplateParameter: - return createCXString("TemplateTemplateParameter"); + return cxstring::createRef("TemplateTemplateParameter"); case CXCursor_FunctionTemplate: - return createCXString("FunctionTemplate"); + return cxstring::createRef("FunctionTemplate"); case CXCursor_ClassTemplate: - return createCXString("ClassTemplate"); + return cxstring::createRef("ClassTemplate"); case CXCursor_ClassTemplatePartialSpecialization: - return createCXString("ClassTemplatePartialSpecialization"); + return cxstring::createRef("ClassTemplatePartialSpecialization"); case CXCursor_NamespaceAlias: - return createCXString("NamespaceAlias"); + return cxstring::createRef("NamespaceAlias"); case CXCursor_UsingDirective: - return createCXString("UsingDirective"); + return cxstring::createRef("UsingDirective"); case CXCursor_UsingDeclaration: - return createCXString("UsingDeclaration"); + return cxstring::createRef("UsingDeclaration"); case CXCursor_TypeAliasDecl: - return createCXString("TypeAliasDecl"); + return cxstring::createRef("TypeAliasDecl"); case CXCursor_ObjCSynthesizeDecl: - return createCXString("ObjCSynthesizeDecl"); + return cxstring::createRef("ObjCSynthesizeDecl"); case CXCursor_ObjCDynamicDecl: - return createCXString("ObjCDynamicDecl"); + return cxstring::createRef("ObjCDynamicDecl"); case CXCursor_CXXAccessSpecifier: - return createCXString("CXXAccessSpecifier"); + return cxstring::createRef("CXXAccessSpecifier"); case CXCursor_ModuleImportDecl: - return createCXString("ModuleImport"); + return cxstring::createRef("ModuleImport"); } llvm_unreachable("Unhandled CXCursorKind"); @@ -3697,12 +3772,12 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, if (clang_isDeclaration(cursor.kind)) { // Avoid having the implicit methods override the property decls. - if (ObjCMethodDecl *MD + if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) { if (MD->isImplicit()) return CXChildVisit_Break; - } else if (ObjCInterfaceDecl *ID + } else if (const ObjCInterfaceDecl *ID = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) { // Check that when we have multiple @class references in the same line, // that later ones do not override the previous ones. @@ -3712,7 +3787,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, // 'Foo' even though the cursor location was at 'Foo'. if (BestCursor->kind == CXCursor_ObjCInterfaceDecl || BestCursor->kind == CXCursor_ObjCClassRef) - if (ObjCInterfaceDecl *PrevID + if (const ObjCInterfaceDecl *PrevID = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){ if (PrevID != ID && !PrevID->isThisDeclarationADefinition() && @@ -3720,7 +3795,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, return CXChildVisit_Break; } - } else if (DeclaratorDecl *DD + } else if (const DeclaratorDecl *DD = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) { SourceLocation StartLoc = DD->getSourceRange().getBegin(); // Check that when we have multiple declarators in the same line, @@ -3733,7 +3808,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, return CXChildVisit_Break; Data->VisitedDeclaratorDeclStartLoc = StartLoc; - } else if (ObjCPropertyImplDecl *PropImp + } else if (const ObjCPropertyImplDecl *PropImp = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) { (void)PropImp; // Check that when we have multiple @synthesize in the same line, @@ -3750,7 +3825,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, if (clang_isExpression(cursor.kind) && clang_isDeclaration(BestCursor->kind)) { - if (Decl *D = getCursorDecl(*BestCursor)) { + if (const Decl *D = getCursorDecl(*BestCursor)) { // Avoid having the cursor of an expression replace the declaration cursor // when the expression source range overlaps the declaration range. // This can happen for C++ constructor expressions whose range generally @@ -3782,14 +3857,13 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { if (!TU) return clang_getNullCursor(); - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); ASTUnit::ConcurrencyCheck Check(*CXXUnit); SourceLocation SLoc = cxloc::translateSourceLocation(Loc); CXCursor Result = cxcursor::getCursor(TU, SLoc); - bool Logging = getenv("LIBCLANG_LOGGING"); - if (Logging) { + LOG_FUNC_SECTION { CXFile SearchFile; unsigned SearchLine, SearchColumn; CXFile ResultFile; @@ -3798,18 +3872,19 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : ""; CXSourceLocation ResultLoc = clang_getCursorLocation(Result); - clang_getExpansionLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0); - clang_getExpansionLocation(ResultLoc, &ResultFile, &ResultLine, + clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0); + clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn, 0); SearchFileName = clang_getFileName(SearchFile); ResultFileName = clang_getFileName(ResultFile); KindSpelling = clang_getCursorKindSpelling(Result.kind); USR = clang_getCursorUSR(Result); - fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n", - clang_getCString(SearchFileName), SearchLine, SearchColumn, - clang_getCString(KindSpelling), - clang_getCString(ResultFileName), ResultLine, ResultColumn, - clang_getCString(USR), IsDef); + *Log << llvm::format("(%s:%d:%d) = %s", + clang_getCString(SearchFileName), SearchLine, SearchColumn, + clang_getCString(KindSpelling)) + << llvm::format("(%s:%d:%d):%s%s", + clang_getCString(ResultFileName), ResultLine, ResultColumn, + clang_getCString(USR), IsDef); clang_disposeString(SearchFileName); clang_disposeString(ResultFileName); clang_disposeString(KindSpelling); @@ -3822,13 +3897,13 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { = clang_getCursorKindSpelling(Definition.kind); CXFile DefinitionFile; unsigned DefinitionLine, DefinitionColumn; - clang_getExpansionLocation(DefinitionLoc, &DefinitionFile, + clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine, &DefinitionColumn, 0); CXString DefinitionFileName = clang_getFileName(DefinitionFile); - fprintf(stderr, " -> %s(%s:%d:%d)\n", - clang_getCString(DefinitionKindSpelling), - clang_getCString(DefinitionFileName), - DefinitionLine, DefinitionColumn); + *Log << llvm::format(" -> %s(%s:%d:%d)", + clang_getCString(DefinitionKindSpelling), + clang_getCString(DefinitionFileName), + DefinitionLine, DefinitionColumn); clang_disposeString(DefinitionFileName); clang_disposeString(DefinitionKindSpelling); } @@ -3842,6 +3917,18 @@ CXCursor clang_getNullCursor(void) { } unsigned clang_equalCursors(CXCursor X, CXCursor Y) { + // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we + // can't set consistently. For example, when visiting a DeclStmt we will set + // it but we don't set it on the result of clang_getCursorDefinition for + // a reference of the same declaration. + // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works + // when visiting a DeclStmt currently, the AST should be enhanced to be able + // to provide that kind of info. + if (clang_isDeclaration(X.kind)) + X.data[1] = 0; + if (clang_isDeclaration(Y.kind)) + Y.data[1] = 0; + return X == Y; } @@ -3850,7 +3937,7 @@ unsigned clang_hashCursor(CXCursor C) { if (clang_isExpression(C.kind) || clang_isStatement(C.kind)) Index = 1; - return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue( + return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue( std::make_pair(C.kind, C.data[Index])); } @@ -3907,50 +3994,51 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { if (clang_isReference(C.kind)) { switch (C.kind) { case CXCursor_ObjCSuperClassRef: { - std::pair<ObjCInterfaceDecl *, SourceLocation> P + std::pair<const ObjCInterfaceDecl *, SourceLocation> P = getCursorObjCSuperClassRef(C); return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); } case CXCursor_ObjCProtocolRef: { - std::pair<ObjCProtocolDecl *, SourceLocation> P + std::pair<const ObjCProtocolDecl *, SourceLocation> P = getCursorObjCProtocolRef(C); return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); } case CXCursor_ObjCClassRef: { - std::pair<ObjCInterfaceDecl *, SourceLocation> P + std::pair<const ObjCInterfaceDecl *, SourceLocation> P = getCursorObjCClassRef(C); return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); } case CXCursor_TypeRef: { - std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C); + std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C); return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); } case CXCursor_TemplateRef: { - std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C); + std::pair<const TemplateDecl *, SourceLocation> P = + getCursorTemplateRef(C); return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); } case CXCursor_NamespaceRef: { - std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C); + std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C); return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); } case CXCursor_MemberRef: { - std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C); + std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C); return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); } case CXCursor_VariableRef: { - std::pair<VarDecl *, SourceLocation> P = getCursorVariableRef(C); + std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C); return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); } case CXCursor_CXXBaseSpecifier: { - CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C); + const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C); if (!BaseSpec) return clang_getNullLocation(); @@ -3963,7 +4051,7 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { } case CXCursor_LabelRef: { - std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C); + std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C); return cxloc::translateSourceLocation(getCursorContext(C), P.second); } @@ -3992,7 +4080,7 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { if (C.kind == CXCursor_MacroExpansion) { SourceLocation L - = cxcursor::getCursorMacroExpansion(C)->getSourceRange().getBegin(); + = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin(); return cxloc::translateSourceLocation(getCursorContext(C), L); } @@ -4010,7 +4098,7 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { if (!clang_isDeclaration(C.kind)) return clang_getNullLocation(); - Decl *D = getCursorDecl(C); + const Decl *D = getCursorDecl(C); if (!D) return clang_getNullLocation(); @@ -4020,13 +4108,13 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { // ranges when accounting for the type-specifier. We use context // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, // and if so, whether it is the first decl. - if (VarDecl *VD = dyn_cast<VarDecl>(D)) { + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { if (!cxcursor::isFirstInDeclGroup(C)) Loc = VD->getLocation(); } // For ObjC methods, give the start location of the method name. - if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) + if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) Loc = MD->getSelectorStartLoc(); return cxloc::translateSourceLocation(getCursorContext(C), Loc); @@ -4042,7 +4130,7 @@ CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) { if (SLoc.isInvalid()) return clang_getNullCursor(); - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); // Translate the given source location to make it point at the beginning of // the token under the cursor. @@ -4118,7 +4206,7 @@ static SourceRange getRawCursorExtent(CXCursor C) { if (C.kind == CXCursor_MacroExpansion) { ASTUnit *TU = getCursorASTUnit(C); - SourceRange Range = cxcursor::getCursorMacroExpansion(C)->getSourceRange(); + SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange(); return TU->mapRangeFromPreamble(Range); } @@ -4143,7 +4231,7 @@ static SourceRange getRawCursorExtent(CXCursor C) { } if (clang_isDeclaration(C.kind)) { - Decl *D = cxcursor::getCursorDecl(C); + const Decl *D = cxcursor::getCursorDecl(C); if (!D) return SourceRange(); @@ -4153,7 +4241,7 @@ static SourceRange getRawCursorExtent(CXCursor C) { // ranges when accounting for the type-specifier. We use context // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, // and if so, whether it is the first decl. - if (VarDecl *VD = dyn_cast<VarDecl>(D)) { + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { if (!cxcursor::isFirstInDeclGroup(C)) R.setBegin(VD->getLocation()); } @@ -4166,7 +4254,7 @@ static SourceRange getRawCursorExtent(CXCursor C) { /// the decl-specifier-seq for declarations. static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) { if (clang_isDeclaration(C.kind)) { - Decl *D = cxcursor::getCursorDecl(C); + const Decl *D = cxcursor::getCursorDecl(C); if (!D) return SourceRange(); @@ -4178,7 +4266,7 @@ static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) { if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) { if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) StartLoc = TI->getTypeLoc().getLocStart(); - } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) { + } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) { if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo()) StartLoc = TI->getTypeLoc().getLocStart(); } @@ -4192,7 +4280,7 @@ static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) { // ranges when accounting for the type-specifier. We use context // stored in the CXCursor to determine if the VarDecl is in a DeclGroup, // and if so, whether it is the first decl. - if (VarDecl *VD = dyn_cast<VarDecl>(D)) { + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { if (!cxcursor::isFirstInDeclGroup(C)) R.setBegin(VD->getLocation()); } @@ -4219,12 +4307,13 @@ CXCursor clang_getCursorReferenced(CXCursor C) { CXTranslationUnit tu = getCursorTU(C); if (clang_isDeclaration(C.kind)) { - Decl *D = getCursorDecl(C); + const Decl *D = getCursorDecl(C); if (!D) return clang_getNullCursor(); - if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) + if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu); - if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D)) + if (const ObjCPropertyImplDecl *PropImpl = + dyn_cast<ObjCPropertyImplDecl>(D)) if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl()) return MakeCXCursor(Property, tu); @@ -4232,8 +4321,8 @@ CXCursor clang_getCursorReferenced(CXCursor C) { } if (clang_isExpression(C.kind)) { - Expr *E = getCursorExpr(C); - Decl *D = getDeclFromExpr(E); + const Expr *E = getCursorExpr(C); + const Decl *D = getDeclFromExpr(E); if (D) { CXCursor declCursor = MakeCXCursor(D, tu); declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C), @@ -4241,15 +4330,15 @@ CXCursor clang_getCursorReferenced(CXCursor C) { return declCursor; } - if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E)) + if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E)) return MakeCursorOverloadedDeclRef(Ovl, tu); return clang_getNullCursor(); } if (clang_isStatement(C.kind)) { - Stmt *S = getCursorStmt(C); - if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S)) + const Stmt *S = getCursorStmt(C); + if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S)) if (LabelDecl *label = Goto->getLabel()) if (LabelStmt *labelS = label->getStmt()) return MakeCXCursor(labelS, getCursorDecl(C), tu); @@ -4258,7 +4347,7 @@ CXCursor clang_getCursorReferenced(CXCursor C) { } if (C.kind == CXCursor_MacroExpansion) { - if (MacroDefinition *Def = getCursorMacroExpansion(C)->getDefinition()) + if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition()) return MakeMacroDefinitionCursor(Def, tu); } @@ -4270,16 +4359,16 @@ CXCursor clang_getCursorReferenced(CXCursor C) { return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu); case CXCursor_ObjCProtocolRef: { - ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first; - if (ObjCProtocolDecl *Def = Prot->getDefinition()) + const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first; + if (const ObjCProtocolDecl *Def = Prot->getDefinition()) return MakeCXCursor(Def, tu); return MakeCXCursor(Prot, tu); } case CXCursor_ObjCClassRef: { - ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; - if (ObjCInterfaceDecl *Def = Class->getDefinition()) + const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; + if (const ObjCInterfaceDecl *Def = Class->getDefinition()) return MakeCXCursor(Def, tu); return MakeCXCursor(Class, tu); @@ -4298,7 +4387,7 @@ CXCursor clang_getCursorReferenced(CXCursor C) { return MakeCXCursor(getCursorMemberRef(C).first, tu ); case CXCursor_CXXBaseSpecifier: { - CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); + const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu )); } @@ -4306,9 +4395,9 @@ CXCursor clang_getCursorReferenced(CXCursor C) { case CXCursor_LabelRef: // FIXME: We end up faking the "parent" declaration here because we // don't want to make CXCursor larger. - return MakeCXCursor(getCursorLabelRef(C).first, - static_cast<ASTUnit*>(tu->TUData)->getASTContext() - .getTranslationUnitDecl(), + return MakeCXCursor(getCursorLabelRef(C).first, + cxtu::getASTUnit(tu)->getASTContext() + .getTranslationUnitDecl(), tu); case CXCursor_OverloadedDeclRef: @@ -4341,7 +4430,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) { if (!clang_isDeclaration(C.kind)) return clang_getNullCursor(); - Decl *D = getCursorDecl(C); + const Decl *D = getCursorDecl(C); if (!D) return clang_getNullCursor(); @@ -4373,10 +4462,12 @@ CXCursor clang_getCursorDefinition(CXCursor C) { case Decl::Label: // FIXME: Is this right?? case Decl::ClassScopeFunctionSpecialization: case Decl::Import: + case Decl::OMPThreadPrivate: return C; // Declaration kinds that don't make any sense here, but are // nonetheless harmless. + case Decl::Empty: case Decl::TranslationUnit: break; @@ -4408,13 +4499,13 @@ CXCursor clang_getCursorDefinition(CXCursor C) { case Decl::CXXConversion: { const FunctionDecl *Def = 0; if (cast<FunctionDecl>(D)->getBody(Def)) - return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU); + return MakeCXCursor(Def, TU); return clang_getNullCursor(); } case Decl::Var: { // Ask the variable if it has a definition. - if (VarDecl *Def = cast<VarDecl>(D)->getDefinition()) + if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition()) return MakeCXCursor(Def, TU); return clang_getNullCursor(); } @@ -4444,14 +4535,14 @@ CXCursor clang_getCursorDefinition(CXCursor C) { TU)); case Decl::ObjCMethod: { - ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D); + const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D); if (Method->isThisDeclarationADefinition()) return C; // Dig out the method definition in the associated // @implementation, if we have it. // FIXME: The ASTs should make finding the definition easier. - if (ObjCInterfaceDecl *Class + if (const ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) if (ObjCImplementationDecl *ClassImpl = Class->getImplementation()) if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(), @@ -4469,7 +4560,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) { return clang_getNullCursor(); case Decl::ObjCProtocol: - if (ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition()) + if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition()) return MakeCXCursor(Def, TU); return clang_getNullCursor(); @@ -4479,9 +4570,9 @@ CXCursor clang_getCursorDefinition(CXCursor C) { // reference to an Objective-C class, produce the @interface as // the definition; when we were provided with the interface, // produce the @implementation as the definition. - ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D); + const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D); if (WasReference) { - if (ObjCInterfaceDecl *Def = IFace->getDefinition()) + if (const ObjCInterfaceDecl *Def = IFace->getDefinition()) return MakeCXCursor(Def, TU); } else if (ObjCImplementationDecl *Impl = IFace->getImplementation()) return MakeCXCursor(Impl, TU); @@ -4494,9 +4585,9 @@ CXCursor clang_getCursorDefinition(CXCursor C) { return clang_getNullCursor(); case Decl::ObjCCompatibleAlias: - if (ObjCInterfaceDecl *Class + if (const ObjCInterfaceDecl *Class = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface()) - if (ObjCInterfaceDecl *Def = Class->getDefinition()) + if (const ObjCInterfaceDecl *Def = Class->getDefinition()) return MakeCXCursor(Def, TU); return clang_getNullCursor(); @@ -4526,13 +4617,13 @@ CXCursor clang_getCanonicalCursor(CXCursor C) { if (!clang_isDeclaration(C.kind)) return C; - if (Decl *D = getCursorDecl(C)) { - if (ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) + if (const Decl *D = getCursorDecl(C)) { + if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl()) return MakeCXCursor(CatD, getCursorTU(C)); - if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D)) - if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) + if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D)) + if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) return MakeCXCursor(IFD, getCursorTU(C)); return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C)); @@ -4550,15 +4641,15 @@ unsigned clang_getNumOverloadedDecls(CXCursor C) { return 0; OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first; - if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) + if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>()) return E->getNumDecls(); if (OverloadedTemplateStorage *S = Storage.dyn_cast<OverloadedTemplateStorage*>()) return S->size(); - Decl *D = Storage.get<Decl*>(); - if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) + const Decl *D = Storage.get<const Decl *>(); + if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) return Using->shadow_size(); return 0; @@ -4573,15 +4664,15 @@ CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) { CXTranslationUnit TU = getCursorTU(cursor); OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first; - if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>()) + if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>()) return MakeCXCursor(E->decls_begin()[index], TU); if (OverloadedTemplateStorage *S = Storage.dyn_cast<OverloadedTemplateStorage*>()) return MakeCXCursor(S->begin()[index], TU); - Decl *D = Storage.get<Decl*>(); - if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) { + const Decl *D = Storage.get<const Decl *>(); + if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) { // FIXME: This is, unfortunately, linear time. UsingDecl::shadow_iterator Pos = Using->shadow_begin(); std::advance(Pos, index); @@ -4599,8 +4690,7 @@ void clang_getDefinitionSpellingAndExtent(CXCursor C, unsigned *endLine, unsigned *endColumn) { assert(getCursorDecl(C) && "CXCursor has null decl"); - NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C)); - FunctionDecl *FD = dyn_cast<FunctionDecl>(ND); + const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C)); CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody()); SourceManager &SM = FD->getASTContext().getSourceManager(); @@ -4619,26 +4709,26 @@ CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags, switch (C.kind) { case CXCursor_MemberRefExpr: - if (MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C))) + if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C))) Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(), E->getQualifierLoc().getSourceRange()); break; case CXCursor_DeclRefExpr: - if (DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) + if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) Pieces = buildPieces(NameFlags, false, E->getNameInfo(), E->getQualifierLoc().getSourceRange(), E->getOptionalExplicitTemplateArgs()); break; case CXCursor_CallExpr: - if (CXXOperatorCallExpr *OCE = + if (const CXXOperatorCallExpr *OCE = dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) { - Expr *Callee = OCE->getCallee(); - if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) + const Expr *Callee = OCE->getCallee(); + if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) Callee = ICE->getSubExpr(); - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee)) + if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee)) Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(), DRE->getQualifierLoc().getSourceRange()); } @@ -4694,13 +4784,13 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) { case CXToken_Identifier: case CXToken_Keyword: // We know we have an IdentifierInfo*, so use that. - return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data) + return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data) ->getNameStart()); case CXToken_Literal: { // We have stashed the starting pointer in the ptr_data field. Use it. const char *Text = static_cast<const char *>(CXTok.ptr_data); - return createCXString(StringRef(Text, CXTok.int_data[2])); + return cxstring::createDup(StringRef(Text, CXTok.int_data[2])); } case CXToken_Punctuation: @@ -4710,9 +4800,9 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) { // We have to find the starting buffer pointer the hard way, by // deconstructing the source location. - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); if (!CXXUnit) - return createCXString(""); + return cxstring::createEmpty(); SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]); std::pair<FileID, unsigned> LocInfo @@ -4721,13 +4811,13 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) { StringRef Buffer = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); if (Invalid) - return createCXString(""); + return cxstring::createEmpty(); - return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2])); + return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2])); } CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) { - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); if (!CXXUnit) return clang_getNullLocation(); @@ -4736,7 +4826,7 @@ CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) { } CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) { - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); if (!CXXUnit) return clang_getNullRange(); @@ -4748,9 +4838,9 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range, SmallVectorImpl<CXToken> &CXTokens) { SourceManager &SourceMgr = CXXUnit->getSourceManager(); std::pair<FileID, unsigned> BeginLocInfo - = SourceMgr.getDecomposedLoc(Range.getBegin()); + = SourceMgr.getDecomposedSpellingLoc(Range.getBegin()); std::pair<FileID, unsigned> EndLocInfo - = SourceMgr.getDecomposedLoc(Range.getEnd()); + = SourceMgr.getDecomposedSpellingLoc(Range.getEnd()); // Cannot tokenize across files. if (BeginLocInfo.first != EndLocInfo.first) @@ -4789,7 +4879,7 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range, // - Kind-specific fields if (Tok.isLiteral()) { CXTok.int_data[0] = CXToken_Literal; - CXTok.ptr_data = (void *)Tok.getLiteralData(); + CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData()); } else if (Tok.is(tok::raw_identifier)) { // Lookup the identifier to determine whether we have a keyword. IdentifierInfo *II @@ -4818,12 +4908,19 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range, void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens, unsigned *NumTokens) { + LOG_FUNC_SECTION { + *Log << TU << ' ' << Range; + } + if (Tokens) *Tokens = 0; if (NumTokens) *NumTokens = 0; - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); + if (!TU) + return; + + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); if (!CXXUnit || !Tokens || !NumTokens) return; @@ -4855,7 +4952,6 @@ void clang_disposeTokens(CXTranslationUnit TU, // Token annotation APIs. //===----------------------------------------------------------------------===// -typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData; static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data); @@ -4864,7 +4960,6 @@ static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor, namespace { class AnnotateTokensWorker { - AnnotateTokensData &Annotated; CXToken *Tokens; CXCursor *Cursors; unsigned NumTokens; @@ -4877,9 +4972,10 @@ class AnnotateTokensWorker { struct PostChildrenInfo { CXCursor Cursor; SourceRange CursorRange; + unsigned BeforeReachingCursorIdx; unsigned BeforeChildrenTokenIdx; }; - llvm::SmallVector<PostChildrenInfo, 8> PostChildrenInfos; + SmallVector<PostChildrenInfo, 8> PostChildrenInfos; bool MoreTokens() const { return TokIdx < NumTokens; } unsigned NextToken() const { return TokIdx; } @@ -4895,23 +4991,22 @@ class AnnotateTokensWorker { } void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange); - void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult, + bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult, SourceRange); public: - AnnotateTokensWorker(AnnotateTokensData &annotated, - CXToken *tokens, CXCursor *cursors, unsigned numTokens, - CXTranslationUnit tu, SourceRange RegionOfInterest) - : Annotated(annotated), Tokens(tokens), Cursors(cursors), + AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens, + CXTranslationUnit TU, SourceRange RegionOfInterest) + : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0), - AnnotateVis(tu, + AnnotateVis(TU, AnnotateTokensVisitor, this, /*VisitPreprocessorLast=*/true, /*VisitIncludedEntities=*/false, RegionOfInterest, /*VisitDeclsOnly=*/false, AnnotateTokensPostChildrenVisitor), - SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()), + SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()), HasContextSensitiveKeywords(false) { } void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); } @@ -4935,27 +5030,13 @@ void AnnotateTokensWorker::AnnotateTokens() { // Walk the AST within the region of interest, annotating tokens // along the way. AnnotateVis.visitFileRegion(); +} - for (unsigned I = 0 ; I < TokIdx ; ++I) { - AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); - if (Pos != Annotated.end() && - (clang_isInvalid(Cursors[I].kind) || - Pos->second.kind != CXCursor_PreprocessingDirective)) - Cursors[I] = Pos->second; - } - - // Finish up annotating any tokens left. - if (!MoreTokens()) +static inline void updateCursorAnnotation(CXCursor &Cursor, + const CXCursor &updateC) { + if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind)) return; - - const CXCursor &C = clang_getNullCursor(); - for (unsigned I = TokIdx ; I < NumTokens ; ++I) { - if (I < PreprocessingTokIdx && clang_isPreprocessing(Cursors[I].kind)) - continue; - - AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); - Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second; - } + Cursor = updateC; } /// \brief It annotates and advances tokens with a cursor until the comparison @@ -4970,11 +5051,12 @@ void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC, while (MoreTokens()) { const unsigned I = NextToken(); if (isFunctionMacroToken(I)) - return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range); + if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range)) + return; SourceLocation TokLoc = GetTokenLoc(I); if (LocationCompare(SrcMgr, TokLoc, range) == compResult) { - Cursors[I] = updateC; + updateCursorAnnotation(Cursors[I], updateC); AdvanceToken(); continue; } @@ -4983,7 +5065,8 @@ void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC, } /// \brief Special annotation handling for macro argument tokens. -void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens( +/// \returns true if it advanced beyond all macro tokens, false otherwise. +bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens( CXCursor updateC, RangeComparisonResult compResult, SourceRange range) { @@ -5013,13 +5096,15 @@ void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens( atLeastOneCompFail = true; } - if (!atLeastOneCompFail) - TokIdx = I; // All of the tokens were handled, advance beyond all of them. + if (atLeastOneCompFail) + return false; + + TokIdx = I; // All of the tokens were handled, advance beyond all of them. + return true; } enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { - CXSourceLocation Loc = clang_getCursorLocation(cursor); SourceRange cursorRange = getRawCursorExtent(cursor); if (cursorRange.isInvalid()) return CXChildVisit_Recurse; @@ -5027,20 +5112,20 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { if (!HasContextSensitiveKeywords) { // Objective-C properties can have context-sensitive keywords. if (cursor.kind == CXCursor_ObjCPropertyDecl) { - if (ObjCPropertyDecl *Property + if (const ObjCPropertyDecl *Property = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor))) HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0; } // Objective-C methods can have context-sensitive keywords. else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl || cursor.kind == CXCursor_ObjCClassMethodDecl) { - if (ObjCMethodDecl *Method + if (const ObjCMethodDecl *Method = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) { if (Method->getObjCDeclQualifier()) HasContextSensitiveKeywords = true; else { - for (ObjCMethodDecl::param_iterator P = Method->param_begin(), - PEnd = Method->param_end(); + for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(), + PEnd = Method->param_end(); P != PEnd; ++P) { if ((*P)->getObjCDeclQualifier()) { HasContextSensitiveKeywords = true; @@ -5052,7 +5137,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { } // C++ methods can have context-sensitive keywords. else if (cursor.kind == CXCursor_CXXMethod) { - if (CXXMethodDecl *Method + if (const CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) { if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>()) HasContextSensitiveKeywords = true; @@ -5063,20 +5148,13 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { cursor.kind == CXCursor_ClassDecl || cursor.kind == CXCursor_ClassTemplate || cursor.kind == CXCursor_ClassTemplatePartialSpecialization) { - if (Decl *D = getCursorDecl(cursor)) + if (const Decl *D = getCursorDecl(cursor)) if (D->hasAttr<FinalAttr>()) HasContextSensitiveKeywords = true; } } if (clang_isPreprocessing(cursor.kind)) { - // For macro expansions, just note where the beginning of the macro - // expansion occurs. - if (cursor.kind == CXCursor_MacroExpansion) { - Annotated[Loc.int_data] = cursor; - return CXChildVisit_Recurse; - } - // Items in the preprocessing record are kept separate from items in // declarations, so we keep a separate token index. unsigned SavedTokIdx = TokIdx; @@ -5108,7 +5186,17 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { case RangeAfter: break; case RangeOverlap: - Cursors[I] = cursor; + // For macro expansions, just note where the beginning of the macro + // expansion occurs. + if (cursor.kind == CXCursor_MacroExpansion) { + if (TokLoc == cursorRange.getBegin()) + Cursors[I] = cursor; + AdvanceToken(); + break; + } + // We may have already annotated macro names inside macro definitions. + if (Cursors[I].kind != CXCursor_MacroExpansion) + Cursors[I] = cursor; AdvanceToken(); continue; } @@ -5124,48 +5212,14 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { if (cursorRange.isInvalid()) return CXChildVisit_Continue; - - SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data); - // Adjust the annotated range based specific declarations. + unsigned BeforeReachingCursorIdx = NextToken(); const enum CXCursorKind cursorK = clang_getCursorKind(cursor); - if (clang_isDeclaration(cursorK)) { - Decl *D = cxcursor::getCursorDecl(cursor); - - SourceLocation StartLoc; - if (const DeclaratorDecl *DD = dyn_cast_or_null<DeclaratorDecl>(D)) { - if (TypeSourceInfo *TI = DD->getTypeSourceInfo()) - StartLoc = TI->getTypeLoc().getLocStart(); - } else if (TypedefDecl *Typedef = dyn_cast_or_null<TypedefDecl>(D)) { - if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo()) - StartLoc = TI->getTypeLoc().getLocStart(); - } - - if (StartLoc.isValid() && L.isValid() && - SrcMgr.isBeforeInTranslationUnit(StartLoc, L)) - cursorRange.setBegin(StartLoc); - } - - // If the location of the cursor occurs within a macro instantiation, record - // the spelling location of the cursor in our annotation map. We can then - // paper over the token labelings during a post-processing step to try and - // get cursor mappings for tokens that are the *arguments* of a macro - // instantiation. - if (L.isMacroID()) { - unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding(); - // Only invalidate the old annotation if it isn't part of a preprocessing - // directive. Here we assume that the default construction of CXCursor - // results in CXCursor.kind being an initialized value (i.e., 0). If - // this isn't the case, we can fix by doing lookup + insertion. - - CXCursor &oldC = Annotated[rawEncoding]; - if (!clang_isPreprocessing(oldC.kind)) - oldC = cursor; - } - const enum CXCursorKind K = clang_getCursorKind(parent); const CXCursor updateC = - (clang_isInvalid(K) || K == CXCursor_TranslationUnit) + (clang_isInvalid(K) || K == CXCursor_TranslationUnit || + // Attributes are annotated out-of-order, skip tokens until we reach it. + clang_isAttribute(cursor.kind)) ? clang_getNullCursor() : parent; annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange); @@ -5176,13 +5230,13 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { // include the variable declaration, e.g.: // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor. if (clang_isExpression(cursorK)) { - Expr *E = getCursorExpr(cursor); - if (Decl *D = getCursorParentDecl(cursor)) { + const Expr *E = getCursorExpr(cursor); + if (const Decl *D = getCursorParentDecl(cursor)) { const unsigned I = NextToken(); if (E->getLocStart().isValid() && D->getLocation().isValid() && E->getLocStart() == D->getLocation() && E->getLocStart() == GetTokenLoc(I)) { - Cursors[I] = updateC; + updateCursorAnnotation(Cursors[I], updateC); AdvanceToken(); } } @@ -5197,6 +5251,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { PostChildrenInfo Info; Info.Cursor = cursor; Info.CursorRange = cursorRange; + Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx; Info.BeforeChildrenTokenIdx = NextToken(); PostChildrenInfos.push_back(Info); @@ -5227,6 +5282,11 @@ bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) { Cursors[I] = cursor; } + // Attributes are annotated out-of-order, rewind TokIdx to when we first + // encountered the attribute cursor. + if (clang_isAttribute(cursor.kind)) + TokIdx = Info.BeforeReachingCursorIdx; + PostChildrenInfos.pop_back(); return false; } @@ -5263,7 +5323,7 @@ public: if (cursor.kind != CXCursor_MacroExpansion) return CXChildVisit_Continue; - SourceRange macroRange = getCursorMacroExpansion(cursor)->getSourceRange(); + SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange(); if (macroRange.getBegin() == macroRange.getEnd()) return CXChildVisit_Continue; // it's not a function macro. @@ -5321,16 +5381,34 @@ namespace { }; } +/// \brief Used by \c annotatePreprocessorTokens. +/// \returns true if lexing was finished, false otherwise. +static bool lexNext(Lexer &Lex, Token &Tok, + unsigned &NextIdx, unsigned NumTokens) { + if (NextIdx >= NumTokens) + return true; + + ++NextIdx; + Lex.LexFromRawLexer(Tok); + if (Tok.is(tok::eof)) + return true; + + return false; +} + static void annotatePreprocessorTokens(CXTranslationUnit TU, SourceRange RegionOfInterest, - AnnotateTokensData &Annotated) { - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); + CXCursor *Cursors, + CXToken *Tokens, + unsigned NumTokens) { + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); + Preprocessor &PP = CXXUnit->getPreprocessor(); SourceManager &SourceMgr = CXXUnit->getSourceManager(); std::pair<FileID, unsigned> BeginLocInfo - = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin()); + = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin()); std::pair<FileID, unsigned> EndLocInfo - = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd()); + = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd()); if (BeginLocInfo.first != EndLocInfo.first) return; @@ -5347,44 +5425,77 @@ static void annotatePreprocessorTokens(CXTranslationUnit TU, Buffer.end()); Lex.SetCommentRetentionState(true); + unsigned NextIdx = 0; // Lex tokens in raw mode until we hit the end of the range, to avoid // entering #includes or expanding macros. while (true) { Token Tok; - Lex.LexFromRawLexer(Tok); + if (lexNext(Lex, Tok, NextIdx, NumTokens)) + break; + unsigned TokIdx = NextIdx-1; + assert(Tok.getLocation() == + SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1])); reprocess: if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) { - // We have found a preprocessing directive. Gobble it up so that we - // don't see it while preprocessing these tokens later, but keep track - // of all of the token locations inside this preprocessing directive so - // that we can annotate them appropriately. + // We have found a preprocessing directive. Annotate the tokens + // appropriately. // // FIXME: Some simple tests here could identify macro definitions and // #undefs, to provide specific cursor kinds for those. - SmallVector<SourceLocation, 32> Locations; - do { - Locations.push_back(Tok.getLocation()); - Lex.LexFromRawLexer(Tok); - } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof)); - - using namespace cxcursor; - CXCursor Cursor - = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(), - Locations.back()), - TU); - for (unsigned I = 0, N = Locations.size(); I != N; ++I) { - Annotated[Locations[I].getRawEncoding()] = Cursor; + + SourceLocation BeginLoc = Tok.getLocation(); + if (lexNext(Lex, Tok, NextIdx, NumTokens)) + break; + + MacroInfo *MI = 0; + if (Tok.is(tok::raw_identifier) && + StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") { + if (lexNext(Lex, Tok, NextIdx, NumTokens)) + break; + + if (Tok.is(tok::raw_identifier)) { + StringRef Name(Tok.getRawIdentifierData(), Tok.getLength()); + IdentifierInfo &II = PP.getIdentifierTable().get(Name); + SourceLocation MappedTokLoc = + CXXUnit->mapLocationToPreamble(Tok.getLocation()); + MI = getMacroInfo(II, MappedTokLoc, TU); + } } + + bool finished = false; + do { + if (lexNext(Lex, Tok, NextIdx, NumTokens)) { + finished = true; + break; + } + // If we are in a macro definition, check if the token was ever a + // macro name and annotate it if that's the case. + if (MI) { + SourceLocation SaveLoc = Tok.getLocation(); + Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc)); + MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU); + Tok.setLocation(SaveLoc); + if (MacroDef) + Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef, + Tok.getLocation(), TU); + } + } while (!Tok.isAtStartOfLine()); + + unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2; + assert(TokIdx <= LastIdx); + SourceLocation EndLoc = + SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]); + CXCursor Cursor = + MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU); + + for (; TokIdx <= LastIdx; ++TokIdx) + updateCursorAnnotation(Cursors[TokIdx], Cursor); - if (Tok.isAtStartOfLine()) - goto reprocess; - - continue; + if (finished) + break; + goto reprocess; } - - if (Tok.is(tok::eof)) - break; } } @@ -5396,7 +5507,7 @@ static void clang_annotateTokensImpl(void *UserData) { const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens; CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors; - CIndexer *CXXIdx = (CIndexer*)TU->CIdx; + CIndexer *CXXIdx = TU->CIdx; if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing)) setThreadBackgroundPriority(); @@ -5408,14 +5519,20 @@ static void clang_annotateTokensImpl(void *UserData) { cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[NumTokens-1]))); - // A mapping from the source locations found when re-lexing or traversing the - // region of interest to the corresponding cursors. - AnnotateTokensData Annotated; - // Relex the tokens within the source range to look for preprocessing // directives. - annotatePreprocessorTokens(TU, RegionOfInterest, Annotated); - + annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens); + + // If begin location points inside a macro argument, set it to the expansion + // location so we can have the full context when annotating semantically. + { + SourceManager &SM = CXXUnit->getSourceManager(); + SourceLocation Loc = + SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin()); + if (Loc.isMacroID()) + RegionOfInterest.setBegin(SM.getExpansionLoc(Loc)); + } + if (CXXUnit->getPreprocessor().getPreprocessingRecord()) { // Search and mark tokens that are macro argument expansions. MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), @@ -5430,8 +5547,7 @@ static void clang_annotateTokensImpl(void *UserData) { // Annotate all of the source locations in the region of interest that map to // a specific cursor. - AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens, - TU, RegionOfInterest); + AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest); // FIXME: We use a ridiculous stack size here because the data-recursion // algorithm uses a large stack frame than the non-data recursive version, @@ -5449,7 +5565,7 @@ static void clang_annotateTokensImpl(void *UserData) { if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) { IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data); - if (ObjCPropertyDecl *Property + if (const ObjCPropertyDecl *Property = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) { if (Property->getPropertyAttributesAsWritten() != 0 && llvm::StringSwitch<bool>(II->getName()) @@ -5500,16 +5616,24 @@ extern "C" { void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens, unsigned NumTokens, CXCursor *Cursors) { - - if (NumTokens == 0 || !Tokens || !Cursors) + if (!TU || NumTokens == 0 || !Tokens || !Cursors) { + LOG_FUNC_SECTION { *Log << "<null input>"; } return; + } + + LOG_FUNC_SECTION { + *Log << TU << ' '; + CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]); + CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]); + *Log << clang_getRange(bloc, eloc); + } // Any token we don't specifically annotate will have a NULL cursor. CXCursor C = clang_getNullCursor(); for (unsigned I = 0; I != NumTokens; ++I) Cursors[I] = C; - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData); + ASTUnit *CXXUnit = cxtu::getASTUnit(TU); if (!CXXUnit) return; @@ -5534,8 +5658,8 @@ CXLinkageKind clang_getCursorLinkage(CXCursor cursor) { if (!clang_isDeclaration(cursor.kind)) return CXLinkage_Invalid; - Decl *D = cxcursor::getCursorDecl(cursor); - if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D)) + const Decl *D = cxcursor::getCursorDecl(cursor); + if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D)) switch (ND->getLinkage()) { case NoLinkage: return CXLinkage_NoLinkage; case InternalLinkage: return CXLinkage_Internal; @@ -5604,7 +5728,7 @@ extern "C" { enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) { if (clang_isDeclaration(cursor.kind)) - if (Decl *D = cxcursor::getCursorDecl(cursor)) { + if (const Decl *D = cxcursor::getCursorDecl(cursor)) { if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()) return CXAvailability_Available; @@ -5631,12 +5755,14 @@ static CXVersion convertVersion(VersionTuple In) { Out.Major = In.getMajor(); - if (llvm::Optional<unsigned> Minor = In.getMinor()) + Optional<unsigned> Minor = In.getMinor(); + if (Minor.hasValue()) Out.Minor = *Minor; else return Out; - if (llvm::Optional<unsigned> Subminor = In.getSubminor()) + Optional<unsigned> Subminor = In.getSubminor(); + if (Subminor.hasValue()) Out.Subminor = *Subminor; return Out; @@ -5652,16 +5778,16 @@ int clang_getCursorPlatformAvailability(CXCursor cursor, if (always_deprecated) *always_deprecated = 0; if (deprecated_message) - *deprecated_message = cxstring::createCXString("", /*DupString=*/false); + *deprecated_message = cxstring::createEmpty(); if (always_unavailable) *always_unavailable = 0; if (unavailable_message) - *unavailable_message = cxstring::createCXString("", /*DupString=*/false); + *unavailable_message = cxstring::createEmpty(); if (!clang_isDeclaration(cursor.kind)) return 0; - Decl *D = cxcursor::getCursorDecl(cursor); + const Decl *D = cxcursor::getCursorDecl(cursor); if (!D) return 0; @@ -5672,7 +5798,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor, if (always_deprecated) *always_deprecated = 1; if (deprecated_message) - *deprecated_message = cxstring::createCXString(Deprecated->getMessage()); + *deprecated_message = cxstring::createDup(Deprecated->getMessage()); continue; } @@ -5680,8 +5806,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor, if (always_unavailable) *always_unavailable = 1; if (unavailable_message) { - *unavailable_message - = cxstring::createCXString(Unavailable->getMessage()); + *unavailable_message = cxstring::createDup(Unavailable->getMessage()); } continue; } @@ -5689,12 +5814,12 @@ int clang_getCursorPlatformAvailability(CXCursor cursor, if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) { if (N < availability_size) { availability[N].Platform - = cxstring::createCXString(Avail->getPlatform()->getName()); + = cxstring::createDup(Avail->getPlatform()->getName()); availability[N].Introduced = convertVersion(Avail->getIntroduced()); availability[N].Deprecated = convertVersion(Avail->getDeprecated()); availability[N].Obsoleted = convertVersion(Avail->getObsoleted()); availability[N].Unavailable = Avail->getUnavailable(); - availability[N].Message = cxstring::createCXString(Avail->getMessage()); + availability[N].Message = cxstring::createDup(Avail->getMessage()); } ++N; } @@ -5718,15 +5843,15 @@ CXLanguageKind clang_getCursorLanguage(CXCursor cursor) { /// \brief If the given cursor is the "templated" declaration /// descibing a class or function template, return the class or /// function template. -static Decl *maybeGetTemplateCursor(Decl *D) { +static const Decl *maybeGetTemplateCursor(const Decl *D) { if (!D) return 0; - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate()) return FunTmpl; - if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) + if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate()) return ClassTmpl; @@ -5735,8 +5860,8 @@ static Decl *maybeGetTemplateCursor(Decl *D) { CXCursor clang_getCursorSemanticParent(CXCursor cursor) { if (clang_isDeclaration(cursor.kind)) { - if (Decl *D = getCursorDecl(cursor)) { - DeclContext *DC = D->getDeclContext(); + if (const Decl *D = getCursorDecl(cursor)) { + const DeclContext *DC = D->getDeclContext(); if (!DC) return clang_getNullCursor(); @@ -5746,7 +5871,7 @@ CXCursor clang_getCursorSemanticParent(CXCursor cursor) { } if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) { - if (Decl *D = getCursorDecl(cursor)) + if (const Decl *D = getCursorDecl(cursor)) return MakeCXCursor(D, getCursorTU(cursor)); } @@ -5755,8 +5880,8 @@ CXCursor clang_getCursorSemanticParent(CXCursor cursor) { CXCursor clang_getCursorLexicalParent(CXCursor cursor) { if (clang_isDeclaration(cursor.kind)) { - if (Decl *D = getCursorDecl(cursor)) { - DeclContext *DC = D->getLexicalDeclContext(); + if (const Decl *D = getCursorDecl(cursor)) { + const DeclContext *DC = D->getLexicalDeclContext(); if (!DC) return clang_getNullCursor(); @@ -5774,8 +5899,8 @@ CXFile clang_getIncludedFile(CXCursor cursor) { if (cursor.kind != CXCursor_InclusionDirective) return 0; - InclusionDirective *ID = getCursorInclusionDirective(cursor); - return (void *)ID->getFile(); + const InclusionDirective *ID = getCursorInclusionDirective(cursor); + return const_cast<FileEntry *>(ID->getFile()); } CXSourceRange clang_Cursor_getCommentRange(CXCursor C) { @@ -5793,7 +5918,7 @@ CXSourceRange clang_Cursor_getCommentRange(CXCursor C) { CXString clang_Cursor_getRawCommentText(CXCursor C) { if (!clang_isDeclaration(C.kind)) - return createCXString((const char *) NULL); + return cxstring::createNull(); const Decl *D = getCursorDecl(C); ASTContext &Context = getCursorContext(C); @@ -5803,12 +5928,12 @@ CXString clang_Cursor_getRawCommentText(CXCursor C) { // Don't duplicate the string because RawText points directly into source // code. - return createCXString(RawText, false); + return cxstring::createRef(RawText); } CXString clang_Cursor_getBriefCommentText(CXCursor C) { if (!clang_isDeclaration(C.kind)) - return createCXString((const char *) NULL); + return cxstring::createNull(); const Decl *D = getCursorDecl(C); const ASTContext &Context = getCursorContext(C); @@ -5819,10 +5944,10 @@ CXString clang_Cursor_getBriefCommentText(CXCursor C) { // Don't duplicate the string because RawComment ensures that this memory // will not go away. - return createCXString(BriefText, false); + return cxstring::createRef(BriefText); } - return createCXString((const char *) NULL); + return cxstring::createNull(); } CXComment clang_Cursor_getParsedComment(CXCursor C) { @@ -5838,7 +5963,8 @@ CXComment clang_Cursor_getParsedComment(CXCursor C) { CXModule clang_Cursor_getModule(CXCursor C) { if (C.kind == CXCursor_ModuleImportDecl) { - if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) + if (const ImportDecl *ImportD = + dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) return ImportD->getImportedModule(); } @@ -5854,32 +5980,38 @@ CXModule clang_Module_getParent(CXModule CXMod) { CXString clang_Module_getName(CXModule CXMod) { if (!CXMod) - return createCXString(""); + return cxstring::createEmpty(); Module *Mod = static_cast<Module*>(CXMod); - return createCXString(Mod->Name); + return cxstring::createDup(Mod->Name); } CXString clang_Module_getFullName(CXModule CXMod) { if (!CXMod) - return createCXString(""); + return cxstring::createEmpty(); Module *Mod = static_cast<Module*>(CXMod); - return createCXString(Mod->getFullModuleName()); + return cxstring::createDup(Mod->getFullModuleName()); } -unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) { - if (!CXMod) +unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU, + CXModule CXMod) { + if (!TU || !CXMod) return 0; Module *Mod = static_cast<Module*>(CXMod); - return Mod->TopHeaders.size(); + FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager(); + ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr); + return TopHeaders.size(); } -CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) { - if (!CXMod) +CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, + CXModule CXMod, unsigned Index) { + if (!TU || !CXMod) return 0; Module *Mod = static_cast<Module*>(CXMod); + FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager(); - if (Index < Mod->TopHeaders.size()) - return const_cast<FileEntry *>(Mod->TopHeaders[Index]); + ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr); + if (Index < TopHeaders.size()) + return const_cast<FileEntry *>(TopHeaders[Index]); return 0; } @@ -5895,9 +6027,10 @@ unsigned clang_CXXMethod_isStatic(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; - CXXMethodDecl *Method = 0; - Decl *D = cxcursor::getCursorDecl(C); - if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D)) + const CXXMethodDecl *Method = 0; + const Decl *D = cxcursor::getCursorDecl(C); + if (const FunctionTemplateDecl *FunTmpl = + dyn_cast_or_null<FunctionTemplateDecl>(D)) Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); else Method = dyn_cast_or_null<CXXMethodDecl>(D); @@ -5908,9 +6041,10 @@ unsigned clang_CXXMethod_isVirtual(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; - CXXMethodDecl *Method = 0; - Decl *D = cxcursor::getCursorDecl(C); - if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D)) + const CXXMethodDecl *Method = 0; + const Decl *D = cxcursor::getCursorDecl(C); + if (const FunctionTemplateDecl *FunTmpl = + dyn_cast_or_null<FunctionTemplateDecl>(D)) Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); else Method = dyn_cast_or_null<CXXMethodDecl>(D); @@ -5927,7 +6061,7 @@ CXType clang_getIBOutletCollectionType(CXCursor C) { if (C.kind != CXCursor_IBOutletCollectionAttr) return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C)); - IBOutletCollectionAttr *A = + const IBOutletCollectionAttr *A = cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C)); return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C)); @@ -6004,7 +6138,7 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) { return usage; } - ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData); + ASTUnit *astUnit = cxtu::getASTUnit(TU); OwningPtr<MemUsageEntries> entries(new MemUsageEntries()); ASTContext &astContext = astUnit->getASTContext(); @@ -6167,11 +6301,205 @@ void cxindex::printDiagsToStderr(ASTUnit *Unit) { #endif } +MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II, + SourceLocation MacroDefLoc, + CXTranslationUnit TU){ + if (MacroDefLoc.isInvalid() || !TU) + return 0; + if (!II.hadMacroDefinition()) + return 0; + + ASTUnit *Unit = cxtu::getASTUnit(TU); + Preprocessor &PP = Unit->getPreprocessor(); + MacroDirective *MD = PP.getMacroDirectiveHistory(&II); + if (MD) { + for (MacroDirective::DefInfo + Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) { + if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc()) + return Def.getMacroInfo(); + } + } + + return 0; +} + +const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef, + CXTranslationUnit TU) { + if (!MacroDef || !TU) + return 0; + const IdentifierInfo *II = MacroDef->getName(); + if (!II) + return 0; + + return getMacroInfo(*II, MacroDef->getLocation(), TU); +} + +MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, + const Token &Tok, + CXTranslationUnit TU) { + if (!MI || !TU) + return 0; + if (Tok.isNot(tok::raw_identifier)) + return 0; + + if (MI->getNumTokens() == 0) + return 0; + SourceRange DefRange(MI->getReplacementToken(0).getLocation(), + MI->getDefinitionEndLoc()); + ASTUnit *Unit = cxtu::getASTUnit(TU); + + // Check that the token is inside the definition and not its argument list. + SourceManager &SM = Unit->getSourceManager(); + if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin())) + return 0; + if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation())) + return 0; + + Preprocessor &PP = Unit->getPreprocessor(); + PreprocessingRecord *PPRec = PP.getPreprocessingRecord(); + if (!PPRec) + return 0; + + StringRef Name(Tok.getRawIdentifierData(), Tok.getLength()); + IdentifierInfo &II = PP.getIdentifierTable().get(Name); + if (!II.hadMacroDefinition()) + return 0; + + // Check that the identifier is not one of the macro arguments. + if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end()) + return 0; + + MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II); + if (!InnerMD) + return 0; + + return PPRec->findMacroDefinition(InnerMD->getMacroInfo()); +} + +MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, + SourceLocation Loc, + CXTranslationUnit TU) { + if (Loc.isInvalid() || !MI || !TU) + return 0; + + if (MI->getNumTokens() == 0) + return 0; + ASTUnit *Unit = cxtu::getASTUnit(TU); + Preprocessor &PP = Unit->getPreprocessor(); + if (!PP.getPreprocessingRecord()) + return 0; + Loc = Unit->getSourceManager().getSpellingLoc(Loc); + Token Tok; + if (PP.getRawToken(Loc, Tok)) + return 0; + + return checkForMacroInMacroDefinition(MI, Tok, TU); +} + extern "C" { CXString clang_getClangVersion() { - return createCXString(getClangFullVersion()); + return cxstring::createDup(getClangFullVersion()); } } // end: extern "C" +Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) { + if (TU) { + if (ASTUnit *Unit = cxtu::getASTUnit(TU)) { + LogOS << '<' << Unit->getMainFileName() << '>'; + if (Unit->isMainFileAST()) + LogOS << " (" << Unit->getASTFileName() << ')'; + return *this; + } + } + + LogOS << "<NULL TU>"; + return *this; +} + +Logger &cxindex::Logger::operator<<(const FileEntry *FE) { + *this << FE->getName(); + return *this; +} + +Logger &cxindex::Logger::operator<<(CXCursor cursor) { + CXString cursorName = clang_getCursorDisplayName(cursor); + *this << cursorName << "@" << clang_getCursorLocation(cursor); + clang_disposeString(cursorName); + return *this; +} + +Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) { + CXFile File; + unsigned Line, Column; + clang_getFileLocation(Loc, &File, &Line, &Column, 0); + CXString FileName = clang_getFileName(File); + *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column); + clang_disposeString(FileName); + return *this; +} + +Logger &cxindex::Logger::operator<<(CXSourceRange range) { + CXSourceLocation BLoc = clang_getRangeStart(range); + CXSourceLocation ELoc = clang_getRangeEnd(range); + + CXFile BFile; + unsigned BLine, BColumn; + clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0); + + CXFile EFile; + unsigned ELine, EColumn; + clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0); + + CXString BFileName = clang_getFileName(BFile); + if (BFile == EFile) { + *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName), + BLine, BColumn, ELine, EColumn); + } else { + CXString EFileName = clang_getFileName(EFile); + *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), + BLine, BColumn) + << llvm::format("%s:%d:%d]", clang_getCString(EFileName), + ELine, EColumn); + clang_disposeString(EFileName); + } + clang_disposeString(BFileName); + return *this; +} + +Logger &cxindex::Logger::operator<<(CXString Str) { + *this << clang_getCString(Str); + return *this; +} + +Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) { + LogOS << Fmt; + return *this; +} + +cxindex::Logger::~Logger() { + LogOS.flush(); + + llvm::sys::ScopedLock L(EnableMultithreadingMutex); + + static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime(); + + raw_ostream &OS = llvm::errs(); + OS << "[libclang:" << Name << ':'; + + // FIXME: Portability. +#if HAVE_PTHREAD_H && __APPLE__ + mach_port_t tid = pthread_mach_thread_np(pthread_self()); + OS << tid << ':'; +#endif + + llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime(); + OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime()); + OS << Msg.str() << '\n'; + + if (Trace) { + llvm::sys::PrintStackTrace(stderr); + OS << "--------------------------------------------------\n"; + } +} |