summaryrefslogtreecommitdiffstats
path: root/tools/libclang/CIndex.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2012-12-02 13:20:44 +0000
committerdim <dim@FreeBSD.org>2012-12-02 13:20:44 +0000
commit056abd2059c65a3e908193aeae16fad98017437c (patch)
tree2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /tools/libclang/CIndex.cpp
parentcc73504950eb7b5dff2dded9bedd67bc36d64641 (diff)
downloadFreeBSD-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.cpp202
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);
OpenPOWER on IntegriCloud