diff options
author | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
commit | 056abd2059c65a3e908193aeae16fad98017437c (patch) | |
tree | 2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /tools/libclang | |
parent | cc73504950eb7b5dff2dded9bedd67bc36d64641 (diff) | |
download | FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.zip FreeBSD-src-056abd2059c65a3e908193aeae16fad98017437c.tar.gz |
Vendor import of clang release_32 branch r168974 (effectively, 3.2 RC2):
http://llvm.org/svn/llvm-project/cfe/branches/release_32@168974
Diffstat (limited to 'tools/libclang')
-rw-r--r-- | tools/libclang/CIndex.cpp | 202 | ||||
-rw-r--r-- | tools/libclang/CIndexCXX.cpp | 3 | ||||
-rw-r--r-- | tools/libclang/CIndexCodeCompletion.cpp | 8 | ||||
-rw-r--r-- | tools/libclang/CIndexDiagnostic.cpp | 8 | ||||
-rw-r--r-- | tools/libclang/CIndexUSRs.cpp | 44 | ||||
-rw-r--r-- | tools/libclang/CMakeLists.txt | 3 | ||||
-rw-r--r-- | tools/libclang/CXComment.cpp | 197 | ||||
-rw-r--r-- | tools/libclang/CXComment.h | 23 | ||||
-rw-r--r-- | tools/libclang/CXCursor.cpp | 204 | ||||
-rw-r--r-- | tools/libclang/CXType.cpp | 3 | ||||
-rw-r--r-- | tools/libclang/CursorVisitor.h | 20 | ||||
-rw-r--r-- | tools/libclang/IndexBody.cpp | 14 | ||||
-rw-r--r-- | tools/libclang/IndexDecl.cpp | 15 | ||||
-rw-r--r-- | tools/libclang/Indexing.cpp | 104 | ||||
-rw-r--r-- | tools/libclang/IndexingContext.cpp | 68 | ||||
-rw-r--r-- | tools/libclang/IndexingContext.h | 26 | ||||
-rw-r--r-- | tools/libclang/Makefile | 15 | ||||
-rw-r--r-- | tools/libclang/RecursiveASTVisitor.h | 7 | ||||
-rw-r--r-- | tools/libclang/libclang.exports | 7 |
19 files changed, 580 insertions, 391 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index bd27b4c..3a6c408 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -145,8 +145,8 @@ RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) { /// /// \param Cursor the cursor to visit. /// -/// \param CheckRegionOfInterest if true, then the caller already checked that -/// this cursor is within the region of interest. +/// \param CheckedRegionOfInterest if true, then the caller already checked +/// that this cursor is within the region of interest. /// /// \returns true if the visitation should be aborted, false if it /// should continue. @@ -182,8 +182,13 @@ bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) { case CXChildVisit_Continue: return false; - case CXChildVisit_Recurse: - return VisitChildren(Cursor); + case CXChildVisit_Recurse: { + bool ret = VisitChildren(Cursor); + if (PostChildrenVisitor) + if (PostChildrenVisitor(Cursor, ClientData)) + return true; + return ret; + } } llvm_unreachable("Invalid CXChildVisitResult!"); @@ -566,6 +571,16 @@ bool CursorVisitor::VisitDeclContext(DeclContext *DC) { continue; CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest); + // Ignore synthesized ivars here, otherwise if we have something like: + // @synthesize prop = _prop; + // and '_prop' is not declared, we will encounter a '_prop' ivar before + // encountering the 'prop' synthesize declaration and we will think that + // we passed the region-of-interest. + if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) { + if (ivarD->getSynthesize()) + continue; + } + // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol // declarations is a mismatch with the compiler semantics. if (Cursor.kind == CXCursor_ObjCInterfaceDecl) { @@ -1006,12 +1021,12 @@ bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) { // Visit synthesized methods since they will be skipped when visiting // the @interface. if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl()) - if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl) + if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl) if (Visit(MakeCXCursor(MD, TU, RegionOfInterest))) return true; if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl()) - if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl) + if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl) if (Visit(MakeCXCursor(MD, TU, RegionOfInterest))) return true; @@ -1312,7 +1327,12 @@ bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) { if (Expr *E = TAL.getSourceDeclExpression()) return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest)); return false; - + + case TemplateArgument::NullPtr: + if (Expr *E = TAL.getSourceNullPtrExpression()) + return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest)); + return false; + case TemplateArgument::Expression: if (Expr *E = TAL.getSourceExpression()) return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest)); @@ -1622,6 +1642,7 @@ DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo, ExplicitTemplateArgsVisitKind) DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind) DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind) +DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind) #undef DEF_JOB class DeclVisit : public VisitorJob { @@ -2198,6 +2219,8 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { case CXChildVisit_Break: return true; case CXChildVisit_Continue: break; case CXChildVisit_Recurse: + if (PostChildrenVisitor) + WL.push_back(PostChildrenVisit(0, Cursor)); EnqueueWorkList(WL, S); break; } @@ -2314,6 +2337,11 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { } break; } + + case VisitorJob::PostChildrenVisitKind: + if (PostChildrenVisitor(Parent, ClientData)) + return true; + break; } } return false; @@ -2528,12 +2556,13 @@ static void clang_parseTranslationUnit_Impl(void *UserData) { bool IncludeBriefCommentsInCodeCompletion = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion; bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies; + bool ForSerialization = options & CXTranslationUnit_ForSerialization; // Configure the diagnostics. - DiagnosticOptions DiagOpts; IntrusiveRefCntPtr<DiagnosticsEngine> - Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args, - command_line_args)); + Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions, + num_command_line_args, + command_line_args)); // Recover resources if we crash before exiting this function. llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, @@ -2615,6 +2644,7 @@ static void clang_parseTranslationUnit_Impl(void *UserData) { /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, /*UserFilesAreVolatile=*/true, + ForSerialization, &ErrUnit)); if (NumErrors != Diags->getClient()->getNumErrors()) { @@ -2689,7 +2719,8 @@ static void clang_saveTranslationUnit_Impl(void *UserData) { if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing)) setThreadBackgroundPriority(); - STUI->result = static_cast<ASTUnit *>(STUI->TU->TUData)->Save(STUI->FileName); + bool hadError = static_cast<ASTUnit *>(STUI->TU->TUData)->Save(STUI->FileName); + STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None; } int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName, @@ -3018,6 +3049,10 @@ static CXString getDeclSpelling(Decl *D) { if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl()) return createCXString(Property->getIdentifier()->getName()); + if (ImportDecl *ImportD = dyn_cast<ImportDecl>(D)) + if (Module *Mod = ImportD->getImportedModule()) + return createCXString(Mod->getFullModuleName()); + return createCXString(""); } @@ -3219,6 +3254,18 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc()); } + if (C.kind == CXCursor_ModuleImportDecl) { + if (pieceIndex > 0) + return clang_getNullRange(); + if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) { + ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs(); + if (!Locs.empty()) + return cxloc::translateSourceRange(Ctx, + SourceRange(Locs.front(), Locs.back())); + } + return clang_getNullRange(); + } + // FIXME: A CXCursor_InclusionDirective should give the location of the // filename, but we don't keep track of this. @@ -3510,8 +3557,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return createCXString("BreakStmt"); case CXCursor_ReturnStmt: return createCXString("ReturnStmt"); - case CXCursor_AsmStmt: - return createCXString("AsmStmt"); + case CXCursor_GCCAsmStmt: + return createCXString("GCCAsmStmt"); case CXCursor_MSAsmStmt: return createCXString("MSAsmStmt"); case CXCursor_ObjCAtTryStmt: @@ -3614,6 +3661,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return createCXString("ObjCDynamicDecl"); case CXCursor_CXXAccessSpecifier: return createCXString("CXXAccessSpecifier"); + case CXCursor_ModuleImportDecl: + return createCXString("ModuleImport"); } llvm_unreachable("Unhandled CXCursorKind"); @@ -3810,7 +3859,8 @@ unsigned clang_isInvalid(enum CXCursorKind K) { } unsigned clang_isDeclaration(enum CXCursorKind K) { - return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl; + return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) || + (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl); } unsigned clang_isReference(enum CXCursorKind K) { @@ -3957,7 +4007,7 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { return cxloc::translateSourceLocation(getCursorContext(C), L); } - if (C.kind < CXCursor_FirstDecl || C.kind > CXCursor_LastDecl) + if (!clang_isDeclaration(C.kind)) return clang_getNullLocation(); Decl *D = getCursorDecl(C); @@ -4092,7 +4142,7 @@ static SourceRange getRawCursorExtent(CXCursor C) { return SourceRange(Start, End); } - if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) { + if (clang_isDeclaration(C.kind)) { Decl *D = cxcursor::getCursorDecl(C); if (!D) return SourceRange(); @@ -4115,7 +4165,7 @@ static SourceRange getRawCursorExtent(CXCursor C) { /// \brief Retrieves the "raw" cursor extent, which is then extended to include /// the decl-specifier-seq for declarations. static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) { - if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) { + if (clang_isDeclaration(C.kind)) { Decl *D = cxcursor::getCursorDecl(C); if (!D) return SourceRange(); @@ -4809,6 +4859,9 @@ typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData; static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data); +static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor, + CXClientData client_data); + namespace { class AnnotateTokensWorker { AnnotateTokensData &Annotated; @@ -4820,6 +4873,13 @@ class AnnotateTokensWorker { CursorVisitor AnnotateVis; SourceManager &SrcMgr; bool HasContextSensitiveKeywords; + + struct PostChildrenInfo { + CXCursor Cursor; + SourceRange CursorRange; + unsigned BeforeChildrenTokenIdx; + }; + llvm::SmallVector<PostChildrenInfo, 8> PostChildrenInfos; bool MoreTokens() const { return TokIdx < NumTokens; } unsigned NextToken() const { return TokIdx; } @@ -4848,12 +4908,15 @@ public: AnnotateTokensVisitor, this, /*VisitPreprocessorLast=*/true, /*VisitIncludedEntities=*/false, - RegionOfInterest), + RegionOfInterest, + /*VisitDeclsOnly=*/false, + AnnotateTokensPostChildrenVisitor), SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()), HasContextSensitiveKeywords(false) { } void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); } enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent); + bool postVisitChildren(CXCursor cursor); void AnnotateTokens(); /// \brief Determine whether the annotator saw any cursors that have @@ -4861,6 +4924,10 @@ public: bool hasContextSensitiveKeywords() const { return HasContextSensitiveKeywords; } + + ~AnnotateTokensWorker() { + assert(PostChildrenInfos.empty()); + } }; } @@ -5062,7 +5129,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { // Adjust the annotated range based specific declarations. const enum CXCursorKind cursorK = clang_getCursorKind(cursor); - if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) { + if (clang_isDeclaration(cursorK)) { Decl *D = cxcursor::getCursorDecl(cursor); SourceLocation StartLoc; @@ -5121,25 +5188,47 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { } } - // Visit children to get their cursor information. - const unsigned BeforeChildren = NextToken(); - VisitChildren(cursor); + // Before recursing into the children keep some state that we are going + // to use in the AnnotateTokensWorker::postVisitChildren callback to do some + // extra work after the child nodes are visited. + // Note that we don't call VisitChildren here to avoid traversing statements + // code-recursively which can blow the stack. + + PostChildrenInfo Info; + Info.Cursor = cursor; + Info.CursorRange = cursorRange; + Info.BeforeChildrenTokenIdx = NextToken(); + PostChildrenInfos.push_back(Info); + + return CXChildVisit_Recurse; +} + +bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) { + if (PostChildrenInfos.empty()) + return false; + const PostChildrenInfo &Info = PostChildrenInfos.back(); + if (!clang_equalCursors(Info.Cursor, cursor)) + return false; + + const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx; const unsigned AfterChildren = NextToken(); + SourceRange cursorRange = Info.CursorRange; // Scan the tokens that are at the end of the cursor, but are not captured // but the child cursors. annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange); - + // Scan the tokens that are at the beginning of the cursor, but are not // capture by the child cursors. for (unsigned I = BeforeChildren; I != AfterChildren; ++I) { if (!clang_isInvalid(clang_getCursorKind(Cursors[I]))) break; - + Cursors[I] = cursor; } - return CXChildVisit_Continue; + PostChildrenInfos.pop_back(); + return false; } static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, @@ -5148,6 +5237,12 @@ static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent); } +static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor, + CXClientData client_data) { + return static_cast<AnnotateTokensWorker*>(client_data)-> + postVisitChildren(cursor); +} + namespace { /// \brief Uses the macro expansions in the preprocessing record to find @@ -5732,13 +5827,61 @@ CXString clang_Cursor_getBriefCommentText(CXCursor C) { CXComment clang_Cursor_getParsedComment(CXCursor C) { if (!clang_isDeclaration(C.kind)) - return cxcomment::createCXComment(NULL); + return cxcomment::createCXComment(NULL, NULL); const Decl *D = getCursorDecl(C); const ASTContext &Context = getCursorContext(C); - const comments::FullComment *FC = Context.getCommentForDecl(D); + const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL); + + return cxcomment::createCXComment(FC, getCursorTU(C)); +} + +CXModule clang_Cursor_getModule(CXCursor C) { + if (C.kind == CXCursor_ModuleImportDecl) { + if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) + return ImportD->getImportedModule(); + } + + return 0; +} + +CXModule clang_Module_getParent(CXModule CXMod) { + if (!CXMod) + return 0; + Module *Mod = static_cast<Module*>(CXMod); + return Mod->Parent; +} + +CXString clang_Module_getName(CXModule CXMod) { + if (!CXMod) + return createCXString(""); + Module *Mod = static_cast<Module*>(CXMod); + return createCXString(Mod->Name); +} - return cxcomment::createCXComment(FC); +CXString clang_Module_getFullName(CXModule CXMod) { + if (!CXMod) + return createCXString(""); + Module *Mod = static_cast<Module*>(CXMod); + return createCXString(Mod->getFullModuleName()); +} + +unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) { + if (!CXMod) + return 0; + Module *Mod = static_cast<Module*>(CXMod); + return Mod->TopHeaders.size(); +} + +CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) { + if (!CXMod) + return 0; + Module *Mod = static_cast<Module*>(CXMod); + + if (Index < Mod->TopHeaders.size()) + return const_cast<FileEntry *>(Mod->TopHeaders[Index]); + + return 0; } } // end: extern "C" @@ -5994,6 +6137,9 @@ void SetSafetyThreadStackSize(unsigned Value) { } void clang::setThreadBackgroundPriority() { + if (getenv("LIBCLANG_BGPRIO_DISABLE")) + return; + // FIXME: Move to llvm/Support and make it cross-platform. #ifdef __APPLE__ setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG); diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp index 240b0f6..9bc3efa 100644 --- a/tools/libclang/CIndexCXX.cpp +++ b/tools/libclang/CIndexCXX.cpp @@ -67,8 +67,9 @@ enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) { = dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>( getCursorDecl(C))) { switch (PartialSpec->getTagKind()) { - case TTK_Class: return CXCursor_ClassDecl; + case TTK_Interface: case TTK_Struct: return CXCursor_StructDecl; + case TTK_Class: return CXCursor_ClassDecl; case TTK_Union: return CXCursor_UnionDecl; case TTK_Enum: return CXCursor_NoDeclFound; } diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp index 0073b50..46af661 100644 --- a/tools/libclang/CIndexCodeCompletion.cpp +++ b/tools/libclang/CIndexCodeCompletion.cpp @@ -223,8 +223,6 @@ clang_getCompletionParent(CXCompletionString completion_string, if (!CCStr) return createCXString((const char *)0); - if (kind) - *kind = CCStr->getParentContextKind(); return createCXString(CCStr->getParentContextName(), /*DupString=*/false); } @@ -248,6 +246,8 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults { /// \brief Diagnostics produced while performing code completion. SmallVector<StoredDiagnostic, 8> Diagnostics; + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; + /// \brief Diag object IntrusiveRefCntPtr<DiagnosticsEngine> Diag; @@ -307,8 +307,10 @@ static llvm::sys::cas_flag CodeCompletionResultObjects; AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults( const FileSystemOptions& FileSystemOpts) : CXCodeCompleteResults(), + DiagOpts(new DiagnosticOptions), Diag(new DiagnosticsEngine( - IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs))), + IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), + &*DiagOpts)), FileSystemOpts(FileSystemOpts), FileMgr(new FileManager(FileSystemOpts)), SourceMgr(new SourceManager(*Diag, *FileMgr)), diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp index 14722e0..3154480 100644 --- a/tools/libclang/CIndexDiagnostic.cpp +++ b/tools/libclang/CIndexDiagnostic.cpp @@ -19,7 +19,7 @@ #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/DiagnosticRenderer.h" -#include "clang/Frontend/DiagnosticOptions.h" +#include "clang/Basic/DiagnosticOptions.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/MemoryBuffer.h" @@ -87,7 +87,7 @@ public: class CXDiagnosticRenderer : public DiagnosticNoteRenderer { public: CXDiagnosticRenderer(const LangOptions &LangOpts, - const DiagnosticOptions &DiagOpts, + DiagnosticOptions *DiagOpts, CXDiagnosticSetImpl *mainSet) : DiagnosticNoteRenderer(LangOpts, DiagOpts), CurrentSet(mainSet), MainSet(mainSet) {} @@ -191,9 +191,9 @@ CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU, if (!TU->Diagnostics) { CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl(); TU->Diagnostics = Set; - DiagnosticOptions DOpts; + llvm::IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions; CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(), - DOpts, Set); + &*DOpts, Set); for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(), ei = AU->stored_diag_end(); it != ei; ++it) { diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp index c885dd5..6140032 100644 --- a/tools/libclang/CIndexUSRs.cpp +++ b/tools/libclang/CIndexUSRs.cpp @@ -402,6 +402,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) { AlreadyStarted = true; switch (D->getTagKind()) { + case TTK_Interface: case TTK_Struct: Out << "@ST"; break; case TTK_Class: Out << "@CT"; break; case TTK_Union: Out << "@UT"; break; @@ -413,6 +414,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) { AlreadyStarted = true; switch (D->getTagKind()) { + case TTK_Interface: case TTK_Struct: Out << "@SP"; break; case TTK_Class: Out << "@CP"; break; case TTK_Union: Out << "@UP"; break; @@ -424,6 +426,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) { if (!AlreadyStarted) { switch (D->getTagKind()) { + case TTK_Interface: case TTK_Struct: Out << "@S"; break; case TTK_Class: Out << "@C"; break; case TTK_Union: Out << "@U"; break; @@ -725,10 +728,12 @@ void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) { break; case TemplateArgument::Declaration: - if (Decl *D = Arg.getAsDecl()) - Visit(D); + Visit(Arg.getAsDecl()); break; - + + case TemplateArgument::NullPtr: + break; + case TemplateArgument::TemplateExpansion: Out << 'P'; // pack expansion of... // Fall through @@ -800,36 +805,11 @@ bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) { if (!D || D->getLocStart().isInvalid()) return true; - // Check if the cursor has 'NoLinkage'. - if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) - switch (ND->getLinkage()) { - case ExternalLinkage: - // Generate USRs for all entities with external linkage. - break; - case NoLinkage: - case UniqueExternalLinkage: - // We allow enums, typedefs, and structs that have no linkage to - // have USRs that are anchored to the file they were defined in - // (e.g., the header). This is a little gross, but in principal - // enums/anonymous structs/etc. defined in a common header file - // are referred to across multiple translation units. - if (isa<TagDecl>(ND) || isa<TypedefDecl>(ND) || - isa<EnumConstantDecl>(ND) || isa<FieldDecl>(ND) || - isa<VarDecl>(ND) || isa<NamespaceDecl>(ND)) - break; - // Fall-through. - case InternalLinkage: - if (isa<FunctionDecl>(ND)) - break; - } + USRGenerator UG(&D->getASTContext(), &Buf); + UG->Visit(const_cast<Decl*>(D)); - { - USRGenerator UG(&D->getASTContext(), &Buf); - UG->Visit(const_cast<Decl*>(D)); - - if (UG->ignoreResults()) - return true; - } + if (UG->ignoreResults()) + return true; return false; } diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt index 283276f..1426c42 100644 --- a/tools/libclang/CMakeLists.txt +++ b/tools/libclang/CMakeLists.txt @@ -43,7 +43,8 @@ set(SOURCES set(LIBRARIES clangARCMigrate - clangRewrite + clangRewriteCore + clangRewriteFrontend clangFrontend clangDriver clangSerialization diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp index c5c9ca8..fa149a0 100644 --- a/tools/libclang/CXComment.cpp +++ b/tools/libclang/CXComment.cpp @@ -15,12 +15,11 @@ #include "CXString.h" #include "CXComment.h" #include "CXCursor.h" -#include "CXTranslationUnit.h" +#include "clang/AST/PrettyPrinter.h" #include "clang/AST/CommentVisitor.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/Decl.h" -#include "clang/Frontend/ASTUnit.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" @@ -94,9 +93,9 @@ unsigned clang_Comment_getNumChildren(CXComment CXC) { CXComment clang_Comment_getChild(CXComment CXC, unsigned ChildIdx) { const Comment *C = getASTNode(CXC); if (!C || ChildIdx >= C->child_count()) - return createCXComment(NULL); + return createCXComment(NULL, NULL); - return createCXComment(*(C->child_begin() + ChildIdx)); + return createCXComment(*(C->child_begin() + ChildIdx), CXC.TranslationUnit); } unsigned clang_Comment_isWhitespace(CXComment CXC) { @@ -134,7 +133,8 @@ CXString clang_InlineCommandComment_getCommandName(CXComment CXC) { if (!ICC) return createCXString((const char *) 0); - return createCXString(ICC->getCommandName(), /*DupString=*/ false); + const CommandTraits &Traits = getCommandTraits(CXC); + return createCXString(ICC->getCommandName(Traits), /*DupString=*/ false); } enum CXCommentInlineCommandRenderKind @@ -221,7 +221,8 @@ CXString clang_BlockCommandComment_getCommandName(CXComment CXC) { if (!BCC) return createCXString((const char *) 0); - return createCXString(BCC->getCommandName(), /*DupString=*/ false); + const CommandTraits &Traits = getCommandTraits(CXC); + return createCXString(BCC->getCommandName(Traits), /*DupString=*/ false); } unsigned clang_BlockCommandComment_getNumArgs(CXComment CXC) { @@ -244,9 +245,9 @@ CXString clang_BlockCommandComment_getArgText(CXComment CXC, CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) { const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC); if (!BCC) - return createCXComment(NULL); + return createCXComment(NULL, NULL); - return createCXComment(BCC->getParagraph()); + return createCXComment(BCC->getParagraph(), CXC.TranslationUnit); } CXString clang_ParamCommandComment_getParamName(CXComment CXC) { @@ -254,7 +255,7 @@ CXString clang_ParamCommandComment_getParamName(CXComment CXC) { if (!PCC || !PCC->hasParamName()) return createCXString((const char *) 0); - return createCXString(PCC->getParamName(), /*DupString=*/ false); + return createCXString(PCC->getParamNameAsWritten(), /*DupString=*/ false); } unsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) { @@ -305,7 +306,7 @@ CXString clang_TParamCommandComment_getParamName(CXComment CXC) { if (!TPCC || !TPCC->hasParamName()) return createCXString((const char *) 0); - return createCXString(TPCC->getParamName(), /*DupString=*/ false); + return createCXString(TPCC->getParamNameAsWritten(), /*DupString=*/ false); } unsigned clang_TParamCommandComment_isParamPositionValid(CXComment CXC) { @@ -405,7 +406,8 @@ public: /// Separate parts of a FullComment. struct FullCommentParts { /// Take a full comment apart and initialize members accordingly. - FullCommentParts(const FullComment *C); + FullCommentParts(const FullComment *C, + const CommandTraits &Traits); const BlockContentComment *Brief; const ParagraphComment *FirstParagraph; @@ -415,9 +417,9 @@ struct FullCommentParts { SmallVector<const BlockContentComment *, 8> MiscBlocks; }; -FullCommentParts::FullCommentParts(const FullComment *C) : +FullCommentParts::FullCommentParts(const FullComment *C, + const CommandTraits &Traits) : Brief(NULL), FirstParagraph(NULL), Returns(NULL) { - const CommandTraits Traits; for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); I != E; ++I) { const Comment *Child = *I; @@ -440,12 +442,12 @@ FullCommentParts::FullCommentParts(const FullComment *C) : case Comment::BlockCommandCommentKind: { const BlockCommandComment *BCC = cast<BlockCommandComment>(Child); - StringRef CommandName = BCC->getCommandName(); - if (!Brief && Traits.isBriefCommand(CommandName)) { + const CommandInfo *Info = Traits.getCommandInfo(BCC->getCommandID()); + if (!Brief && Info->IsBriefCommand) { Brief = BCC; break; } - if (!Returns && Traits.isReturnsCommand(CommandName)) { + if (!Returns && Info->IsReturnsCommand) { Returns = BCC; break; } @@ -483,7 +485,8 @@ FullCommentParts::FullCommentParts(const FullComment *C) : case Comment::VerbatimLineCommentKind: { const VerbatimLineComment *VLC = cast<VerbatimLineComment>(Child); - if (!Traits.isDeclarationCommand(VLC->getCommandName())) + const CommandInfo *Info = Traits.getCommandInfo(VLC->getCommandID()); + if (!Info->IsDeclarationCommand) MiscBlocks.push_back(VLC); break; } @@ -533,7 +536,11 @@ class CommentASTToHTMLConverter : public ConstCommentVisitor<CommentASTToHTMLConverter> { public: /// \param Str accumulator for HTML. - CommentASTToHTMLConverter(SmallVectorImpl<char> &Str) : Result(Str) { } + CommentASTToHTMLConverter(const FullComment *FC, + SmallVectorImpl<char> &Str, + const CommandTraits &Traits) : + FC(FC), Result(Str), Traits(Traits) + { } // Inline content. void visitTextComment(const TextComment *C); @@ -561,10 +568,11 @@ public: void appendToResultWithHTMLEscaping(StringRef S); private: - const CommandTraits Traits; - + const FullComment *FC; /// Output stream for HTML. llvm::raw_svector_ostream Result; + + const CommandTraits &Traits; }; } // end unnamed namespace @@ -637,14 +645,14 @@ void CommentASTToHTMLConverter::visitParagraphComment( void CommentASTToHTMLConverter::visitBlockCommandComment( const BlockCommandComment *C) { - StringRef CommandName = C->getCommandName(); - if (Traits.isBriefCommand(CommandName)) { + const CommandInfo *Info = Traits.getCommandInfo(C->getCommandID()); + if (Info->IsBriefCommand) { Result << "<p class=\"para-brief\">"; visitNonStandaloneParagraphComment(C->getParagraph()); Result << "</p>"; return; } - if (Traits.isReturnsCommand(CommandName)) { + if (Info->IsReturnsCommand) { Result << "<p class=\"para-returns\">" "<span class=\"word-returns\">Returns</span> "; visitNonStandaloneParagraphComment(C->getParagraph()); @@ -661,10 +669,11 @@ void CommentASTToHTMLConverter::visitParamCommandComment( Result << "<dt class=\"param-name-index-" << C->getParamIndex() << "\">"; - } else + appendToResultWithHTMLEscaping(C->getParamName(FC)); + } else { Result << "<dt class=\"param-name-index-invalid\">"; - - appendToResultWithHTMLEscaping(C->getParamName()); + appendToResultWithHTMLEscaping(C->getParamNameAsWritten()); + } Result << "</dt>"; if (C->isParamIndexValid()) { @@ -687,10 +696,12 @@ void CommentASTToHTMLConverter::visitTParamCommandComment( << "\">"; else Result << "<dt class=\"tparam-name-index-other\">"; - } else + appendToResultWithHTMLEscaping(C->getParamName(FC)); + } else { Result << "<dt class=\"tparam-name-index-invalid\">"; - - appendToResultWithHTMLEscaping(C->getParamName()); + appendToResultWithHTMLEscaping(C->getParamNameAsWritten()); + } + Result << "</dt>"; if (C->isPositionValid()) { @@ -735,7 +746,7 @@ void CommentASTToHTMLConverter::visitVerbatimLineComment( } void CommentASTToHTMLConverter::visitFullComment(const FullComment *C) { - FullCommentParts Parts(C); + FullCommentParts Parts(C, Traits); bool FirstParagraphIsBrief = false; if (Parts.Brief) @@ -822,7 +833,7 @@ CXString clang_HTMLTagComment_getAsString(CXComment CXC) { return createCXString((const char *) 0); SmallString<128> HTML; - CommentASTToHTMLConverter Converter(HTML); + CommentASTToHTMLConverter Converter(0, HTML, getCommandTraits(CXC)); Converter.visit(HTC); return createCXString(HTML.str(), /* DupString = */ true); } @@ -833,7 +844,7 @@ CXString clang_FullComment_getAsHTML(CXComment CXC) { return createCXString((const char *) 0); SmallString<1024> HTML; - CommentASTToHTMLConverter Converter(HTML); + CommentASTToHTMLConverter Converter(FC, HTML, getCommandTraits(CXC)); Converter.visit(FC); return createCXString(HTML.str(), /* DupString = */ true); } @@ -845,9 +856,11 @@ class CommentASTToXMLConverter : public ConstCommentVisitor<CommentASTToXMLConverter> { public: /// \param Str accumulator for XML. - CommentASTToXMLConverter(const SourceManager &SM, - SmallVectorImpl<char> &Str) : - SM(SM), Result(Str) { } + CommentASTToXMLConverter(const FullComment *FC, + SmallVectorImpl<char> &Str, + const CommandTraits &Traits, + const SourceManager &SM) : + FC(FC), Result(Str), Traits(Traits), SM(SM) { } // Inline content. void visitTextComment(const TextComment *C); @@ -870,11 +883,27 @@ public: void appendToResultWithXMLEscaping(StringRef S); private: - const SourceManager &SM; + const FullComment *FC; /// Output stream for XML. llvm::raw_svector_ostream Result; + + const CommandTraits &Traits; + const SourceManager &SM; }; + +void getSourceTextOfDeclaration(const DeclInfo *ThisDecl, + SmallVectorImpl<char> &Str) { + ASTContext &Context = ThisDecl->CurrentDecl->getASTContext(); + const LangOptions &LangOpts = Context.getLangOpts(); + llvm::raw_svector_ostream OS(Str); + PrintingPolicy PPolicy(LangOpts); + PPolicy.SuppressAttributes = true; + PPolicy.TerseOutput = true; + ThisDecl->CurrentDecl->print(OS, PPolicy, + /*Indentation*/0, /*PrintInstantiation*/true); +} + } // end unnamed namespace void CommentASTToXMLConverter::visitTextComment(const TextComment *C) { @@ -947,7 +976,8 @@ void CommentASTToXMLConverter::visitBlockCommandComment(const BlockCommandCommen void CommentASTToXMLConverter::visitParamCommandComment(const ParamCommandComment *C) { Result << "<Parameter><Name>"; - appendToResultWithXMLEscaping(C->getParamName()); + appendToResultWithXMLEscaping(C->isParamIndexValid() ? C->getParamName(FC) + : C->getParamNameAsWritten()); Result << "</Name>"; if (C->isParamIndexValid()) @@ -973,7 +1003,8 @@ void CommentASTToXMLConverter::visitParamCommandComment(const ParamCommandCommen void CommentASTToXMLConverter::visitTParamCommandComment( const TParamCommandComment *C) { Result << "<Parameter><Name>"; - appendToResultWithXMLEscaping(C->getParamName()); + appendToResultWithXMLEscaping(C->isPositionValid() ? C->getParamName(FC) + : C->getParamNameAsWritten()); Result << "</Name>"; if (C->isPositionValid() && C->getDepth() == 1) { @@ -991,7 +1022,7 @@ void CommentASTToXMLConverter::visitVerbatimBlockComment( if (NumLines == 0) return; - Result << llvm::StringSwitch<const char *>(C->getCommandName()) + Result << llvm::StringSwitch<const char *>(C->getCommandName(Traits)) .Case("code", "<Verbatim xml:space=\"preserve\" kind=\"code\">") .Default("<Verbatim xml:space=\"preserve\" kind=\"verbatim\">"); for (unsigned i = 0; i != NumLines; ++i) { @@ -1015,7 +1046,7 @@ void CommentASTToXMLConverter::visitVerbatimLineComment( } void CommentASTToXMLConverter::visitFullComment(const FullComment *C) { - FullCommentParts Parts(C); + FullCommentParts Parts(C, Traits); const DeclInfo *DI = C->getDeclInfo(); StringRef RootEndTag; @@ -1083,7 +1114,7 @@ void CommentASTToXMLConverter::visitFullComment(const FullComment *C) { { // Print line and column number. - SourceLocation Loc = DI->ThisDecl->getLocation(); + SourceLocation Loc = DI->CurrentDecl->getLocation(); std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); FileID FID = LocInfo.first; unsigned FileOffset = LocInfo.second; @@ -1104,7 +1135,7 @@ void CommentASTToXMLConverter::visitFullComment(const FullComment *C) { Result << ">"; bool FoundName = false; - if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->ThisDecl)) { + if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->CommentDecl)) { if (DeclarationName DeclName = ND->getDeclName()) { Result << "<Name>"; std::string Name = DeclName.getAsString(); @@ -1119,7 +1150,7 @@ void CommentASTToXMLConverter::visitFullComment(const FullComment *C) { { // Print USR. SmallString<128> USR; - cxcursor::getDeclCursorUSR(DI->ThisDecl, USR); + cxcursor::getDeclCursorUSR(DI->CommentDecl, USR); if (!USR.empty()) { Result << "<USR>"; appendToResultWithXMLEscaping(USR); @@ -1132,6 +1163,15 @@ void CommentASTToXMLConverter::visitFullComment(const FullComment *C) { Result << "<Other><Name>unknown</Name>"; } + { + // Pretty-print the declaration. + Result << "<Declaration>"; + SmallString<128> Declaration; + getSourceTextOfDeclaration(DI, Declaration); + appendToResultWithXMLEscaping(Declaration); + Result << "</Declaration>"; + } + bool FirstParagraphIsBrief = false; if (Parts.Brief) { Result << "<Abstract>"; @@ -1163,6 +1203,72 @@ void CommentASTToXMLConverter::visitFullComment(const FullComment *C) { visit(Parts.Returns); Result << "</ResultDiscussion>"; } + + if (DI->CommentDecl->hasAttrs()) { + const AttrVec &Attrs = DI->CommentDecl->getAttrs(); + for (unsigned i = 0, e = Attrs.size(); i != e; i++) { + const AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attrs[i]); + if (!AA) { + if (const DeprecatedAttr *DA = dyn_cast<DeprecatedAttr>(Attrs[i])) { + if (DA->getMessage().empty()) + Result << "<Deprecated/>"; + else { + Result << "<Deprecated>"; + appendToResultWithXMLEscaping(DA->getMessage()); + Result << "</Deprecated>"; + } + } + else if (const UnavailableAttr *UA = dyn_cast<UnavailableAttr>(Attrs[i])) { + if (UA->getMessage().empty()) + Result << "<Unavailable/>"; + else { + Result << "<Unavailable>"; + appendToResultWithXMLEscaping(UA->getMessage()); + Result << "</Unavailable>"; + } + } + continue; + } + + // 'availability' attribute. + Result << "<Availability"; + StringRef Distribution; + if (AA->getPlatform()) { + Distribution = AvailabilityAttr::getPrettyPlatformName( + AA->getPlatform()->getName()); + if (Distribution.empty()) + Distribution = AA->getPlatform()->getName(); + } + Result << " distribution=\"" << Distribution << "\">"; + VersionTuple IntroducedInVersion = AA->getIntroduced(); + if (!IntroducedInVersion.empty()) { + Result << "<IntroducedInVersion>" + << IntroducedInVersion.getAsString() + << "</IntroducedInVersion>"; + } + VersionTuple DeprecatedInVersion = AA->getDeprecated(); + if (!DeprecatedInVersion.empty()) { + Result << "<DeprecatedInVersion>" + << DeprecatedInVersion.getAsString() + << "</DeprecatedInVersion>"; + } + VersionTuple RemovedAfterVersion = AA->getObsoleted(); + if (!RemovedAfterVersion.empty()) { + Result << "<RemovedAfterVersion>" + << RemovedAfterVersion.getAsString() + << "</RemovedAfterVersion>"; + } + StringRef DeprecationSummary = AA->getMessage(); + if (!DeprecationSummary.empty()) { + Result << "<DeprecationSummary>"; + appendToResultWithXMLEscaping(DeprecationSummary); + Result << "</DeprecationSummary>"; + } + if (AA->getUnavailable()) + Result << "<Unavailable/>"; + Result << "</Availability>"; + } + } { bool StartTagEmitted = false; @@ -1213,15 +1319,16 @@ void CommentASTToXMLConverter::appendToResultWithXMLEscaping(StringRef S) { extern "C" { -CXString clang_FullComment_getAsXML(CXTranslationUnit TU, CXComment CXC) { +CXString clang_FullComment_getAsXML(CXComment CXC) { const FullComment *FC = getASTNodeAs<FullComment>(CXC); if (!FC) return createCXString((const char *) 0); + CXTranslationUnit TU = CXC.TranslationUnit; SourceManager &SM = static_cast<ASTUnit *>(TU->TUData)->getSourceManager(); SmallString<1024> XML; - CommentASTToXMLConverter Converter(SM, XML); + CommentASTToXMLConverter Converter(FC, XML, getCommandTraits(CXC), SM); Converter.visit(FC); return createCXString(XML.str(), /* DupString = */ true); } diff --git a/tools/libclang/CXComment.h b/tools/libclang/CXComment.h index 753877e..5134317 100644 --- a/tools/libclang/CXComment.h +++ b/tools/libclang/CXComment.h @@ -15,20 +15,29 @@ #define LLVM_CLANG_CXCOMMENT_H #include "clang-c/Index.h" +#include "CXTranslationUnit.h" #include "clang/AST/Comment.h" +#include "clang/AST/ASTContext.h" +#include "clang/Frontend/ASTUnit.h" namespace clang { +namespace comments { + class CommandTraits; +} + namespace cxcomment { -inline CXComment createCXComment(const comments::Comment *C) { +inline CXComment createCXComment(const comments::Comment *C, + CXTranslationUnit TU) { CXComment Result; - Result.Data = C; + Result.ASTNode = C; + Result.TranslationUnit = TU; return Result; } inline const comments::Comment *getASTNode(CXComment CXC) { - return static_cast<const comments::Comment *>(CXC.Data); + return static_cast<const comments::Comment *>(CXC.ASTNode); } template<typename T> @@ -40,6 +49,14 @@ inline const T *getASTNodeAs(CXComment CXC) { return dyn_cast<T>(C); } +inline ASTContext &getASTContext(CXComment CXC) { + return static_cast<ASTUnit *>(CXC.TranslationUnit->TUData)->getASTContext(); +} + +inline comments::CommandTraits &getCommandTraits(CXComment CXC) { + return getASTContext(CXC).getCommentCommandTraits(); +} + } // end namespace cxcomment } // end namespace clang diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index 2757af4..8d3e169 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -15,6 +15,7 @@ #include "CXTranslationUnit.h" #include "CXCursor.h" +#include "CXType.h" #include "CXString.h" #include "clang/Frontend/ASTUnit.h" #include "clang/AST/Decl.h" @@ -145,8 +146,8 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, CXTranslationUnit TU, K = CXCursor_ReturnStmt; break; - case Stmt::AsmStmtClass: - K = CXCursor_AsmStmt; + case Stmt::GCCAsmStmtClass: + K = CXCursor_GCCAsmStmt; break; case Stmt::MSAsmStmtClass: @@ -432,6 +433,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, CXTranslationUnit TU, case Stmt::DependentScopeDeclRefExprClass: case Stmt::SubstNonTypeTemplateParmExprClass: case Stmt::SubstNonTypeTemplateParmPackExprClass: + case Stmt::FunctionParmPackExprClass: case Stmt::UnresolvedLookupExprClass: K = CXCursor_DeclRefExpr; break; @@ -794,194 +796,20 @@ CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) { return static_cast<CXTranslationUnit>(Cursor.data[2]); } -static void CollectOverriddenMethodsRecurse(CXTranslationUnit TU, - ObjCContainerDecl *Container, - ObjCMethodDecl *Method, - SmallVectorImpl<CXCursor> &Methods, - bool MovedToSuper) { - if (!Container) - return; - - // In categories look for overriden methods from protocols. A method from - // category is not "overriden" since it is considered as the "same" method - // (same USR) as the one from the interface. - if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) { - // Check whether we have a matching method at this category but only if we - // are at the super class level. - if (MovedToSuper) - if (ObjCMethodDecl * - Overridden = Container->getMethod(Method->getSelector(), - Method->isInstanceMethod())) - if (Method != Overridden) { - // We found an override at this category; there is no need to look - // into its protocols. - Methods.push_back(MakeCXCursor(Overridden, TU)); - return; - } - - for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(), - PEnd = Category->protocol_end(); - P != PEnd; ++P) - CollectOverriddenMethodsRecurse(TU, *P, Method, Methods, MovedToSuper); - return; - } - - // Check whether we have a matching method at this level. - if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(), - Method->isInstanceMethod())) - if (Method != Overridden) { - // We found an override at this level; there is no need to look - // into other protocols or categories. - Methods.push_back(MakeCXCursor(Overridden, TU)); - return; - } - - if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) { - for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(), - PEnd = Protocol->protocol_end(); - P != PEnd; ++P) - CollectOverriddenMethodsRecurse(TU, *P, Method, Methods, MovedToSuper); - } - - if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) { - for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(), - PEnd = Interface->protocol_end(); - P != PEnd; ++P) - CollectOverriddenMethodsRecurse(TU, *P, Method, Methods, MovedToSuper); - - for (ObjCCategoryDecl *Category = Interface->getCategoryList(); - Category; Category = Category->getNextClassCategory()) - CollectOverriddenMethodsRecurse(TU, Category, Method, Methods, - MovedToSuper); - - if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) - return CollectOverriddenMethodsRecurse(TU, Super, Method, Methods, - /*MovedToSuper=*/true); - } -} - -static inline void CollectOverriddenMethods(CXTranslationUnit TU, - ObjCContainerDecl *Container, - ObjCMethodDecl *Method, - SmallVectorImpl<CXCursor> &Methods) { - CollectOverriddenMethodsRecurse(TU, Container, Method, Methods, - /*MovedToSuper=*/false); -} - -static void collectOverriddenMethodsSlow(CXTranslationUnit TU, - ObjCMethodDecl *Method, - SmallVectorImpl<CXCursor> &overridden) { - assert(Method->isOverriding()); - - if (ObjCProtocolDecl * - ProtD = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) { - CollectOverriddenMethods(TU, ProtD, Method, overridden); - - } else if (ObjCImplDecl * - IMD = dyn_cast<ObjCImplDecl>(Method->getDeclContext())) { - ObjCInterfaceDecl *ID = IMD->getClassInterface(); - if (!ID) - return; - // Start searching for overridden methods using the method from the - // interface as starting point. - if (ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(), - Method->isInstanceMethod())) - Method = IFaceMeth; - CollectOverriddenMethods(TU, ID, Method, overridden); - - } else if (ObjCCategoryDecl * - CatD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) { - ObjCInterfaceDecl *ID = CatD->getClassInterface(); - if (!ID) - return; - // Start searching for overridden methods using the method from the - // interface as starting point. - if (ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(), - Method->isInstanceMethod())) - Method = IFaceMeth; - CollectOverriddenMethods(TU, ID, Method, overridden); - - } else { - CollectOverriddenMethods(TU, - dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()), - Method, overridden); - } -} - -static void collectOnCategoriesAfterLocation(SourceLocation Loc, - ObjCInterfaceDecl *Class, - CXTranslationUnit TU, - ObjCMethodDecl *Method, - SmallVectorImpl<CXCursor> &Methods) { - if (!Class) - return; - - SourceManager &SM = static_cast<ASTUnit *>(TU->TUData)->getSourceManager(); - for (ObjCCategoryDecl *Category = Class->getCategoryList(); - Category; Category = Category->getNextClassCategory()) - if (SM.isBeforeInTranslationUnit(Loc, Category->getLocation())) - CollectOverriddenMethodsRecurse(TU, Category, Method, Methods, true); - - collectOnCategoriesAfterLocation(Loc, Class->getSuperClass(), TU, - Method, Methods); -} - -/// \brief Faster collection that is enabled when ObjCMethodDecl::isOverriding() -/// returns false. -/// You'd think that in that case there are no overrides but categories can -/// "introduce" new overridden methods that are missed by Sema because the -/// overrides lookup that it does for methods, inside implementations, will -/// stop at the interface level (if there is a method there) and not look -/// further in super classes. -static void collectOverriddenMethodsFast(CXTranslationUnit TU, - ObjCMethodDecl *Method, - SmallVectorImpl<CXCursor> &Methods) { - assert(!Method->isOverriding()); - - ObjCContainerDecl *ContD = cast<ObjCContainerDecl>(Method->getDeclContext()); - if (isa<ObjCInterfaceDecl>(ContD) || isa<ObjCProtocolDecl>(ContD)) - return; - ObjCInterfaceDecl *Class = Method->getClassInterface(); - if (!Class) - return; - - collectOnCategoriesAfterLocation(Class->getLocation(), Class->getSuperClass(), - TU, Method, Methods); -} - void cxcursor::getOverriddenCursors(CXCursor cursor, SmallVectorImpl<CXCursor> &overridden) { assert(clang_isDeclaration(cursor.kind)); - Decl *D = getCursorDecl(cursor); + const NamedDecl *D = dyn_cast_or_null<NamedDecl>(getCursorDecl(cursor)); if (!D) return; - // Handle C++ member functions. CXTranslationUnit TU = getCursorTU(cursor); - if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) { - for (CXXMethodDecl::method_iterator - M = CXXMethod->begin_overridden_methods(), - MEnd = CXXMethod->end_overridden_methods(); - M != MEnd; ++M) - overridden.push_back(MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU)); - return; - } - - ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D); - if (!Method) - return; + SmallVector<const NamedDecl *, 8> OverDecls; + D->getASTContext().getOverriddenMethods(D, OverDecls); - if (Method->isRedeclaration()) { - Method = cast<ObjCContainerDecl>(Method->getDeclContext())-> - getMethod(Method->getSelector(), Method->isInstanceMethod()); - } - - if (!Method->isOverriding()) { - collectOverriddenMethodsFast(TU, Method, overridden); - } else { - collectOverriddenMethodsSlow(TU, Method, overridden); - assert(!overridden.empty() && - "ObjCMethodDecl's overriding bit is not as expected"); + for (SmallVector<const NamedDecl *, 8>::iterator + I = OverDecls.begin(), E = OverDecls.end(); I != E; ++I) { + overridden.push_back(MakeCXCursor(const_cast<NamedDecl*>(*I), TU)); } } @@ -1345,4 +1173,16 @@ int clang_Cursor_isDynamicCall(CXCursor C) { return 0; } +CXType clang_Cursor_getReceiverType(CXCursor C) { + CXTranslationUnit TU = cxcursor::getCursorTU(C); + const Expr *E = 0; + if (clang_isExpression(C.kind)) + E = getCursorExpr(C); + + if (const ObjCMessageExpr *MsgE = dyn_cast_or_null<ObjCMessageExpr>(E)) + return cxtype::MakeCXType(MsgE->getReceiverType(), TU); + + return cxtype::MakeCXType(QualType(), TU); +} + } // end: extern "C" diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp index 15f818a..4e031d2 100644 --- a/tools/libclang/CXType.cpp +++ b/tools/libclang/CXType.cpp @@ -464,6 +464,7 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) { TCALLINGCONV(X86Pascal); TCALLINGCONV(AAPCS); TCALLINGCONV(AAPCS_VFP); + TCALLINGCONV(PnaclCall); } #undef TCALLINGCONV } @@ -615,7 +616,7 @@ long long clang_getArraySize(CXType CT) { } CXString clang_getDeclObjCTypeEncoding(CXCursor C) { - if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl)) + if (!clang_isDeclaration(C.kind)) return cxstring::createCXString(""); Decl *D = static_cast<Decl*>(C.data[0]); diff --git a/tools/libclang/CursorVisitor.h b/tools/libclang/CursorVisitor.h index 88b70a4..7cf7508 100644 --- a/tools/libclang/CursorVisitor.h +++ b/tools/libclang/CursorVisitor.h @@ -1,4 +1,4 @@ -//===- CursorVisitor.h - CursorVisitor interface --------------------------===// +//===- CursorVisitor.h - CursorVisitor interface ----------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -32,7 +32,7 @@ public: NestedNameSpecifierLocVisitKind, DeclarationNameInfoVisitKind, MemberRefVisitKind, SizeOfPackExprPartsKind, - LambdaExprPartsKind }; + LambdaExprPartsKind, PostChildrenVisitKind }; protected: void *data[3]; CXCursor parent; @@ -46,7 +46,6 @@ protected: public: Kind getKind() const { return K; } const CXCursor &getParent() const { return parent; } - static bool classof(VisitorJob *VJ) { return true; } }; typedef SmallVector<VisitorJob, 10> VisitorWorkList; @@ -55,6 +54,13 @@ typedef SmallVector<VisitorJob, 10> VisitorWorkList; class CursorVisitor : public DeclVisitor<CursorVisitor, bool>, public TypeLocVisitor<CursorVisitor, bool> { +public: + /// \brief Callback called after child nodes of a cursor have been visited. + /// Return true to break visitation or false to continue. + typedef bool (*PostChildrenVisitorTy)(CXCursor cursor, + CXClientData client_data); + +private: /// \brief The translation unit we are traversing. CXTranslationUnit TU; ASTUnit *AU; @@ -69,6 +75,8 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>, /// \brief The visitor function. CXCursorVisitor Visitor; + PostChildrenVisitorTy PostChildrenVisitor; + /// \brief The opaque client data, to be passed along to the visitor. CXClientData ClientData; @@ -137,9 +145,11 @@ public: bool VisitPreprocessorLast, bool VisitIncludedPreprocessingEntries = false, SourceRange RegionOfInterest = SourceRange(), - bool VisitDeclsOnly = false) + bool VisitDeclsOnly = false, + PostChildrenVisitorTy PostChildrenVisitor = 0) : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)), - Visitor(Visitor), ClientData(ClientData), + Visitor(Visitor), PostChildrenVisitor(PostChildrenVisitor), + ClientData(ClientData), VisitPreprocessorLast(VisitPreprocessorLast), VisitIncludedEntities(VisitIncludedPreprocessingEntries), RegionOfInterest(RegionOfInterest), diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp index acf8838..3614206 100644 --- a/tools/libclang/IndexBody.cpp +++ b/tools/libclang/IndexBody.cpp @@ -130,8 +130,20 @@ public: } bool VisitDeclStmt(DeclStmt *S) { - if (IndexCtx.shouldIndexFunctionLocalSymbols()) + if (IndexCtx.shouldIndexFunctionLocalSymbols()) { IndexCtx.indexDeclGroupRef(S->getDeclGroup()); + return true; + } + + DeclGroupRef DG = S->getDeclGroup(); + for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) { + const Decl *D = *I; + if (!D) + continue; + if (!IndexCtx.isFunctionLocalDecl(D)) + IndexCtx.indexTopLevelDecl(D); + } + return true; } diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp index 7560398..4b6706f 100644 --- a/tools/libclang/IndexDecl.cpp +++ b/tools/libclang/IndexDecl.cpp @@ -110,7 +110,7 @@ public: return true; } - bool VisitTypedefDecl(TypedefNameDecl *D) { + bool VisitTypedefNameDecl(TypedefNameDecl *D) { IndexCtx.handleTypedefName(D); IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); return true; @@ -194,7 +194,7 @@ public: bool VisitObjCMethodDecl(ObjCMethodDecl *D) { // Methods associated with a property, even user-declared ones, are // handled when we handle the property. - if (D->isSynthesized()) + if (D->isPropertyAccessor()) return true; handleObjCMethod(D); @@ -228,12 +228,12 @@ public: } if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) { - if (MD->isSynthesized()) + if (MD->isPropertyAccessor()) IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation(), D->getLexicalDeclContext()); } if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) { - if (MD->isSynthesized()) + if (MD->isPropertyAccessor()) IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation(), D->getLexicalDeclContext()); } @@ -305,6 +305,11 @@ public: IndexCtx.indexTypeSourceInfo(D->getTemplatedDecl()->getTypeSourceInfo(), D); return true; } + + bool VisitImportDecl(ImportDecl *D) { + IndexCtx.importedModule(D); + return true; + } }; } // anonymous namespace @@ -325,7 +330,7 @@ void IndexingContext::indexDeclContext(const DeclContext *DC) { } } -void IndexingContext::indexTopLevelDecl(Decl *D) { +void IndexingContext::indexTopLevelDecl(const Decl *D) { if (isNotFromSourceFile(D->getLocation())) return; diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp index 8fe9c36..714a36e 100644 --- a/tools/libclang/Indexing.cpp +++ b/tools/libclang/Indexing.cpp @@ -68,13 +68,15 @@ public: const Token &IncludeTok, StringRef FileName, bool IsAngled, + CharSourceRange FilenameRange, const FileEntry *File, - SourceLocation EndLoc, StringRef SearchPath, - StringRef RelativePath) { + StringRef RelativePath, + const Module *Imported) { bool isImport = (IncludeTok.is(tok::identifier) && IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import); - IndexCtx.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled); + IndexCtx.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled, + Imported); } /// MacroDefined - This hook is called whenever a macro definition is seen. @@ -189,6 +191,13 @@ public: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); + + if (!PPOpts.ImplicitPCHInclude.empty()) { + IndexCtx.importedPCH( + CI.getFileManager().getFile(PPOpts.ImplicitPCHInclude)); + } + IndexCtx.setASTContext(CI.getASTContext()); Preprocessor &PP = CI.getPreprocessor(); PP.addPPCallbacks(new IndexPPCallbacks(PP, IndexCtx)); @@ -281,13 +290,13 @@ static void clang_indexSourceFile_Impl(void *UserData) { CaptureDiagnosticConsumer *CaptureDiag = new CaptureDiagnosticConsumer(); // Configure the diagnostics. - DiagnosticOptions DiagOpts; IntrusiveRefCntPtr<DiagnosticsEngine> - Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args, - command_line_args, - CaptureDiag, - /*ShouldOwnClient=*/true, - /*ShouldCloneClient=*/false)); + Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions, + num_command_line_args, + command_line_args, + CaptureDiag, + /*ShouldOwnClient=*/true, + /*ShouldCloneClient=*/false)); // Recover resources if we crash before exiting this function. llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine, @@ -346,9 +355,6 @@ static void clang_indexSourceFile_Impl(void *UserData) { // precompiled headers are involved), we disable it. CInvok->getLangOpts()->SpellChecking = false; - if (!requestedToGetTU) - CInvok->getPreprocessorOpts().DetailedRecord = false; - if (index_options & CXIndexOpt_SuppressWarnings) CInvok->getDiagnosticOpts().IgnoreWarnings = true; @@ -374,7 +380,6 @@ static void clang_indexSourceFile_Impl(void *UserData) { bool PrecompilePreamble = false; bool CacheCodeCompletionResults = false; PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts(); - PPOpts.DetailedRecord = false; PPOpts.AllowPCHWithCompilerErrors = true; if (requestedToGetTU) { @@ -383,11 +388,15 @@ static void clang_indexSourceFile_Impl(void *UserData) { // FIXME: Add a flag for modules. CacheCodeCompletionResults = TU_options & CXTranslationUnit_CacheCompletionResults; - if (TU_options & CXTranslationUnit_DetailedPreprocessingRecord) { - PPOpts.DetailedRecord = true; - } } + if (TU_options & CXTranslationUnit_DetailedPreprocessingRecord) { + PPOpts.DetailedRecord = true; + } + + if (!requestedToGetTU && !CInvok->getLangOpts()->Modules) + PPOpts.DetailedRecord = false; + DiagnosticErrorTrap DiagTrap(*Diags); bool Success = ASTUnit::LoadFromCompilerInvocationAction(CInvok.getPtr(), Diags, IndexAction.get(), @@ -435,57 +444,39 @@ static void indexPreprocessingRecord(ASTUnit &Unit, IndexingContext &IdxCtx) { if (!PP.getPreprocessingRecord()) return; - PreprocessingRecord &PPRec = *PP.getPreprocessingRecord(); - // FIXME: Only deserialize inclusion directives. - // FIXME: Only deserialize stuff from the last chained PCH, not the PCH/Module - // that it depends on. - bool OnlyLocal = !Unit.isMainFileAST() && Unit.getOnlyLocalDecls(); PreprocessingRecord::iterator I, E; - if (OnlyLocal) { - I = PPRec.local_begin(); - E = PPRec.local_end(); - } else { - I = PPRec.begin(); - E = PPRec.end(); - } + llvm::tie(I, E) = Unit.getLocalPreprocessingEntities(); + bool isModuleFile = Unit.isModuleFile(); for (; I != E; ++I) { PreprocessedEntity *PPE = *I; if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) { - IdxCtx.ppIncludedFile(ID->getSourceRange().getBegin(), ID->getFileName(), - ID->getFile(), ID->getKind() == InclusionDirective::Import, - !ID->wasInQuotes()); + SourceLocation Loc = ID->getSourceRange().getBegin(); + // Modules have synthetic main files as input, give an invalid location + // if the location points to such a file. + if (isModuleFile && Unit.isInMainFileID(Loc)) + Loc = SourceLocation(); + IdxCtx.ppIncludedFile(Loc, ID->getFileName(), + ID->getFile(), + ID->getKind() == InclusionDirective::Import, + !ID->wasInQuotes(), ID->importedModule()); } } } -static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IdxCtx) { - // FIXME: Only deserialize stuff from the last chained PCH, not the PCH/Module - // that it depends on. - - bool OnlyLocal = !Unit.isMainFileAST() && Unit.getOnlyLocalDecls(); - - if (OnlyLocal) { - for (ASTUnit::top_level_iterator TL = Unit.top_level_begin(), - TLEnd = Unit.top_level_end(); - TL != TLEnd; ++TL) { - IdxCtx.indexTopLevelDecl(*TL); - if (IdxCtx.shouldAbort()) - return; - } +static bool topLevelDeclVisitor(void *context, const Decl *D) { + IndexingContext &IdxCtx = *static_cast<IndexingContext*>(context); + IdxCtx.indexTopLevelDecl(D); + if (IdxCtx.shouldAbort()) + return false; + return true; +} - } else { - TranslationUnitDecl *TUDecl = Unit.getASTContext().getTranslationUnitDecl(); - for (TranslationUnitDecl::decl_iterator - I = TUDecl->decls_begin(), E = TUDecl->decls_end(); I != E; ++I) { - IdxCtx.indexTopLevelDecl(*I); - if (IdxCtx.shouldAbort()) - return; - } - } +static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IdxCtx) { + Unit.visitLocalTopLevelDecls(&IdxCtx, topLevelDeclVisitor); } static void indexDiagnostics(CXTranslationUnit TU, IndexingContext &IdxCtx) { @@ -539,6 +530,11 @@ static void clang_indexTranslationUnit_Impl(void *UserData) { if (!Unit) return; + ASTUnit::ConcurrencyCheck Check(*Unit); + + if (const FileEntry *PCHFile = Unit->getPCHFile()) + IndexCtx->importedPCH(PCHFile); + FileManager &FileMgr = Unit->getFileManager(); if (Unit->getOriginalSourceFileName().empty()) diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp index ace5c75..d4daa49 100644 --- a/tools/libclang/IndexingContext.cpp +++ b/tools/libclang/IndexingContext.cpp @@ -1,4 +1,4 @@ -//===- CIndexHigh.cpp - Higher level API functions ------------------------===// +//===- IndexingContext.cpp - Higher level API functions -------------------===// // // The LLVM Compiler Infrastructure // @@ -204,6 +204,26 @@ void IndexingContext::setPreprocessor(Preprocessor &PP) { static_cast<ASTUnit*>(CXTU->TUData)->setPreprocessor(&PP); } +bool IndexingContext::isFunctionLocalDecl(const Decl *D) { + assert(D); + + if (!D->getParentFunctionOrMethod()) + return false; + + if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { + switch (ND->getLinkage()) { + case NoLinkage: + case InternalLinkage: + return true; + case UniqueExternalLinkage: + case ExternalLinkage: + return false; + } + } + + return true; +} + bool IndexingContext::shouldAbort() { if (!CB.abortQuery) return false; @@ -220,7 +240,8 @@ void IndexingContext::enteredMainFile(const FileEntry *File) { void IndexingContext::ppIncludedFile(SourceLocation hashLoc, StringRef filename, const FileEntry *File, - bool isImport, bool isAngled) { + bool isImport, bool isAngled, + bool isModuleImport) { if (!CB.ppIncludedFile) return; @@ -228,11 +249,44 @@ void IndexingContext::ppIncludedFile(SourceLocation hashLoc, CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc), SA.toCStr(filename), (CXFile)File, - isImport, isAngled }; + isImport, isAngled, isModuleImport }; CXIdxClientFile idxFile = CB.ppIncludedFile(ClientData, &Info); FileMap[File] = idxFile; } +void IndexingContext::importedModule(const ImportDecl *ImportD) { + if (!CB.importedASTFile) + return; + + Module *Mod = ImportD->getImportedModule(); + if (!Mod) + return; + std::string ModuleName = Mod->getFullModuleName(); + + CXIdxImportedASTFileInfo Info = { + (CXFile)Mod->getASTFile(), + Mod, + getIndexLoc(ImportD->getLocation()), + ImportD->isImplicit() + }; + CXIdxClientASTFile astFile = CB.importedASTFile(ClientData, &Info); + (void)astFile; +} + +void IndexingContext::importedPCH(const FileEntry *File) { + if (!CB.importedASTFile) + return; + + CXIdxImportedASTFileInfo Info = { + (CXFile)File, + /*module=*/NULL, + getIndexLoc(SourceLocation()), + /*isImplicit=*/false + }; + CXIdxClientASTFile astFile = CB.importedASTFile(ClientData, &Info); + (void)astFile; +} + void IndexingContext::startedTranslationUnit() { CXIdxClientContainer idxCont = 0; if (CB.startedTranslationUnit) @@ -590,7 +644,7 @@ bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc, return false; if (Loc.isInvalid()) return false; - if (!shouldIndexFunctionLocalSymbols() && D->getParentFunctionOrMethod()) + if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D)) return false; if (isNotFromSourceFile(D->getLocation())) return false; @@ -855,6 +909,10 @@ void IndexingContext::getEntityInfo(const NamedDecl *D, EntityInfo.kind = CXIdxEntity_CXXClass; EntityInfo.lang = CXIdxEntityLang_CXX; break; + case TTK_Interface: + EntityInfo.kind = CXIdxEntity_CXXInterface; + EntityInfo.lang = CXIdxEntityLang_CXX; + break; case TTK_Enum: EntityInfo.kind = CXIdxEntity_Enum; break; } @@ -1065,6 +1123,8 @@ bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) { return false; if (isa<ObjCMethodDecl>(D)) return false; + if (isa<ImportDecl>(D)) + return false; return true; } diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h index 00e1096..0fc7238 100644 --- a/tools/libclang/IndexingContext.h +++ b/tools/libclang/IndexingContext.h @@ -1,4 +1,4 @@ -//===- IndexingContext.h - Higher level API functions ------------------------===// +//===- IndexingContext.h - Higher level API functions -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -100,8 +100,6 @@ struct DeclInfo : public CXIdxDeclInfo { numAttributes = 0; declAsContainer = semanticContainer = lexicalContainer = 0; } - - static bool classof(const DeclInfo *) { return true; } }; struct ObjCContainerDeclInfo : public DeclInfo { @@ -126,7 +124,6 @@ struct ObjCContainerDeclInfo : public DeclInfo { static bool classof(const DeclInfo *D) { return Info_ObjCContainer <= D->Kind && D->Kind <= Info_ObjCCategory; } - static bool classof(const ObjCContainerDeclInfo *D) { return true; } private: void init(bool isForwardRef, bool isImplementation) { @@ -152,7 +149,6 @@ struct ObjCInterfaceDeclInfo : public ObjCContainerDeclInfo { static bool classof(const DeclInfo *D) { return D->Kind == Info_ObjCInterface; } - static bool classof(const ObjCInterfaceDeclInfo *D) { return true; } }; struct ObjCProtocolDeclInfo : public ObjCContainerDeclInfo { @@ -167,7 +163,6 @@ struct ObjCProtocolDeclInfo : public ObjCContainerDeclInfo { static bool classof(const DeclInfo *D) { return D->Kind == Info_ObjCProtocol; } - static bool classof(const ObjCProtocolDeclInfo *D) { return true; } }; struct ObjCCategoryDeclInfo : public ObjCContainerDeclInfo { @@ -183,7 +178,6 @@ struct ObjCCategoryDeclInfo : public ObjCContainerDeclInfo { static bool classof(const DeclInfo *D) { return D->Kind == Info_ObjCCategory; } - static bool classof(const ObjCCategoryDeclInfo *D) { return true; } }; struct ObjCPropertyDeclInfo : public DeclInfo { @@ -197,7 +191,6 @@ struct ObjCPropertyDeclInfo : public DeclInfo { static bool classof(const DeclInfo *D) { return D->Kind == Info_ObjCProperty; } - static bool classof(const ObjCPropertyDeclInfo *D) { return true; } }; struct CXXClassDeclInfo : public DeclInfo { @@ -209,7 +202,6 @@ struct CXXClassDeclInfo : public DeclInfo { static bool classof(const DeclInfo *D) { return D->Kind == Info_CXXClass; } - static bool classof(const CXXClassDeclInfo *D) { return true; } }; struct AttrInfo : public CXIdxAttrInfo { @@ -221,8 +213,6 @@ struct AttrInfo : public CXIdxAttrInfo { loc = Loc; this->A = A; } - - static bool classof(const AttrInfo *) { return true; } }; struct IBOutletCollectionInfo : public AttrInfo { @@ -240,7 +230,6 @@ struct IBOutletCollectionInfo : public AttrInfo { static bool classof(const AttrInfo *A) { return A->kind == CXIdxAttr_IBOutletCollection; } - static bool classof(const IBOutletCollectionInfo *D) { return true; } }; class AttrListInfo { @@ -251,8 +240,8 @@ class AttrListInfo { SmallVector<CXIdxAttrInfo *, 2> CXAttrs; unsigned ref_cnt; - AttrListInfo(const AttrListInfo&); // DO NOT IMPLEMENT - void operator=(const AttrListInfo&); // DO NOT IMPLEMENT + AttrListInfo(const AttrListInfo &) LLVM_DELETED_FUNCTION; + void operator=(const AttrListInfo &) LLVM_DELETED_FUNCTION; public: AttrListInfo(const Decl *D, IndexingContext &IdxCtx); @@ -370,6 +359,8 @@ public: return IndexOptions & CXIndexOpt_IndexImplicitTemplateInstantiations; } + static bool isFunctionLocalDecl(const Decl *D); + bool shouldAbort(); bool hasDiagnosticCallback() const { return CB.diagnostic; } @@ -378,7 +369,10 @@ public: void ppIncludedFile(SourceLocation hashLoc, StringRef filename, const FileEntry *File, - bool isImport, bool isAngled); + bool isImport, bool isAngled, bool isModuleImport); + + void importedModule(const ImportDecl *ImportD); + void importedPCH(const FileEntry *File); void startedTranslationUnit(); @@ -451,7 +445,7 @@ public: bool isNotFromSourceFile(SourceLocation Loc) const; - void indexTopLevelDecl(Decl *D); + void indexTopLevelDecl(const Decl *D); void indexTUDeclsInObjCContainer(); void indexDeclGroupRef(DeclGroupRef DG); diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile index 975d381..93f63cf 100644 --- a/tools/libclang/Makefile +++ b/tools/libclang/Makefile @@ -17,10 +17,11 @@ SHARED_LIBRARY = 1 include $(CLANG_LEVEL)/../../Makefile.config LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc -USEDLIBS = clangARCMigrate.a clangRewrite.a clangFrontend.a clangDriver.a \ - clangSerialization.a \ - clangParse.a clangSema.a clangEdit.a clangAnalysis.a \ - clangAST.a clangLex.a clangTooling.a clangBasic.a +USEDLIBS = clangARCMigrate.a clangRewriteCore.a clangRewriteFrontend.a \ + clangFrontend.a clangDriver.a \ + clangSerialization.a \ + clangParse.a clangSema.a clangEdit.a clangAnalysis.a \ + clangAST.a clangLex.a clangTooling.a clangBasic.a include $(CLANG_LEVEL)/Makefile @@ -51,4 +52,10 @@ ifeq ($(HOST_OS),Darwin) LLVMLibsOptions += -Wl,-install_name \ -Wl,"@rpath/lib$(LIBRARYNAME)$(SHLIBEXT)" endif + + # If we're doing an Apple-style build, add the LTO object path. + ifeq ($(RC_BUILDIT),YES) + TempFile := $(shell mkdir -p ${OBJROOT}/dSYMs ; mktemp ${OBJROOT}/dSYMs/clang-lto.XXXXXX) + LLVMLibsOptions += -Wl,-object_path_lto -Wl,$(TempFile) + endif endif diff --git a/tools/libclang/RecursiveASTVisitor.h b/tools/libclang/RecursiveASTVisitor.h index 7131025..4844204 100644 --- a/tools/libclang/RecursiveASTVisitor.h +++ b/tools/libclang/RecursiveASTVisitor.h @@ -657,6 +657,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument( case TemplateArgument::Null: case TemplateArgument::Declaration: case TemplateArgument::Integral: + case TemplateArgument::NullPtr: return true; case TemplateArgument::Type: @@ -689,6 +690,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc( case TemplateArgument::Null: case TemplateArgument::Declaration: case TemplateArgument::Integral: + case TemplateArgument::NullPtr: return true; case TemplateArgument::Type: { @@ -1753,7 +1755,7 @@ bool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) { \ return true; \ } -DEF_TRAVERSE_STMT(AsmStmt, { +DEF_TRAVERSE_STMT(GCCAsmStmt, { StmtQueue.queue(S->getAsmString()); for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) { StmtQueue.queue(S->getInputConstraintLiteral(I)); @@ -1762,7 +1764,7 @@ DEF_TRAVERSE_STMT(AsmStmt, { StmtQueue.queue(S->getOutputConstraintLiteral(I)); } for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) { - StmtQueue.queue(S->getClobber(I)); + StmtQueue.queue(S->getClobberStringLiteral(I)); } // children() iterates over inputExpr and outputExpr. }) @@ -2141,6 +2143,7 @@ DEF_TRAVERSE_STMT(PackExpansionExpr, { }) DEF_TRAVERSE_STMT(SizeOfPackExpr, { }) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { }) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { }) +DEF_TRAVERSE_STMT(FunctionParmPackExpr, { }) DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { }) DEF_TRAVERSE_STMT(AtomicExpr, { }) diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index 610bd91..4495b66 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -13,8 +13,15 @@ clang_Cursor_getNumArguments clang_Cursor_getObjCSelectorIndex clang_Cursor_getSpellingNameRange clang_Cursor_getTranslationUnit +clang_Cursor_getReceiverType clang_Cursor_isDynamicCall clang_Cursor_isNull +clang_Cursor_getModule +clang_Module_getParent +clang_Module_getName +clang_Module_getFullName +clang_Module_getNumTopLevelHeaders +clang_Module_getTopLevelHeader clang_IndexAction_create clang_IndexAction_dispose clang_Range_isNull |