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/CIndex.cpp | |
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/CIndex.cpp')
-rw-r--r-- | tools/libclang/CIndex.cpp | 202 |
1 files changed, 174 insertions, 28 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); |