summaryrefslogtreecommitdiffstats
path: root/tools/libclang
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libclang')
-rw-r--r--tools/libclang/CIndex.cpp202
-rw-r--r--tools/libclang/CIndexCXX.cpp3
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp8
-rw-r--r--tools/libclang/CIndexDiagnostic.cpp8
-rw-r--r--tools/libclang/CIndexUSRs.cpp44
-rw-r--r--tools/libclang/CMakeLists.txt3
-rw-r--r--tools/libclang/CXComment.cpp197
-rw-r--r--tools/libclang/CXComment.h23
-rw-r--r--tools/libclang/CXCursor.cpp204
-rw-r--r--tools/libclang/CXType.cpp3
-rw-r--r--tools/libclang/CursorVisitor.h20
-rw-r--r--tools/libclang/IndexBody.cpp14
-rw-r--r--tools/libclang/IndexDecl.cpp15
-rw-r--r--tools/libclang/Indexing.cpp104
-rw-r--r--tools/libclang/IndexingContext.cpp68
-rw-r--r--tools/libclang/IndexingContext.h26
-rw-r--r--tools/libclang/Makefile15
-rw-r--r--tools/libclang/RecursiveASTVisitor.h7
-rw-r--r--tools/libclang/libclang.exports7
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
OpenPOWER on IntegriCloud