summaryrefslogtreecommitdiffstats
path: root/tools/libclang
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
committerdim <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
commit952eddef9aff85b1e92626e89baaf7a360e2ac85 (patch)
treedf8df0b0067b381eab470a3b8f28d14a552a6340 /tools/libclang
parentea266cad53e3d49771fa38103913d3ec7a166694 (diff)
downloadFreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.zip
FreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.tar.gz
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
https://llvm.org/svn/llvm-project/cfe/branches/release_34@197841
Diffstat (limited to 'tools/libclang')
-rw-r--r--tools/libclang/CIndex.cpp318
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp22
-rw-r--r--tools/libclang/CIndexHigh.cpp2
-rw-r--r--tools/libclang/CIndexUSRs.cpp848
-rw-r--r--tools/libclang/CIndexer.cpp87
-rw-r--r--tools/libclang/CIndexer.h15
-rw-r--r--tools/libclang/CMakeLists.txt22
-rw-r--r--tools/libclang/CXComment.cpp1094
-rw-r--r--tools/libclang/CXComment.h12
-rw-r--r--tools/libclang/CXCompilationDatabase.cpp37
-rw-r--r--tools/libclang/CXCursor.cpp14
-rw-r--r--tools/libclang/CXSourceLocation.cpp41
-rw-r--r--tools/libclang/CXTranslationUnit.h7
-rw-r--r--tools/libclang/CXType.cpp70
-rw-r--r--tools/libclang/IndexBody.cpp4
-rw-r--r--tools/libclang/IndexDecl.cpp15
-rw-r--r--tools/libclang/Indexing.cpp44
-rw-r--r--tools/libclang/IndexingContext.cpp25
-rw-r--r--tools/libclang/IndexingContext.h35
-rw-r--r--tools/libclang/Makefile10
-rw-r--r--tools/libclang/RecursiveASTVisitor.h170
-rw-r--r--tools/libclang/SimpleFormatContext.h75
-rw-r--r--tools/libclang/libclang.exports5
23 files changed, 720 insertions, 2252 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index a43c1ab..f53e5c1 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -22,13 +22,14 @@
#include "CXTranslationUnit.h"
#include "CXType.h"
#include "CursorVisitor.h"
-#include "SimpleFormatContext.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/Version.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Index/CommentToXML.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/PreprocessingRecord.h"
@@ -42,7 +43,6 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
-#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/Signals.h"
@@ -68,8 +68,7 @@ CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
D->StringPool = new cxstring::CXStringPool();
D->Diagnostics = 0;
D->OverridenCursorsPool = createOverridenCXCursorsPool();
- D->FormatContext = 0;
- D->FormatInMemoryUniqueId = 0;
+ D->CommentToXML = 0;
return D;
}
@@ -308,8 +307,8 @@ bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
bool VisitedAtLeastOnce = false;
DeclContext *CurDC = 0;
- SmallVector<Decl *, 16>::iterator DIt = Decls.begin();
- for (SmallVector<Decl *, 16>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
+ SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
+ for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Decl *D = *DIt;
if (D->getSourceRange().isInvalid())
continue;
@@ -426,6 +425,9 @@ bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
continue;
PreprocessedEntity *PPE = *First;
+ if (!PPE)
+ continue;
+
if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
if (Visit(MakeMacroExpansionCursor(ME, TU)))
return true;
@@ -528,9 +530,10 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
const IBOutletCollectionAttr *A =
cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
- if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
- return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
- A->getInterfaceLoc(), TU));
+ if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
+ return Visit(cxcursor::MakeCursorObjCClassRef(
+ ObjT->getInterface(),
+ A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
}
// If pointing inside a macro definition, check if the token is an identifier
@@ -698,8 +701,9 @@ bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
return true;
// Visit the partial specialization arguments.
- const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
- for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
+ const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
+ const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
+ for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
if (VisitTemplateArgumentLoc(TemplateArgs[I]))
return true;
@@ -743,18 +747,9 @@ bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
}
/// \brief Compare two base or member initializers based on their source order.
-static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
- CXXCtorInitializer const * const *X
- = static_cast<CXXCtorInitializer const * const *>(Xp);
- CXXCtorInitializer const * const *Y
- = static_cast<CXXCtorInitializer const * const *>(Yp);
-
- if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
- return -1;
- else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
- return 1;
- else
- return 0;
+static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
+ CXXCtorInitializer *const *Y) {
+ return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
}
bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
@@ -1543,6 +1538,10 @@ bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
return false;
}
+bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
+ return Visit(TL.getOriginalLoc());
+}
+
bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
// Visit the template name.
@@ -1795,6 +1794,7 @@ public:
}
};
class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
+ friend class OMPClauseEnqueue;
VisitorWorkList &WL;
CXCursor Parent;
public:
@@ -1846,6 +1846,8 @@ public:
void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
void VisitLambdaExpr(const LambdaExpr *E);
+ void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
+ void VisitOMPParallelDirective(const OMPParallelDirective *D);
private:
void AddDeclarationNameInfo(const Stmt *S);
@@ -1856,6 +1858,7 @@ private:
void AddDecl(const Decl *D, bool isFirst = true);
void AddTypeLoc(TypeSourceInfo *TI);
void EnqueueChildren(const Stmt *S);
+ void EnqueueChildren(const OMPClause *S);
};
} // end anonyous namespace
@@ -1904,6 +1907,52 @@ void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
std::reverse(I, E);
}
+namespace {
+class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
+ EnqueueVisitor *Visitor;
+ /// \brief Process clauses with list of variables.
+ template <typename T>
+ void VisitOMPClauseList(T *Node);
+public:
+ OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
+#define OPENMP_CLAUSE(Name, Class) \
+ void Visit##Class(const Class *C);
+#include "clang/Basic/OpenMPKinds.def"
+};
+
+void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
+
+template<typename T>
+void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
+ for (typename T::varlist_const_iterator I = Node->varlist_begin(),
+ E = Node->varlist_end();
+ I != E; ++I)
+ Visitor->AddStmt(*I);
+}
+
+void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
+ VisitOMPClauseList(C);
+}
+void OMPClauseEnqueue::VisitOMPFirstprivateClause(
+ const OMPFirstprivateClause *C) {
+ VisitOMPClauseList(C);
+}
+void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
+ VisitOMPClauseList(C);
+}
+}
+
+void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
+ unsigned size = WL.size();
+ OMPClauseEnqueue Visitor(this);
+ Visitor.Visit(S);
+ if (size == WL.size())
+ return;
+ // Now reverse the entries we just added. This will match the DFS
+ // ordering performed by the worklist.
+ VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
+ std::reverse(I, E);
+}
void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
}
@@ -2027,7 +2076,6 @@ void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
}
void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
AddStmt(E->getInit());
- typedef DesignatedInitExpr::Designator Designator;
for (DesignatedInitExpr::const_reverse_designators_iterator
D = E->designators_rbegin(), DEnd = E->designators_rend();
D != DEnd; ++D) {
@@ -2182,6 +2230,19 @@ void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Visit(E->getSyntacticForm());
}
+void EnqueueVisitor::VisitOMPExecutableDirective(
+ const OMPExecutableDirective *D) {
+ EnqueueChildren(D);
+ for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
+ E = D->clauses().end();
+ I != E; ++I)
+ EnqueueChildren(*I);
+}
+
+void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
}
@@ -2198,8 +2259,7 @@ bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
while (!WL.empty()) {
// Dequeue the worklist item.
- VisitorJob LI = WL.back();
- WL.pop_back();
+ VisitorJob LI = WL.pop_back_val();
// Set the Parent field, then back to its old value once we're done.
SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
@@ -2363,9 +2423,10 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
CEnd = E->explicit_capture_end();
C != CEnd; ++C) {
- if (C->capturesThis())
+ // FIXME: Lambda init-captures.
+ if (!C->capturesVariable())
continue;
-
+
if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
C->getLocation(),
TU)))
@@ -2481,10 +2542,6 @@ static void fatal_error_handler(void *user_data, const std::string& reason,
extern "C" {
CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
int displayDiagnostics) {
- // Disable pretty stack trace functionality, which will otherwise be a very
- // poor citizen of the world and set up all sorts of signal handlers.
- llvm::DisablePrettyStackTrace = true;
-
// We use crash recovery to make some of our APIs more reliable, implicitly
// enable it.
llvm::CrashRecoveryContext::Enable();
@@ -2540,9 +2597,13 @@ void clang_toggleCrashRecovery(unsigned isEnabled) {
CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
const char *ast_filename) {
- if (!CIdx)
+ if (!CIdx || !ast_filename)
return 0;
+ LOG_FUNC_SECTION {
+ *Log << ast_filename;
+ }
+
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
FileSystemOptions FileSystemOpts;
@@ -2842,7 +2903,7 @@ void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
delete CTUnit->StringPool;
delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
- delete CTUnit->FormatContext;
+ delete CTUnit->CommentToXML;
delete CTUnit;
}
}
@@ -2995,15 +3056,12 @@ int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
if (!file || !outID)
return 1;
-#ifdef LLVM_ON_WIN32
- return 1; // inodes not supported on windows.
-#else
FileEntry *FEnt = static_cast<FileEntry *>(file);
- outID->data[0] = FEnt->getDevice();
- outID->data[1] = FEnt->getInode();
+ const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
+ outID->data[0] = ID.getDevice();
+ outID->data[1] = ID.getFile();
outID->data[2] = FEnt->getModificationTime();
return 0;
-#endif
}
} // end: extern "C"
@@ -3289,6 +3347,10 @@ CXString clang_getCursorSpelling(CXCursor C) {
return cxstring::createDup(AA->getLabel());
}
+ if (C.kind == CXCursor_PackedAttr) {
+ return cxstring::createRef("packed");
+ }
+
return cxstring::createEmpty();
}
@@ -3706,6 +3768,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("attribute(annotate)");
case CXCursor_AsmLabelAttr:
return cxstring::createRef("asm label");
+ case CXCursor_PackedAttr:
+ return cxstring::createRef("attribute(packed)");
case CXCursor_PreprocessingDirective:
return cxstring::createRef("preprocessing directive");
case CXCursor_MacroDefinition:
@@ -3754,6 +3818,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("CXXAccessSpecifier");
case CXCursor_ModuleImportDecl:
return cxstring::createRef("ModuleImport");
+ case CXCursor_OMPParallelDirective:
+ return cxstring::createRef("OMPParallelDirective");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -4111,6 +4177,12 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
return cxloc::translateSourceLocation(getCursorContext(C), L);
}
+ if (clang_isAttribute(C.kind)) {
+ SourceLocation L
+ = cxcursor::getCursorAttr(C)->getLocation();
+ return cxloc::translateSourceLocation(getCursorContext(C), L);
+ }
+
if (!clang_isDeclaration(C.kind))
return clang_getNullLocation();
@@ -4521,7 +4593,9 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
return clang_getNullCursor();
}
- case Decl::Var: {
+ case Decl::Var:
+ case Decl::VarTemplateSpecialization:
+ case Decl::VarTemplatePartialSpecialization: {
// Ask the variable if it has a definition.
if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
return MakeCXCursor(Def, TU);
@@ -4543,6 +4617,13 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
return clang_getNullCursor();
}
+ case Decl::VarTemplate: {
+ if (VarDecl *Def =
+ cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
+ return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
+ return clang_getNullCursor();
+ }
+
case Decl::Using:
return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
D->getLocation(), TU);
@@ -5171,6 +5252,11 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
HasContextSensitiveKeywords = true;
}
}
+
+ // Don't override a property annotation with its getter/setter method.
+ if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
+ parent.kind == CXCursor_ObjCPropertyDecl)
+ return CXChildVisit_Continue;
if (clang_isPreprocessing(cursor.kind)) {
// Items in the preprocessing record are kept separate from items in
@@ -5678,8 +5764,9 @@ CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
const Decl *D = cxcursor::getCursorDecl(cursor);
if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
- switch (ND->getLinkage()) {
- case NoLinkage: return CXLinkage_NoLinkage;
+ switch (ND->getLinkageInternal()) {
+ case NoLinkage:
+ case VisibleNoLinkage: return CXLinkage_NoLinkage;
case InternalLinkage: return CXLinkage_Internal;
case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
case ExternalLinkage: return CXLinkage_External;
@@ -5743,25 +5830,33 @@ static CXLanguageKind getDeclLanguage(const Decl *D) {
}
extern "C" {
+
+static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
+ if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
+ return CXAvailability_Available;
-enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
- if (clang_isDeclaration(cursor.kind))
- if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
- if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
- return CXAvailability_Available;
-
- switch (D->getAvailability()) {
- case AR_Available:
- case AR_NotYetIntroduced:
- return CXAvailability_Available;
+ switch (D->getAvailability()) {
+ case AR_Available:
+ case AR_NotYetIntroduced:
+ if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
+ return getCursorAvailabilityForDecl(
+ cast<Decl>(EnumConst->getDeclContext()));
+ return CXAvailability_Available;
- case AR_Deprecated:
- return CXAvailability_Deprecated;
+ case AR_Deprecated:
+ return CXAvailability_Deprecated;
- case AR_Unavailable:
- return CXAvailability_NotAvailable;
- }
- }
+ case AR_Unavailable:
+ return CXAvailability_NotAvailable;
+ }
+
+ llvm_unreachable("Unknown availability kind!");
+}
+
+enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
+ if (clang_isDeclaration(cursor.kind))
+ if (const Decl *D = cxcursor::getCursorDecl(cursor))
+ return getCursorAvailabilityForDecl(D);
return CXAvailability_Available;
}
@@ -5785,34 +5880,20 @@ static CXVersion convertVersion(VersionTuple In) {
return Out;
}
-
-int clang_getCursorPlatformAvailability(CXCursor cursor,
- int *always_deprecated,
- CXString *deprecated_message,
- int *always_unavailable,
- CXString *unavailable_message,
- CXPlatformAvailability *availability,
- int availability_size) {
- if (always_deprecated)
- *always_deprecated = 0;
- if (deprecated_message)
- *deprecated_message = cxstring::createEmpty();
- if (always_unavailable)
- *always_unavailable = 0;
- if (unavailable_message)
- *unavailable_message = cxstring::createEmpty();
-
- if (!clang_isDeclaration(cursor.kind))
- return 0;
-
- const Decl *D = cxcursor::getCursorDecl(cursor);
- if (!D)
- return 0;
-
+
+static int getCursorPlatformAvailabilityForDecl(const Decl *D,
+ int *always_deprecated,
+ CXString *deprecated_message,
+ int *always_unavailable,
+ CXString *unavailable_message,
+ CXPlatformAvailability *availability,
+ int availability_size) {
+ bool HadAvailAttr = false;
int N = 0;
for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
++A) {
if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
+ HadAvailAttr = true;
if (always_deprecated)
*always_deprecated = 1;
if (deprecated_message)
@@ -5821,6 +5902,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
}
if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
+ HadAvailAttr = true;
if (always_unavailable)
*always_unavailable = 1;
if (unavailable_message) {
@@ -5830,6 +5912,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
}
if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
+ HadAvailAttr = true;
if (N < availability_size) {
availability[N].Platform
= cxstring::createDup(Avail->getPlatform()->getName());
@@ -5842,9 +5925,51 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
++N;
}
}
+
+ if (!HadAvailAttr)
+ if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
+ return getCursorPlatformAvailabilityForDecl(
+ cast<Decl>(EnumConst->getDeclContext()),
+ always_deprecated,
+ deprecated_message,
+ always_unavailable,
+ unavailable_message,
+ availability,
+ availability_size);
return N;
}
+
+int clang_getCursorPlatformAvailability(CXCursor cursor,
+ int *always_deprecated,
+ CXString *deprecated_message,
+ int *always_unavailable,
+ CXString *unavailable_message,
+ CXPlatformAvailability *availability,
+ int availability_size) {
+ if (always_deprecated)
+ *always_deprecated = 0;
+ if (deprecated_message)
+ *deprecated_message = cxstring::createEmpty();
+ if (always_unavailable)
+ *always_unavailable = 0;
+ if (unavailable_message)
+ *unavailable_message = cxstring::createEmpty();
+
+ if (!clang_isDeclaration(cursor.kind))
+ return 0;
+
+ const Decl *D = cxcursor::getCursorDecl(cursor);
+ if (!D)
+ return 0;
+
+ return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
+ deprecated_message,
+ always_unavailable,
+ unavailable_message,
+ availability,
+ availability_size);
+}
void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
clang_disposeString(availability->Platform);
@@ -5974,6 +6099,19 @@ unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
return Result;
}
+unsigned clang_Cursor_isObjCOptional(CXCursor C) {
+ if (!clang_isDeclaration(C.kind))
+ return 0;
+
+ const Decl *D = getCursorDecl(C);
+ if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
+ return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+ return MD->getImplementationControl() == ObjCMethodDecl::Optional;
+
+ return 0;
+}
+
unsigned clang_Cursor_isVariadic(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
@@ -6114,6 +6252,20 @@ CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
//===----------------------------------------------------------------------===//
extern "C" {
+unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
+ if (!clang_isDeclaration(C.kind))
+ return 0;
+
+ const CXXMethodDecl *Method = 0;
+ const Decl *D = cxcursor::getCursorDecl(C);
+ if (const FunctionTemplateDecl *FunTmpl =
+ dyn_cast_or_null<FunctionTemplateDecl>(D))
+ Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
+ else
+ Method = dyn_cast_or_null<CXXMethodDecl>(D);
+ return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
+}
+
unsigned clang_CXXMethod_isStatic(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index f79de29..865bb58 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -27,10 +27,12 @@
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/Sema.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Atomic.h"
#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Timer.h"
@@ -271,7 +273,7 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
/// \brief Temporary files that should be removed once we have finished
/// with the code-completion results.
- std::vector<llvm::sys::Path> TemporaryFiles;
+ std::vector<std::string> TemporaryFiles;
/// \brief Temporary buffers that will be deleted once we have finished with
/// the code-completion results.
@@ -340,7 +342,7 @@ AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
delete [] Results;
for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
- TemporaryFiles[I].eraseFromDisk();
+ llvm::sys::fs::remove(TemporaryFiles[I]);
for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
delete TemporaryBuffers[I];
@@ -561,15 +563,13 @@ namespace {
AllocatedResults.Contexts = getContextsForContextKind(contextKind, S);
AllocatedResults.Selector = "";
- if (Context.getNumSelIdents() > 0) {
- for (unsigned i = 0; i < Context.getNumSelIdents(); i++) {
- IdentifierInfo *selIdent = Context.getSelIdents()[i];
- if (selIdent != NULL) {
- StringRef selectorString = Context.getSelIdents()[i]->getName();
- AllocatedResults.Selector += selectorString;
- }
- AllocatedResults.Selector += ":";
- }
+ ArrayRef<IdentifierInfo *> SelIdents = Context.getSelIdents();
+ for (ArrayRef<IdentifierInfo *>::iterator I = SelIdents.begin(),
+ E = SelIdents.end();
+ I != E; ++I) {
+ if (IdentifierInfo *selIdent = *I)
+ AllocatedResults.Selector += selIdent->getName();
+ AllocatedResults.Selector += ":";
}
QualType baseType = Context.getBaseType();
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
index 2a55af5..c772dbb 100644
--- a/tools/libclang/CIndexHigh.cpp
+++ b/tools/libclang/CIndexHigh.cpp
@@ -36,7 +36,7 @@ static void getTopOverriddenMethods(CXTranslationUnit TU,
return;
}
- for (SmallVector<CXCursor, 8>::iterator
+ for (SmallVectorImpl<CXCursor>::iterator
I = Overridden.begin(), E = Overridden.end(); I != E; ++I)
getTopOverriddenMethods(TU, cxcursor::getCursorDecl(*I), Methods);
}
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index a911ce5..2b43c5b 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -14,787 +14,13 @@
#include "CIndexer.h"
#include "CXCursor.h"
#include "CXString.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/Frontend/ASTUnit.h"
+#include "clang/Index/USRGeneration.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// USR generation.
-//===----------------------------------------------------------------------===//
-
-namespace {
-class USRGenerator : public ConstDeclVisitor<USRGenerator> {
- OwningPtr<SmallString<128> > OwnedBuf;
- SmallVectorImpl<char> &Buf;
- llvm::raw_svector_ostream Out;
- bool IgnoreResults;
- ASTContext *Context;
- bool generatedLoc;
-
- llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
-
-public:
- explicit USRGenerator(ASTContext *Ctx = 0, SmallVectorImpl<char> *extBuf = 0)
- : OwnedBuf(extBuf ? 0 : new SmallString<128>()),
- Buf(extBuf ? *extBuf : *OwnedBuf.get()),
- Out(Buf),
- IgnoreResults(false),
- Context(Ctx),
- generatedLoc(false)
- {
- // Add the USR space prefix.
- Out << "c:";
- }
-
- StringRef str() {
- return Out.str();
- }
-
- USRGenerator* operator->() { return this; }
-
- template <typename T>
- llvm::raw_svector_ostream &operator<<(const T &x) {
- Out << x;
- return Out;
- }
-
- bool ignoreResults() const { return IgnoreResults; }
-
- // Visitation methods from generating USRs from AST elements.
- void VisitDeclContext(const DeclContext *D);
- void VisitFieldDecl(const FieldDecl *D);
- void VisitFunctionDecl(const FunctionDecl *D);
- void VisitNamedDecl(const NamedDecl *D);
- void VisitNamespaceDecl(const NamespaceDecl *D);
- void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
- void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
- void VisitClassTemplateDecl(const ClassTemplateDecl *D);
- void VisitObjCContainerDecl(const ObjCContainerDecl *CD);
- void VisitObjCMethodDecl(const ObjCMethodDecl *MD);
- void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
- void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
- void VisitTagDecl(const TagDecl *D);
- void VisitTypedefDecl(const TypedefDecl *D);
- void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
- void VisitVarDecl(const VarDecl *D);
- void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
- void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
- void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
- IgnoreResults = true;
- }
- void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
- IgnoreResults = true;
- }
- void VisitUsingDecl(const UsingDecl *D) {
- IgnoreResults = true;
- }
- void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
- IgnoreResults = true;
- }
- void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
- IgnoreResults = true;
- }
-
- /// Generate the string component containing the location of the
- /// declaration.
- bool GenLoc(const Decl *D);
-
- /// String generation methods used both by the visitation methods
- /// and from other clients that want to directly generate USRs. These
- /// methods do not construct complete USRs (which incorporate the parents
- /// of an AST element), but only the fragments concerning the AST element
- /// itself.
-
- /// Generate a USR for an Objective-C class.
- void GenObjCClass(StringRef cls);
- /// Generate a USR for an Objective-C class category.
- void GenObjCCategory(StringRef cls, StringRef cat);
- /// Generate a USR fragment for an Objective-C instance variable. The
- /// complete USR can be created by concatenating the USR for the
- /// encompassing class with this USR fragment.
- void GenObjCIvar(StringRef ivar);
- /// Generate a USR fragment for an Objective-C method.
- void GenObjCMethod(StringRef sel, bool isInstanceMethod);
- /// Generate a USR fragment for an Objective-C property.
- void GenObjCProperty(StringRef prop);
- /// Generate a USR for an Objective-C protocol.
- void GenObjCProtocol(StringRef prot);
-
- void VisitType(QualType T);
- void VisitTemplateParameterList(const TemplateParameterList *Params);
- void VisitTemplateName(TemplateName Name);
- void VisitTemplateArgument(const TemplateArgument &Arg);
-
- /// Emit a Decl's name using NamedDecl::printName() and return true if
- /// the decl had no name.
- bool EmitDeclName(const NamedDecl *D);
-};
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Generating USRs from ASTS.
-//===----------------------------------------------------------------------===//
-
-bool USRGenerator::EmitDeclName(const NamedDecl *D) {
- Out.flush();
- const unsigned startSize = Buf.size();
- D->printName(Out);
- Out.flush();
- const unsigned endSize = Buf.size();
- return startSize == endSize;
-}
-
-static inline bool ShouldGenerateLocation(const NamedDecl *D) {
- return D->getLinkage() != ExternalLinkage;
-}
-
-void USRGenerator::VisitDeclContext(const DeclContext *DC) {
- if (const NamedDecl *D = dyn_cast<NamedDecl>(DC))
- Visit(D);
-}
-
-void USRGenerator::VisitFieldDecl(const FieldDecl *D) {
- // The USR for an ivar declared in a class extension is based on the
- // ObjCInterfaceDecl, not the ObjCCategoryDecl.
- if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
- Visit(ID);
- else
- VisitDeclContext(D->getDeclContext());
- Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
- if (EmitDeclName(D)) {
- // Bit fields can be anonymous.
- IgnoreResults = true;
- return;
- }
-}
-
-void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
- if (ShouldGenerateLocation(D) && GenLoc(D))
- return;
-
- VisitDeclContext(D->getDeclContext());
- if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) {
- Out << "@FT@";
- VisitTemplateParameterList(FunTmpl->getTemplateParameters());
- } else
- Out << "@F@";
- D->printName(Out);
-
- ASTContext &Ctx = *Context;
- if (!Ctx.getLangOpts().CPlusPlus || D->isExternC())
- return;
-
- if (const TemplateArgumentList *
- SpecArgs = D->getTemplateSpecializationArgs()) {
- Out << '<';
- for (unsigned I = 0, N = SpecArgs->size(); I != N; ++I) {
- Out << '#';
- VisitTemplateArgument(SpecArgs->get(I));
- }
- Out << '>';
- }
-
- // Mangle in type information for the arguments.
- for (FunctionDecl::param_const_iterator I = D->param_begin(),
- E = D->param_end();
- I != E; ++I) {
- Out << '#';
- if (ParmVarDecl *PD = *I)
- VisitType(PD->getType());
- }
- if (D->isVariadic())
- Out << '.';
- Out << '#';
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
- if (MD->isStatic())
- Out << 'S';
- if (unsigned quals = MD->getTypeQualifiers())
- Out << (char)('0' + quals);
- }
-}
-
-void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
- VisitDeclContext(D->getDeclContext());
- Out << "@";
-
- if (EmitDeclName(D)) {
- // The string can be empty if the declaration has no name; e.g., it is
- // the ParmDecl with no name for declaration of a function pointer type,
- // e.g.: void (*f)(void *);
- // In this case, don't generate a USR.
- IgnoreResults = true;
- }
-}
-
-void USRGenerator::VisitVarDecl(const VarDecl *D) {
- // VarDecls can be declared 'extern' within a function or method body,
- // but their enclosing DeclContext is the function, not the TU. We need
- // to check the storage class to correctly generate the USR.
- if (ShouldGenerateLocation(D) && GenLoc(D))
- return;
-
- VisitDeclContext(D->getDeclContext());
-
- // Variables always have simple names.
- StringRef s = D->getName();
-
- // The string can be empty if the declaration has no name; e.g., it is
- // the ParmDecl with no name for declaration of a function pointer type, e.g.:
- // void (*f)(void *);
- // In this case, don't generate a USR.
- if (s.empty())
- IgnoreResults = true;
- else
- Out << '@' << s;
-}
-
-void USRGenerator::VisitNonTypeTemplateParmDecl(
- const NonTypeTemplateParmDecl *D) {
- GenLoc(D);
- return;
-}
-
-void USRGenerator::VisitTemplateTemplateParmDecl(
- const TemplateTemplateParmDecl *D) {
- GenLoc(D);
- return;
-}
-
-void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
- if (D->isAnonymousNamespace()) {
- Out << "@aN";
- return;
- }
-
- VisitDeclContext(D->getDeclContext());
- if (!IgnoreResults)
- Out << "@N@" << D->getName();
-}
-
-void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
- VisitFunctionDecl(D->getTemplatedDecl());
-}
-
-void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
- VisitTagDecl(D->getTemplatedDecl());
-}
-
-void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
- VisitDeclContext(D->getDeclContext());
- if (!IgnoreResults)
- Out << "@NA@" << D->getName();
-}
-
-void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
- const DeclContext *container = D->getDeclContext();
- if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
- Visit(pd);
- }
- else {
- // The USR for a method declared in a class extension or category is based on
- // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
- const ObjCInterfaceDecl *ID = D->getClassInterface();
- if (!ID) {
- IgnoreResults = true;
- return;
- }
- Visit(ID);
- }
- // Ideally we would use 'GenObjCMethod', but this is such a hot path
- // for Objective-C code that we don't want to use
- // DeclarationName::getAsString().
- Out << (D->isInstanceMethod() ? "(im)" : "(cm)");
- DeclarationName N(D->getSelector());
- N.printName(Out);
-}
-
-void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D) {
- switch (D->getKind()) {
- default:
- llvm_unreachable("Invalid ObjC container.");
- case Decl::ObjCInterface:
- case Decl::ObjCImplementation:
- GenObjCClass(D->getName());
- break;
- case Decl::ObjCCategory: {
- const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
- const ObjCInterfaceDecl *ID = CD->getClassInterface();
- if (!ID) {
- // Handle invalid code where the @interface might not
- // have been specified.
- // FIXME: We should be able to generate this USR even if the
- // @interface isn't available.
- IgnoreResults = true;
- return;
- }
- // Specially handle class extensions, which are anonymous categories.
- // We want to mangle in the location to uniquely distinguish them.
- if (CD->IsClassExtension()) {
- Out << "objc(ext)" << ID->getName() << '@';
- GenLoc(CD);
- }
- else
- GenObjCCategory(ID->getName(), CD->getName());
-
- break;
- }
- case Decl::ObjCCategoryImpl: {
- const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
- const ObjCInterfaceDecl *ID = CD->getClassInterface();
- if (!ID) {
- // Handle invalid code where the @interface might not
- // have been specified.
- // FIXME: We should be able to generate this USR even if the
- // @interface isn't available.
- IgnoreResults = true;
- return;
- }
- GenObjCCategory(ID->getName(), CD->getName());
- break;
- }
- case Decl::ObjCProtocol:
- GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName());
- break;
- }
-}
-
-void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
- // The USR for a property declared in a class extension or category is based
- // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
- if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
- Visit(ID);
- else
- Visit(cast<Decl>(D->getDeclContext()));
- GenObjCProperty(D->getName());
-}
-
-void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
- if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
- VisitObjCPropertyDecl(PD);
- return;
- }
-
- IgnoreResults = true;
-}
-
-void USRGenerator::VisitTagDecl(const TagDecl *D) {
- // Add the location of the tag decl to handle resolution across
- // translation units.
- if (ShouldGenerateLocation(D) && GenLoc(D))
- return;
-
- D = D->getCanonicalDecl();
- VisitDeclContext(D->getDeclContext());
-
- bool AlreadyStarted = false;
- if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
- if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
- 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;
- case TTK_Enum: llvm_unreachable("enum template");
- }
- VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
- } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec
- = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
- 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;
- case TTK_Enum: llvm_unreachable("enum partial specialization");
- }
- VisitTemplateParameterList(PartialSpec->getTemplateParameters());
- }
- }
-
- 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;
- case TTK_Enum: Out << "@E"; break;
- }
- }
-
- Out << '@';
- Out.flush();
- assert(Buf.size() > 0);
- const unsigned off = Buf.size() - 1;
-
- if (EmitDeclName(D)) {
- if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
- Buf[off] = 'A';
- Out << '@' << *TD;
- }
- else
- Buf[off] = 'a';
- }
-
- // For a class template specialization, mangle the template arguments.
- if (const ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
- const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
- Out << '>';
- for (unsigned I = 0, N = Args.size(); I != N; ++I) {
- Out << '#';
- VisitTemplateArgument(Args.get(I));
- }
- }
-}
-
-void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
- if (ShouldGenerateLocation(D) && GenLoc(D))
- return;
- const DeclContext *DC = D->getDeclContext();
- if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
- Visit(DCN);
- Out << "@T@";
- Out << D->getName();
-}
-
-void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
- GenLoc(D);
- return;
-}
-
-bool USRGenerator::GenLoc(const Decl *D) {
- if (generatedLoc)
- return IgnoreResults;
- generatedLoc = true;
-
- // Guard against null declarations in invalid code.
- if (!D) {
- IgnoreResults = true;
- return true;
- }
-
- // Use the location of canonical decl.
- D = D->getCanonicalDecl();
-
- const SourceManager &SM = Context->getSourceManager();
- SourceLocation L = D->getLocStart();
- if (L.isInvalid()) {
- IgnoreResults = true;
- return true;
- }
- L = SM.getExpansionLoc(L);
- const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
- const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
- if (FE) {
- Out << llvm::sys::path::filename(FE->getName());
- }
- else {
- // This case really isn't interesting.
- IgnoreResults = true;
- return true;
- }
- // Use the offest into the FileID to represent the location. Using
- // a line/column can cause us to look back at the original source file,
- // which is expensive.
- Out << '@' << Decomposed.second;
- return IgnoreResults;
-}
-
-void USRGenerator::VisitType(QualType T) {
- // This method mangles in USR information for types. It can possibly
- // just reuse the naming-mangling logic used by codegen, although the
- // requirements for USRs might not be the same.
- ASTContext &Ctx = *Context;
-
- do {
- T = Ctx.getCanonicalType(T);
- Qualifiers Q = T.getQualifiers();
- unsigned qVal = 0;
- if (Q.hasConst())
- qVal |= 0x1;
- if (Q.hasVolatile())
- qVal |= 0x2;
- if (Q.hasRestrict())
- qVal |= 0x4;
- if(qVal)
- Out << ((char) ('0' + qVal));
-
- // Mangle in ObjC GC qualifiers?
-
- if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
- Out << 'P';
- T = Expansion->getPattern();
- }
-
- if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
- unsigned char c = '\0';
- switch (BT->getKind()) {
- case BuiltinType::Void:
- c = 'v'; break;
- case BuiltinType::Bool:
- c = 'b'; break;
- case BuiltinType::Char_U:
- case BuiltinType::UChar:
- c = 'c'; break;
- case BuiltinType::Char16:
- c = 'q'; break;
- case BuiltinType::Char32:
- c = 'w'; break;
- case BuiltinType::UShort:
- c = 's'; break;
- case BuiltinType::UInt:
- c = 'i'; break;
- case BuiltinType::ULong:
- c = 'l'; break;
- case BuiltinType::ULongLong:
- c = 'k'; break;
- case BuiltinType::UInt128:
- c = 'j'; break;
- case BuiltinType::Char_S:
- case BuiltinType::SChar:
- c = 'C'; break;
- case BuiltinType::WChar_S:
- case BuiltinType::WChar_U:
- c = 'W'; break;
- case BuiltinType::Short:
- c = 'S'; break;
- case BuiltinType::Int:
- c = 'I'; break;
- case BuiltinType::Long:
- c = 'L'; break;
- case BuiltinType::LongLong:
- c = 'K'; break;
- case BuiltinType::Int128:
- c = 'J'; break;
- case BuiltinType::Half:
- c = 'h'; break;
- case BuiltinType::Float:
- c = 'f'; break;
- case BuiltinType::Double:
- c = 'd'; break;
- case BuiltinType::LongDouble:
- c = 'D'; break;
- case BuiltinType::NullPtr:
- c = 'n'; break;
-#define BUILTIN_TYPE(Id, SingletonId)
-#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
-#include "clang/AST/BuiltinTypes.def"
- case BuiltinType::Dependent:
- case BuiltinType::OCLImage1d:
- case BuiltinType::OCLImage1dArray:
- case BuiltinType::OCLImage1dBuffer:
- case BuiltinType::OCLImage2d:
- case BuiltinType::OCLImage2dArray:
- case BuiltinType::OCLImage3d:
- case BuiltinType::OCLEvent:
- case BuiltinType::OCLSampler:
- IgnoreResults = true;
- return;
- case BuiltinType::ObjCId:
- c = 'o'; break;
- case BuiltinType::ObjCClass:
- c = 'O'; break;
- case BuiltinType::ObjCSel:
- c = 'e'; break;
- }
- Out << c;
- return;
- }
-
- // If we have already seen this (non-built-in) type, use a substitution
- // encoding.
- llvm::DenseMap<const Type *, unsigned>::iterator Substitution
- = TypeSubstitutions.find(T.getTypePtr());
- if (Substitution != TypeSubstitutions.end()) {
- Out << 'S' << Substitution->second << '_';
- return;
- } else {
- // Record this as a substitution.
- unsigned Number = TypeSubstitutions.size();
- TypeSubstitutions[T.getTypePtr()] = Number;
- }
-
- if (const PointerType *PT = T->getAs<PointerType>()) {
- Out << '*';
- T = PT->getPointeeType();
- continue;
- }
- if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
- Out << '&';
- T = RT->getPointeeType();
- continue;
- }
- if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
- Out << 'F';
- VisitType(FT->getResultType());
- for (FunctionProtoType::arg_type_iterator
- I = FT->arg_type_begin(), E = FT->arg_type_end(); I!=E; ++I) {
- VisitType(*I);
- }
- if (FT->isVariadic())
- Out << '.';
- return;
- }
- if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
- Out << 'B';
- T = BT->getPointeeType();
- continue;
- }
- if (const ComplexType *CT = T->getAs<ComplexType>()) {
- Out << '<';
- T = CT->getElementType();
- continue;
- }
- if (const TagType *TT = T->getAs<TagType>()) {
- Out << '$';
- VisitTagDecl(TT->getDecl());
- return;
- }
- if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) {
- Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
- return;
- }
- if (const TemplateSpecializationType *Spec
- = T->getAs<TemplateSpecializationType>()) {
- Out << '>';
- VisitTemplateName(Spec->getTemplateName());
- Out << Spec->getNumArgs();
- for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
- VisitTemplateArgument(Spec->getArg(I));
- return;
- }
-
- // Unhandled type.
- Out << ' ';
- break;
- } while (true);
-}
-
-void USRGenerator::VisitTemplateParameterList(
- const TemplateParameterList *Params) {
- if (!Params)
- return;
- Out << '>' << Params->size();
- for (TemplateParameterList::const_iterator P = Params->begin(),
- PEnd = Params->end();
- P != PEnd; ++P) {
- Out << '#';
- if (isa<TemplateTypeParmDecl>(*P)) {
- if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
- Out<< 'p';
- Out << 'T';
- continue;
- }
-
- if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
- if (NTTP->isParameterPack())
- Out << 'p';
- Out << 'N';
- VisitType(NTTP->getType());
- continue;
- }
-
- TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
- if (TTP->isParameterPack())
- Out << 'p';
- Out << 't';
- VisitTemplateParameterList(TTP->getTemplateParameters());
- }
-}
-
-void USRGenerator::VisitTemplateName(TemplateName Name) {
- if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
- if (TemplateTemplateParmDecl *TTP
- = dyn_cast<TemplateTemplateParmDecl>(Template)) {
- Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
- return;
- }
-
- Visit(Template);
- return;
- }
-
- // FIXME: Visit dependent template names.
-}
-
-void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- break;
-
- case TemplateArgument::Declaration:
- Visit(Arg.getAsDecl());
- break;
-
- case TemplateArgument::NullPtr:
- break;
-
- case TemplateArgument::TemplateExpansion:
- Out << 'P'; // pack expansion of...
- // Fall through
- case TemplateArgument::Template:
- VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
- break;
-
- case TemplateArgument::Expression:
- // FIXME: Visit expressions.
- break;
-
- case TemplateArgument::Pack:
- Out << 'p' << Arg.pack_size();
- for (TemplateArgument::pack_iterator P = Arg.pack_begin(), PEnd = Arg.pack_end();
- P != PEnd; ++P)
- VisitTemplateArgument(*P);
- break;
-
- case TemplateArgument::Type:
- VisitType(Arg.getAsType());
- break;
-
- case TemplateArgument::Integral:
- Out << 'V';
- VisitType(Arg.getIntegralType());
- Out << Arg.getAsIntegral();
- break;
- }
-}
-
-//===----------------------------------------------------------------------===//
-// General purpose USR generation methods.
-//===----------------------------------------------------------------------===//
-
-void USRGenerator::GenObjCClass(StringRef cls) {
- Out << "objc(cs)" << cls;
-}
-
-void USRGenerator::GenObjCCategory(StringRef cls, StringRef cat) {
- Out << "objc(cy)" << cls << '@' << cat;
-}
-
-void USRGenerator::GenObjCIvar(StringRef ivar) {
- Out << '@' << ivar;
-}
-
-void USRGenerator::GenObjCMethod(StringRef meth, bool isInstanceMethod) {
- Out << (isInstanceMethod ? "(im)" : "(cm)") << meth;
-}
-
-void USRGenerator::GenObjCProperty(StringRef prop) {
- Out << "(py)" << prop;
-}
-
-void USRGenerator::GenObjCProtocol(StringRef prot) {
- Out << "objc(pl)" << prot;
-}
+using namespace clang::index;
//===----------------------------------------------------------------------===//
// API hooks.
@@ -805,17 +31,7 @@ static inline StringRef extractUSRSuffix(StringRef s) {
}
bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) {
- // Don't generate USRs for things with invalid locations.
- if (!D || D->getLocStart().isInvalid())
- return true;
-
- USRGenerator UG(&D->getASTContext(), &Buf);
- UG->Visit(D);
-
- if (UG->ignoreResults())
- return true;
-
- return false;
+ return generateUSRForDecl(D, Buf);
}
extern "C" {
@@ -857,12 +73,10 @@ CXString clang_getCursorUSR(CXCursor C) {
if (!buf)
return cxstring::createEmpty();
- {
- USRGenerator UG(&cxcursor::getCursorASTUnit(C)->getASTContext(),
- &buf->Data);
- UG << "macro@"
- << cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
- }
+ buf->Data += getUSRSpacePrefix();
+ buf->Data += "macro@";
+ buf->Data +=
+ cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
buf->Data.push_back('\0');
return createCXString(buf);
}
@@ -871,46 +85,52 @@ CXString clang_getCursorUSR(CXCursor C) {
}
CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
- USRGenerator UG;
- UG << extractUSRSuffix(clang_getCString(classUSR));
- UG->GenObjCIvar(name);
- return cxstring::createDup(UG.str());
+ SmallString<128> Buf(getUSRSpacePrefix());
+ llvm::raw_svector_ostream OS(Buf);
+ OS << extractUSRSuffix(clang_getCString(classUSR));
+ generateUSRForObjCIvar(name, OS);
+ return cxstring::createDup(OS.str());
}
CXString clang_constructUSR_ObjCMethod(const char *name,
unsigned isInstanceMethod,
CXString classUSR) {
- USRGenerator UG;
- UG << extractUSRSuffix(clang_getCString(classUSR));
- UG->GenObjCMethod(name, isInstanceMethod);
- return cxstring::createDup(UG.str());
+ SmallString<128> Buf(getUSRSpacePrefix());
+ llvm::raw_svector_ostream OS(Buf);
+ OS << extractUSRSuffix(clang_getCString(classUSR));
+ generateUSRForObjCMethod(name, isInstanceMethod, OS);
+ return cxstring::createDup(OS.str());
}
CXString clang_constructUSR_ObjCClass(const char *name) {
- USRGenerator UG;
- UG->GenObjCClass(name);
- return cxstring::createDup(UG.str());
+ SmallString<128> Buf(getUSRSpacePrefix());
+ llvm::raw_svector_ostream OS(Buf);
+ generateUSRForObjCClass(name, OS);
+ return cxstring::createDup(OS.str());
}
CXString clang_constructUSR_ObjCProtocol(const char *name) {
- USRGenerator UG;
- UG->GenObjCProtocol(name);
- return cxstring::createDup(UG.str());
+ SmallString<128> Buf(getUSRSpacePrefix());
+ llvm::raw_svector_ostream OS(Buf);
+ generateUSRForObjCProtocol(name, OS);
+ return cxstring::createDup(OS.str());
}
CXString clang_constructUSR_ObjCCategory(const char *class_name,
const char *category_name) {
- USRGenerator UG;
- UG->GenObjCCategory(class_name, category_name);
- return cxstring::createDup(UG.str());
+ SmallString<128> Buf(getUSRSpacePrefix());
+ llvm::raw_svector_ostream OS(Buf);
+ generateUSRForObjCCategory(class_name, category_name, OS);
+ return cxstring::createDup(OS.str());
}
CXString clang_constructUSR_ObjCProperty(const char *property,
CXString classUSR) {
- USRGenerator UG;
- UG << extractUSRSuffix(clang_getCString(classUSR));
- UG->GenObjCProperty(property);
- return cxstring::createDup(UG.str());
+ SmallString<128> Buf(getUSRSpacePrefix());
+ llvm::raw_svector_ostream OS(Buf);
+ OS << extractUSRSuffix(clang_getCString(classUSR));
+ generateUSRForObjCProperty(property, OS);
+ return cxstring::createDup(OS.str());
}
} // end extern "C"
diff --git a/tools/libclang/CIndexer.cpp b/tools/libclang/CIndexer.cpp
index d89e0a4..91154cc 100644
--- a/tools/libclang/CIndexer.cpp
+++ b/tools/libclang/CIndexer.cpp
@@ -43,11 +43,13 @@
using namespace clang;
-std::string CIndexer::getClangResourcesPath() {
+const std::string &CIndexer::getClangResourcesPath() {
// Did we already compute the path?
if (!ResourcesPath.empty())
- return ResourcesPath.str();
-
+ return ResourcesPath;
+
+ SmallString<128> LibClangPath;
+
// Find the location where this library lives (libclang.dylib).
#ifdef LLVM_ON_WIN32
MEMORY_BASIC_INFORMATION mbi;
@@ -66,85 +68,20 @@ std::string CIndexer::getClangResourcesPath() {
#endif
#endif
- llvm::sys::Path LibClangPath(path);
- LibClangPath.eraseComponent();
+ LibClangPath += llvm::sys::path::parent_path(path);
#else
// This silly cast below avoids a C++ warning.
Dl_info info;
if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
llvm_unreachable("Call to dladdr() failed");
-
- llvm::sys::Path LibClangPath(info.dli_fname);
-
+
// We now have the CIndex directory, locate clang relative to it.
- LibClangPath.eraseComponent();
+ LibClangPath += llvm::sys::path::parent_path(info.dli_fname);
#endif
-
- LibClangPath.appendComponent("clang");
- LibClangPath.appendComponent(CLANG_VERSION_STRING);
-
- // Cache our result.
- ResourcesPath = LibClangPath;
- return LibClangPath.str();
-}
-static llvm::sys::Path GetTemporaryPath() {
- // FIXME: This is lame; sys::Path should provide this function (in particular,
- // it should know how to find the temporary files dir).
- std::string Error;
- const char *TmpDir = ::getenv("TMPDIR");
- if (!TmpDir)
- TmpDir = ::getenv("TEMP");
- if (!TmpDir)
- TmpDir = ::getenv("TMP");
- if (!TmpDir)
- TmpDir = "/tmp";
- llvm::sys::Path P(TmpDir);
- P.appendComponent("remap");
- if (P.makeUnique(false, &Error))
- return llvm::sys::Path("");
+ llvm::sys::path::append(LibClangPath, "clang", CLANG_VERSION_STRING);
- // FIXME: Grumble, makeUnique sometimes leaves the file around!? PR3837.
- P.eraseFromDisk(false, 0);
-
- return P;
-}
-
-bool clang::RemapFiles(unsigned num_unsaved_files,
- struct CXUnsavedFile *unsaved_files,
- std::vector<std::string> &RemapArgs,
- std::vector<llvm::sys::Path> &TemporaryFiles) {
- for (unsigned i = 0; i != num_unsaved_files; ++i) {
- // Write the contents of this unsaved file into the temporary file.
- llvm::sys::Path SavedFile(GetTemporaryPath());
- if (SavedFile.empty())
- return true;
-
- std::string ErrorInfo;
- llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo,
- llvm::raw_fd_ostream::F_Binary);
- if (!ErrorInfo.empty())
- return true;
-
- OS.write(unsaved_files[i].Contents, unsaved_files[i].Length);
- OS.close();
- if (OS.has_error()) {
- SavedFile.eraseFromDisk();
- OS.clear_error();
- return true;
- }
-
- // Remap the file.
- std::string RemapArg = unsaved_files[i].Filename;
- RemapArg += ';';
- RemapArg += SavedFile.str();
- RemapArgs.push_back("-Xclang");
- RemapArgs.push_back("-remap-file");
- RemapArgs.push_back("-Xclang");
- RemapArgs.push_back(RemapArg);
- TemporaryFiles.push_back(SavedFile);
- }
-
- return false;
+ // Cache our result.
+ ResourcesPath = LibClangPath.str();
+ return ResourcesPath;
}
-
diff --git a/tools/libclang/CIndexer.h b/tools/libclang/CIndexer.h
index 08162c5..95d8115 100644
--- a/tools/libclang/CIndexer.h
+++ b/tools/libclang/CIndexer.h
@@ -37,7 +37,7 @@ class CIndexer {
bool DisplayDiagnostics;
unsigned Options; // CXGlobalOptFlags.
- llvm::sys::Path ResourcesPath;
+ std::string ResourcesPath;
public:
CIndexer() : OnlyLocalDecls(false), DisplayDiagnostics(false),
@@ -62,20 +62,9 @@ public:
}
/// \brief Get the path of the clang resource files.
- std::string getClangResourcesPath();
+ const std::string &getClangResourcesPath();
};
- /**
- * \brief Given a set of "unsaved" files, create temporary files and
- * construct the clang -cc1 argument list needed to perform the remapping.
- *
- * \returns true if an error occurred.
- */
- bool RemapFiles(unsigned num_unsaved_files,
- struct CXUnsavedFile *unsaved_files,
- std::vector<std::string> &RemapArgs,
- std::vector<llvm::sys::Path> &TemporaryFiles);
-
/// \brief Return the current size to request for "safety".
unsigned GetSafetyThreadStackSize();
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index c5a975b..b7bde69 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -39,11 +39,11 @@ set(SOURCES
Indexing.cpp
IndexingContext.cpp
IndexingContext.h
- SimpleFormatContext.h
../../include/clang-c/Index.h
)
set(LIBRARIES
+ clangIndex
clangARCMigrate
clangRewriteCore
clangRewriteFrontend
@@ -56,7 +56,6 @@ set(LIBRARIES
clangLex
clangTooling
clangBasic
- clangFormat
)
set(GENERATED_HEADERS
@@ -70,6 +69,8 @@ set(GENERATED_HEADERS
ClangStmtNodes
)
+set(EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/libclang.exports)
+
if( LLVM_ENABLE_PIC )
set(SHARED_LIBRARY TRUE)
add_clang_library(libclang ${SOURCES})
@@ -92,11 +93,17 @@ if( LLVM_ENABLE_PIC )
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(LIBCLANG_LINK_FLAGS
- "-Wl,-compatibility_version -Wl,1 -Wl,-dead_strip")
+ " -Wl,-compatibility_version -Wl,1 -Wl,-dead_strip")
+ if (DEFINED ${LLVM_SUBMIT_VERSION})
+ set(LIBCLANG_LINK_FLAGS
+ "${LIBCLANG_LINK_FLAGS} -Wl,-current_version -Wl,${LLVM_SUBMIT_VERSION}.${LLVM_SUBMIT_SUBVERSION}")
+ endif()
+
+ set_property(TARGET libclang APPEND_STRING PROPERTY
+ LINK_FLAGS ${LIBCLANG_LINK_FLAGS})
set_target_properties(libclang
PROPERTIES
- LINK_FLAGS "${LIBCLANG_LINK_FLAGS}"
- INSTALL_NAME_DIR "@executable_path/../lib")
+ INSTALL_NAME_DIR "@rpath")
endif()
@@ -105,7 +112,10 @@ else()
set(LIBCLANG_STATIC_TARGET_NAME libclang)
endif()
-if( NOT BUILD_SHARED_LIBS AND NOT WIN32 )
+option(LIBCLANG_BUILD_STATIC
+ "Build libclang as a static library (in addition to a shared one)" OFF)
+
+if( (NOT LLVM_ENABLE_PIC OR LIBCLANG_BUILD_STATIC) AND NOT WIN32 )
add_clang_library(${LIBCLANG_STATIC_TARGET_NAME} STATIC ${SOURCES})
target_link_libraries(${LIBCLANG_STATIC_TARGET_NAME} ${LIBRARIES})
add_dependencies(${LIBCLANG_STATIC_TARGET_NAME} ${GENERATED_HEADERS} clang-headers)
diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp
index 1c127e1..2c4f269 100644
--- a/tools/libclang/CXComment.cpp
+++ b/tools/libclang/CXComment.cpp
@@ -15,17 +15,11 @@
#include "CXComment.h"
#include "CXCursor.h"
#include "CXString.h"
-#include "SimpleFormatContext.h"
-#include "clang/AST/CommentCommandTraits.h"
-#include "clang/AST/CommentVisitor.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/Format/Format.h"
-#include "clang/Lex/Lexer.h"
+#include "clang/Index/CommentToXML.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
#include <climits>
using namespace clang;
@@ -268,7 +262,7 @@ unsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) {
unsigned clang_ParamCommandComment_getParamIndex(CXComment CXC) {
const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
- if (!PCC || !PCC->isParamIndexValid())
+ if (!PCC || !PCC->isParamIndexValid() || PCC->isVarArgParam())
return ParamCommandComment::InvalidParamIndex;
return PCC->getParamIndex();
@@ -350,499 +344,23 @@ CXString clang_VerbatimLineComment_getText(CXComment CXC) {
return cxstring::createRef(VLC->getText());
}
-} // end extern "C"
-
//===----------------------------------------------------------------------===//
-// Helpers for converting comment AST to HTML.
+// Converting comments to XML.
//===----------------------------------------------------------------------===//
-namespace {
-
-/// This comparison will sort parameters with valid index by index and
-/// invalid (unresolved) parameters last.
-class ParamCommandCommentCompareIndex {
-public:
- bool operator()(const ParamCommandComment *LHS,
- const ParamCommandComment *RHS) const {
- unsigned LHSIndex = UINT_MAX;
- unsigned RHSIndex = UINT_MAX;
- if (LHS->isParamIndexValid())
- LHSIndex = LHS->getParamIndex();
- if (RHS->isParamIndexValid())
- RHSIndex = RHS->getParamIndex();
-
- return LHSIndex < RHSIndex;
- }
-};
-
-/// This comparison will sort template parameters in the following order:
-/// \li real template parameters (depth = 1) in index order;
-/// \li all other names (depth > 1);
-/// \li unresolved names.
-class TParamCommandCommentComparePosition {
-public:
- bool operator()(const TParamCommandComment *LHS,
- const TParamCommandComment *RHS) const {
- // Sort unresolved names last.
- if (!LHS->isPositionValid())
- return false;
- if (!RHS->isPositionValid())
- return true;
-
- if (LHS->getDepth() > 1)
- return false;
- if (RHS->getDepth() > 1)
- return true;
-
- // Sort template parameters in index order.
- if (LHS->getDepth() == 1 && RHS->getDepth() == 1)
- return LHS->getIndex(0) < RHS->getIndex(0);
-
- // Leave all other names in source order.
- return true;
- }
-};
-
-/// Separate parts of a FullComment.
-struct FullCommentParts {
- /// Take a full comment apart and initialize members accordingly.
- FullCommentParts(const FullComment *C,
- const CommandTraits &Traits);
-
- const BlockContentComment *Brief;
- const BlockContentComment *Headerfile;
- const ParagraphComment *FirstParagraph;
- const BlockCommandComment *Returns;
- SmallVector<const ParamCommandComment *, 8> Params;
- SmallVector<const TParamCommandComment *, 4> TParams;
- SmallVector<const BlockContentComment *, 8> MiscBlocks;
-};
-
-FullCommentParts::FullCommentParts(const FullComment *C,
- const CommandTraits &Traits) :
- Brief(NULL), Headerfile(NULL), FirstParagraph(NULL), Returns(NULL) {
- for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
- I != E; ++I) {
- const Comment *Child = *I;
- if (!Child)
- continue;
- switch (Child->getCommentKind()) {
- case Comment::NoCommentKind:
- continue;
-
- case Comment::ParagraphCommentKind: {
- const ParagraphComment *PC = cast<ParagraphComment>(Child);
- if (PC->isWhitespace())
- break;
- if (!FirstParagraph)
- FirstParagraph = PC;
-
- MiscBlocks.push_back(PC);
- break;
- }
-
- case Comment::BlockCommandCommentKind: {
- const BlockCommandComment *BCC = cast<BlockCommandComment>(Child);
- const CommandInfo *Info = Traits.getCommandInfo(BCC->getCommandID());
- if (!Brief && Info->IsBriefCommand) {
- Brief = BCC;
- break;
- }
- if (!Headerfile && Info->IsHeaderfileCommand) {
- Headerfile = BCC;
- break;
- }
- if (!Returns && Info->IsReturnsCommand) {
- Returns = BCC;
- break;
- }
- MiscBlocks.push_back(BCC);
- break;
- }
-
- case Comment::ParamCommandCommentKind: {
- const ParamCommandComment *PCC = cast<ParamCommandComment>(Child);
- if (!PCC->hasParamName())
- break;
-
- if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph())
- break;
-
- Params.push_back(PCC);
- break;
- }
-
- case Comment::TParamCommandCommentKind: {
- const TParamCommandComment *TPCC = cast<TParamCommandComment>(Child);
- if (!TPCC->hasParamName())
- break;
-
- if (!TPCC->hasNonWhitespaceParagraph())
- break;
-
- TParams.push_back(TPCC);
- break;
- }
-
- case Comment::VerbatimBlockCommentKind:
- MiscBlocks.push_back(cast<BlockCommandComment>(Child));
- break;
-
- case Comment::VerbatimLineCommentKind: {
- const VerbatimLineComment *VLC = cast<VerbatimLineComment>(Child);
- const CommandInfo *Info = Traits.getCommandInfo(VLC->getCommandID());
- if (!Info->IsDeclarationCommand)
- MiscBlocks.push_back(VLC);
- break;
- }
-
- case Comment::TextCommentKind:
- case Comment::InlineCommandCommentKind:
- case Comment::HTMLStartTagCommentKind:
- case Comment::HTMLEndTagCommentKind:
- case Comment::VerbatimBlockLineCommentKind:
- case Comment::FullCommentKind:
- llvm_unreachable("AST node of this kind can't be a child of "
- "a FullComment");
- }
- }
-
- // Sort params in order they are declared in the function prototype.
- // Unresolved parameters are put at the end of the list in the same order
- // they were seen in the comment.
- std::stable_sort(Params.begin(), Params.end(),
- ParamCommandCommentCompareIndex());
-
- std::stable_sort(TParams.begin(), TParams.end(),
- TParamCommandCommentComparePosition());
-}
-
-void PrintHTMLStartTagComment(const HTMLStartTagComment *C,
- llvm::raw_svector_ostream &Result) {
- Result << "<" << C->getTagName();
-
- if (C->getNumAttrs() != 0) {
- for (unsigned i = 0, e = C->getNumAttrs(); i != e; i++) {
- Result << " ";
- const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
- Result << Attr.Name;
- if (!Attr.Value.empty())
- Result << "=\"" << Attr.Value << "\"";
- }
- }
-
- if (!C->isSelfClosing())
- Result << ">";
- else
- Result << "/>";
-}
-
-class CommentASTToHTMLConverter :
- public ConstCommentVisitor<CommentASTToHTMLConverter> {
-public:
- /// \param Str accumulator for HTML.
- CommentASTToHTMLConverter(const FullComment *FC,
- SmallVectorImpl<char> &Str,
- const CommandTraits &Traits) :
- FC(FC), Result(Str), Traits(Traits)
- { }
-
- // Inline content.
- void visitTextComment(const TextComment *C);
- void visitInlineCommandComment(const InlineCommandComment *C);
- void visitHTMLStartTagComment(const HTMLStartTagComment *C);
- void visitHTMLEndTagComment(const HTMLEndTagComment *C);
-
- // Block content.
- void visitParagraphComment(const ParagraphComment *C);
- void visitBlockCommandComment(const BlockCommandComment *C);
- void visitParamCommandComment(const ParamCommandComment *C);
- void visitTParamCommandComment(const TParamCommandComment *C);
- void visitVerbatimBlockComment(const VerbatimBlockComment *C);
- void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
- void visitVerbatimLineComment(const VerbatimLineComment *C);
-
- void visitFullComment(const FullComment *C);
-
- // Helpers.
-
- /// Convert a paragraph that is not a block by itself (an argument to some
- /// command).
- void visitNonStandaloneParagraphComment(const ParagraphComment *C);
-
- void appendToResultWithHTMLEscaping(StringRef S);
-
-private:
- const FullComment *FC;
- /// Output stream for HTML.
- llvm::raw_svector_ostream Result;
-
- const CommandTraits &Traits;
-};
-} // end unnamed namespace
-
-void CommentASTToHTMLConverter::visitTextComment(const TextComment *C) {
- appendToResultWithHTMLEscaping(C->getText());
-}
-
-void CommentASTToHTMLConverter::visitInlineCommandComment(
- const InlineCommandComment *C) {
- // Nothing to render if no arguments supplied.
- if (C->getNumArgs() == 0)
- return;
-
- // Nothing to render if argument is empty.
- StringRef Arg0 = C->getArgText(0);
- if (Arg0.empty())
- return;
-
- switch (C->getRenderKind()) {
- case InlineCommandComment::RenderNormal:
- for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) {
- appendToResultWithHTMLEscaping(C->getArgText(i));
- Result << " ";
- }
- return;
-
- case InlineCommandComment::RenderBold:
- assert(C->getNumArgs() == 1);
- Result << "<b>";
- appendToResultWithHTMLEscaping(Arg0);
- Result << "</b>";
- return;
- case InlineCommandComment::RenderMonospaced:
- assert(C->getNumArgs() == 1);
- Result << "<tt>";
- appendToResultWithHTMLEscaping(Arg0);
- Result<< "</tt>";
- return;
- case InlineCommandComment::RenderEmphasized:
- assert(C->getNumArgs() == 1);
- Result << "<em>";
- appendToResultWithHTMLEscaping(Arg0);
- Result << "</em>";
- return;
- }
-}
-
-void CommentASTToHTMLConverter::visitHTMLStartTagComment(
- const HTMLStartTagComment *C) {
- PrintHTMLStartTagComment(C, Result);
-}
-
-void CommentASTToHTMLConverter::visitHTMLEndTagComment(
- const HTMLEndTagComment *C) {
- Result << "</" << C->getTagName() << ">";
-}
-
-void CommentASTToHTMLConverter::visitParagraphComment(
- const ParagraphComment *C) {
- if (C->isWhitespace())
- return;
-
- Result << "<p>";
- for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
- I != E; ++I) {
- visit(*I);
- }
- Result << "</p>";
-}
-
-void CommentASTToHTMLConverter::visitBlockCommandComment(
- const BlockCommandComment *C) {
- const CommandInfo *Info = Traits.getCommandInfo(C->getCommandID());
- if (Info->IsBriefCommand) {
- Result << "<p class=\"para-brief\">";
- visitNonStandaloneParagraphComment(C->getParagraph());
- Result << "</p>";
- return;
- }
- if (Info->IsReturnsCommand) {
- Result << "<p class=\"para-returns\">"
- "<span class=\"word-returns\">Returns</span> ";
- visitNonStandaloneParagraphComment(C->getParagraph());
- Result << "</p>";
- return;
- }
- // We don't know anything about this command. Just render the paragraph.
- visit(C->getParagraph());
-}
-
-void CommentASTToHTMLConverter::visitParamCommandComment(
- const ParamCommandComment *C) {
- if (C->isParamIndexValid()) {
- Result << "<dt class=\"param-name-index-"
- << C->getParamIndex()
- << "\">";
- appendToResultWithHTMLEscaping(C->getParamName(FC));
- } else {
- Result << "<dt class=\"param-name-index-invalid\">";
- appendToResultWithHTMLEscaping(C->getParamNameAsWritten());
- }
- Result << "</dt>";
-
- if (C->isParamIndexValid()) {
- Result << "<dd class=\"param-descr-index-"
- << C->getParamIndex()
- << "\">";
- } else
- Result << "<dd class=\"param-descr-index-invalid\">";
-
- visitNonStandaloneParagraphComment(C->getParagraph());
- Result << "</dd>";
-}
-
-void CommentASTToHTMLConverter::visitTParamCommandComment(
- const TParamCommandComment *C) {
- if (C->isPositionValid()) {
- if (C->getDepth() == 1)
- Result << "<dt class=\"tparam-name-index-"
- << C->getIndex(0)
- << "\">";
- else
- Result << "<dt class=\"tparam-name-index-other\">";
- appendToResultWithHTMLEscaping(C->getParamName(FC));
- } else {
- Result << "<dt class=\"tparam-name-index-invalid\">";
- appendToResultWithHTMLEscaping(C->getParamNameAsWritten());
- }
-
- Result << "</dt>";
-
- if (C->isPositionValid()) {
- if (C->getDepth() == 1)
- Result << "<dd class=\"tparam-descr-index-"
- << C->getIndex(0)
- << "\">";
- else
- Result << "<dd class=\"tparam-descr-index-other\">";
- } else
- Result << "<dd class=\"tparam-descr-index-invalid\">";
-
- visitNonStandaloneParagraphComment(C->getParagraph());
- Result << "</dd>";
-}
-
-void CommentASTToHTMLConverter::visitVerbatimBlockComment(
- const VerbatimBlockComment *C) {
- unsigned NumLines = C->getNumLines();
- if (NumLines == 0)
- return;
-
- Result << "<pre>";
- for (unsigned i = 0; i != NumLines; ++i) {
- appendToResultWithHTMLEscaping(C->getText(i));
- if (i + 1 != NumLines)
- Result << '\n';
- }
- Result << "</pre>";
-}
-
-void CommentASTToHTMLConverter::visitVerbatimBlockLineComment(
- const VerbatimBlockLineComment *C) {
- llvm_unreachable("should not see this AST node");
-}
-
-void CommentASTToHTMLConverter::visitVerbatimLineComment(
- const VerbatimLineComment *C) {
- Result << "<pre>";
- appendToResultWithHTMLEscaping(C->getText());
- Result << "</pre>";
-}
-
-void CommentASTToHTMLConverter::visitFullComment(const FullComment *C) {
- FullCommentParts Parts(C, Traits);
-
- bool FirstParagraphIsBrief = false;
- if (Parts.Headerfile)
- visit(Parts.Headerfile);
- if (Parts.Brief)
- visit(Parts.Brief);
- else if (Parts.FirstParagraph) {
- Result << "<p class=\"para-brief\">";
- visitNonStandaloneParagraphComment(Parts.FirstParagraph);
- Result << "</p>";
- FirstParagraphIsBrief = true;
- }
-
- for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) {
- const Comment *C = Parts.MiscBlocks[i];
- if (FirstParagraphIsBrief && C == Parts.FirstParagraph)
- continue;
- visit(C);
- }
-
- if (Parts.TParams.size() != 0) {
- Result << "<dl>";
- for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
- visit(Parts.TParams[i]);
- Result << "</dl>";
- }
-
- if (Parts.Params.size() != 0) {
- Result << "<dl>";
- for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i)
- visit(Parts.Params[i]);
- Result << "</dl>";
- }
-
- if (Parts.Returns)
- visit(Parts.Returns);
-
- Result.flush();
-}
-
-void CommentASTToHTMLConverter::visitNonStandaloneParagraphComment(
- const ParagraphComment *C) {
- if (!C)
- return;
-
- for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
- I != E; ++I) {
- visit(*I);
- }
-}
-
-void CommentASTToHTMLConverter::appendToResultWithHTMLEscaping(StringRef S) {
- for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) {
- const char C = *I;
- switch (C) {
- case '&':
- Result << "&amp;";
- break;
- case '<':
- Result << "&lt;";
- break;
- case '>':
- Result << "&gt;";
- break;
- case '"':
- Result << "&quot;";
- break;
- case '\'':
- Result << "&#39;";
- break;
- case '/':
- Result << "&#47;";
- break;
- default:
- Result << C;
- break;
- }
- }
-}
-
-extern "C" {
-
CXString clang_HTMLTagComment_getAsString(CXComment CXC) {
const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
if (!HTC)
return cxstring::createNull();
- SmallString<128> HTML;
- CommentASTToHTMLConverter Converter(0, HTML, getCommandTraits(CXC));
- Converter.visit(HTC);
- return cxstring::createDup(HTML.str());
+ CXTranslationUnit TU = CXC.TranslationUnit;
+ if (!TU->CommentToXML)
+ TU->CommentToXML = new clang::index::CommentToXMLConverter();
+
+ SmallString<128> Text;
+ TU->CommentToXML->convertHTMLTagNodeToText(
+ HTC, Text, cxtu::getASTUnit(TU)->getASTContext());
+ return cxstring::createDup(Text.str());
}
CXString clang_FullComment_getAsHTML(CXComment CXC) {
@@ -850,596 +368,28 @@ CXString clang_FullComment_getAsHTML(CXComment CXC) {
if (!FC)
return cxstring::createNull();
+ CXTranslationUnit TU = CXC.TranslationUnit;
+ if (!TU->CommentToXML)
+ TU->CommentToXML = new clang::index::CommentToXMLConverter();
+
SmallString<1024> HTML;
- CommentASTToHTMLConverter Converter(FC, HTML, getCommandTraits(CXC));
- Converter.visit(FC);
+ TU->CommentToXML
+ ->convertCommentToHTML(FC, HTML, cxtu::getASTUnit(TU)->getASTContext());
return cxstring::createDup(HTML.str());
}
-} // end extern "C"
-
-namespace {
-class CommentASTToXMLConverter :
- public ConstCommentVisitor<CommentASTToXMLConverter> {
-public:
- /// \param Str accumulator for XML.
- CommentASTToXMLConverter(const FullComment *FC,
- SmallVectorImpl<char> &Str,
- const CommandTraits &Traits,
- const SourceManager &SM,
- SimpleFormatContext &SFC,
- unsigned FUID) :
- FC(FC), Result(Str), Traits(Traits), SM(SM),
- FormatRewriterContext(SFC),
- FormatInMemoryUniqueId(FUID) { }
-
- // Inline content.
- void visitTextComment(const TextComment *C);
- void visitInlineCommandComment(const InlineCommandComment *C);
- void visitHTMLStartTagComment(const HTMLStartTagComment *C);
- void visitHTMLEndTagComment(const HTMLEndTagComment *C);
-
- // Block content.
- void visitParagraphComment(const ParagraphComment *C);
-
- void appendParagraphCommentWithKind(const ParagraphComment *C,
- StringRef Kind);
-
- void visitBlockCommandComment(const BlockCommandComment *C);
- void visitParamCommandComment(const ParamCommandComment *C);
- void visitTParamCommandComment(const TParamCommandComment *C);
- void visitVerbatimBlockComment(const VerbatimBlockComment *C);
- void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
- void visitVerbatimLineComment(const VerbatimLineComment *C);
-
- void visitFullComment(const FullComment *C);
-
- // Helpers.
- void appendToResultWithXMLEscaping(StringRef S);
-
- void formatTextOfDeclaration(const DeclInfo *DI,
- SmallString<128> &Declaration);
-
-private:
- const FullComment *FC;
-
- /// Output stream for XML.
- llvm::raw_svector_ostream Result;
-
- const CommandTraits &Traits;
- const SourceManager &SM;
- SimpleFormatContext &FormatRewriterContext;
- unsigned FormatInMemoryUniqueId;
-};
-
-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.PolishForDeclaration = true;
- PPolicy.TerseOutput = true;
- ThisDecl->CurrentDecl->print(OS, PPolicy,
- /*Indentation*/0, /*PrintInstantiation*/false);
-}
-
-void CommentASTToXMLConverter::formatTextOfDeclaration(
- const DeclInfo *DI,
- SmallString<128> &Declaration) {
- // FIXME. formatting API expects null terminated input string.
- // There might be more efficient way of doing this.
- std::string StringDecl = Declaration.str();
-
- // Formatter specific code.
- // Form a unique in memory buffer name.
- SmallString<128> filename;
- filename += "xmldecl";
- filename += llvm::utostr(FormatInMemoryUniqueId);
- filename += ".xd";
- FileID ID = FormatRewriterContext.createInMemoryFile(filename, StringDecl);
- SourceLocation Start =
- FormatRewriterContext.Sources.getLocForStartOfFile(ID).getLocWithOffset(0);
- unsigned Length = Declaration.size();
-
- std::vector<CharSourceRange>
- Ranges(1, CharSourceRange::getCharRange(Start, Start.getLocWithOffset(Length)));
- ASTContext &Context = DI->CurrentDecl->getASTContext();
- const LangOptions &LangOpts = Context.getLangOpts();
- Lexer Lex(ID, FormatRewriterContext.Sources.getBuffer(ID),
- FormatRewriterContext.Sources, LangOpts);
- tooling::Replacements Replace =
- reformat(format::getLLVMStyle(), Lex, FormatRewriterContext.Sources, Ranges);
- applyAllReplacements(Replace, FormatRewriterContext.Rewrite);
- Declaration = FormatRewriterContext.getRewrittenText(ID);
-}
-
-} // end unnamed namespace
-
-void CommentASTToXMLConverter::visitTextComment(const TextComment *C) {
- appendToResultWithXMLEscaping(C->getText());
-}
-
-void CommentASTToXMLConverter::visitInlineCommandComment(const InlineCommandComment *C) {
- // Nothing to render if no arguments supplied.
- if (C->getNumArgs() == 0)
- return;
-
- // Nothing to render if argument is empty.
- StringRef Arg0 = C->getArgText(0);
- if (Arg0.empty())
- return;
-
- switch (C->getRenderKind()) {
- case InlineCommandComment::RenderNormal:
- for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) {
- appendToResultWithXMLEscaping(C->getArgText(i));
- Result << " ";
- }
- return;
- case InlineCommandComment::RenderBold:
- assert(C->getNumArgs() == 1);
- Result << "<bold>";
- appendToResultWithXMLEscaping(Arg0);
- Result << "</bold>";
- return;
- case InlineCommandComment::RenderMonospaced:
- assert(C->getNumArgs() == 1);
- Result << "<monospaced>";
- appendToResultWithXMLEscaping(Arg0);
- Result << "</monospaced>";
- return;
- case InlineCommandComment::RenderEmphasized:
- assert(C->getNumArgs() == 1);
- Result << "<emphasized>";
- appendToResultWithXMLEscaping(Arg0);
- Result << "</emphasized>";
- return;
- }
-}
-
-void CommentASTToXMLConverter::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
- Result << "<rawHTML><![CDATA[";
- PrintHTMLStartTagComment(C, Result);
- Result << "]]></rawHTML>";
-}
-
-void CommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
- Result << "<rawHTML>&lt;/" << C->getTagName() << "&gt;</rawHTML>";
-}
-
-void CommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C) {
- appendParagraphCommentWithKind(C, StringRef());
-}
-
-void CommentASTToXMLConverter::appendParagraphCommentWithKind(
- const ParagraphComment *C,
- StringRef ParagraphKind) {
- if (C->isWhitespace())
- return;
-
- if (ParagraphKind.empty())
- Result << "<Para>";
- else
- Result << "<Para kind=\"" << ParagraphKind << "\">";
-
- for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
- I != E; ++I) {
- visit(*I);
- }
- Result << "</Para>";
-}
-
-void CommentASTToXMLConverter::visitBlockCommandComment(const BlockCommandComment *C) {
- StringRef ParagraphKind;
-
- switch (C->getCommandID()) {
- case CommandTraits::KCI_attention:
- case CommandTraits::KCI_author:
- case CommandTraits::KCI_authors:
- case CommandTraits::KCI_bug:
- case CommandTraits::KCI_copyright:
- case CommandTraits::KCI_date:
- case CommandTraits::KCI_invariant:
- case CommandTraits::KCI_note:
- case CommandTraits::KCI_post:
- case CommandTraits::KCI_pre:
- case CommandTraits::KCI_remark:
- case CommandTraits::KCI_remarks:
- case CommandTraits::KCI_sa:
- case CommandTraits::KCI_see:
- case CommandTraits::KCI_since:
- case CommandTraits::KCI_todo:
- case CommandTraits::KCI_version:
- case CommandTraits::KCI_warning:
- ParagraphKind = C->getCommandName(Traits);
- default:
- break;
- }
-
- appendParagraphCommentWithKind(C->getParagraph(), ParagraphKind);
-}
-
-void CommentASTToXMLConverter::visitParamCommandComment(const ParamCommandComment *C) {
- Result << "<Parameter><Name>";
- appendToResultWithXMLEscaping(C->isParamIndexValid() ? C->getParamName(FC)
- : C->getParamNameAsWritten());
- Result << "</Name>";
-
- if (C->isParamIndexValid())
- Result << "<Index>" << C->getParamIndex() << "</Index>";
-
- Result << "<Direction isExplicit=\"" << C->isDirectionExplicit() << "\">";
- switch (C->getDirection()) {
- case ParamCommandComment::In:
- Result << "in";
- break;
- case ParamCommandComment::Out:
- Result << "out";
- break;
- case ParamCommandComment::InOut:
- Result << "in,out";
- break;
- }
- Result << "</Direction><Discussion>";
- visit(C->getParagraph());
- Result << "</Discussion></Parameter>";
-}
-
-void CommentASTToXMLConverter::visitTParamCommandComment(
- const TParamCommandComment *C) {
- Result << "<Parameter><Name>";
- appendToResultWithXMLEscaping(C->isPositionValid() ? C->getParamName(FC)
- : C->getParamNameAsWritten());
- Result << "</Name>";
-
- if (C->isPositionValid() && C->getDepth() == 1) {
- Result << "<Index>" << C->getIndex(0) << "</Index>";
- }
-
- Result << "<Discussion>";
- visit(C->getParagraph());
- Result << "</Discussion></Parameter>";
-}
-
-void CommentASTToXMLConverter::visitVerbatimBlockComment(
- const VerbatimBlockComment *C) {
- unsigned NumLines = C->getNumLines();
- if (NumLines == 0)
- return;
-
- switch (C->getCommandID()) {
- case CommandTraits::KCI_code:
- Result << "<Verbatim xml:space=\"preserve\" kind=\"code\">";
- break;
- default:
- Result << "<Verbatim xml:space=\"preserve\" kind=\"verbatim\">";
- break;
- }
- for (unsigned i = 0; i != NumLines; ++i) {
- appendToResultWithXMLEscaping(C->getText(i));
- if (i + 1 != NumLines)
- Result << '\n';
- }
- Result << "</Verbatim>";
-}
-
-void CommentASTToXMLConverter::visitVerbatimBlockLineComment(
- const VerbatimBlockLineComment *C) {
- llvm_unreachable("should not see this AST node");
-}
-
-void CommentASTToXMLConverter::visitVerbatimLineComment(
- const VerbatimLineComment *C) {
- Result << "<Verbatim xml:space=\"preserve\" kind=\"verbatim\">";
- appendToResultWithXMLEscaping(C->getText());
- Result << "</Verbatim>";
-}
-
-void CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
- FullCommentParts Parts(C, Traits);
-
- const DeclInfo *DI = C->getDeclInfo();
- StringRef RootEndTag;
- if (DI) {
- switch (DI->getKind()) {
- case DeclInfo::OtherKind:
- RootEndTag = "</Other>";
- Result << "<Other";
- break;
- case DeclInfo::FunctionKind:
- RootEndTag = "</Function>";
- Result << "<Function";
- switch (DI->TemplateKind) {
- case DeclInfo::NotTemplate:
- break;
- case DeclInfo::Template:
- Result << " templateKind=\"template\"";
- break;
- case DeclInfo::TemplateSpecialization:
- Result << " templateKind=\"specialization\"";
- break;
- case DeclInfo::TemplatePartialSpecialization:
- llvm_unreachable("partial specializations of functions "
- "are not allowed in C++");
- }
- if (DI->IsInstanceMethod)
- Result << " isInstanceMethod=\"1\"";
- if (DI->IsClassMethod)
- Result << " isClassMethod=\"1\"";
- break;
- case DeclInfo::ClassKind:
- RootEndTag = "</Class>";
- Result << "<Class";
- switch (DI->TemplateKind) {
- case DeclInfo::NotTemplate:
- break;
- case DeclInfo::Template:
- Result << " templateKind=\"template\"";
- break;
- case DeclInfo::TemplateSpecialization:
- Result << " templateKind=\"specialization\"";
- break;
- case DeclInfo::TemplatePartialSpecialization:
- Result << " templateKind=\"partialSpecialization\"";
- break;
- }
- break;
- case DeclInfo::VariableKind:
- RootEndTag = "</Variable>";
- Result << "<Variable";
- break;
- case DeclInfo::NamespaceKind:
- RootEndTag = "</Namespace>";
- Result << "<Namespace";
- break;
- case DeclInfo::TypedefKind:
- RootEndTag = "</Typedef>";
- Result << "<Typedef";
- break;
- case DeclInfo::EnumKind:
- RootEndTag = "</Enum>";
- Result << "<Enum";
- break;
- }
-
- {
- // Print line and column number.
- SourceLocation Loc = DI->CurrentDecl->getLocation();
- std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
- FileID FID = LocInfo.first;
- unsigned FileOffset = LocInfo.second;
-
- if (!FID.isInvalid()) {
- if (const FileEntry *FE = SM.getFileEntryForID(FID)) {
- Result << " file=\"";
- appendToResultWithXMLEscaping(FE->getName());
- Result << "\"";
- }
- Result << " line=\"" << SM.getLineNumber(FID, FileOffset)
- << "\" column=\"" << SM.getColumnNumber(FID, FileOffset)
- << "\"";
- }
- }
-
- // Finish the root tag.
- Result << ">";
-
- bool FoundName = false;
- if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->CommentDecl)) {
- if (DeclarationName DeclName = ND->getDeclName()) {
- Result << "<Name>";
- std::string Name = DeclName.getAsString();
- appendToResultWithXMLEscaping(Name);
- FoundName = true;
- Result << "</Name>";
- }
- }
- if (!FoundName)
- Result << "<Name>&lt;anonymous&gt;</Name>";
-
- {
- // Print USR.
- SmallString<128> USR;
- cxcursor::getDeclCursorUSR(DI->CommentDecl, USR);
- if (!USR.empty()) {
- Result << "<USR>";
- appendToResultWithXMLEscaping(USR);
- Result << "</USR>";
- }
- }
- } else {
- // No DeclInfo -- just emit some root tag and name tag.
- RootEndTag = "</Other>";
- Result << "<Other><Name>unknown</Name>";
- }
-
- if (Parts.Headerfile) {
- Result << "<Headerfile>";
- visit(Parts.Headerfile);
- Result << "</Headerfile>";
- }
-
- {
- // Pretty-print the declaration.
- Result << "<Declaration>";
- SmallString<128> Declaration;
- getSourceTextOfDeclaration(DI, Declaration);
- formatTextOfDeclaration(DI, Declaration);
- appendToResultWithXMLEscaping(Declaration);
-
- Result << "</Declaration>";
- }
-
- bool FirstParagraphIsBrief = false;
- if (Parts.Brief) {
- Result << "<Abstract>";
- visit(Parts.Brief);
- Result << "</Abstract>";
- } else if (Parts.FirstParagraph) {
- Result << "<Abstract>";
- visit(Parts.FirstParagraph);
- Result << "</Abstract>";
- FirstParagraphIsBrief = true;
- }
-
- if (Parts.TParams.size() != 0) {
- Result << "<TemplateParameters>";
- for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
- visit(Parts.TParams[i]);
- Result << "</TemplateParameters>";
- }
-
- if (Parts.Params.size() != 0) {
- Result << "<Parameters>";
- for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i)
- visit(Parts.Params[i]);
- Result << "</Parameters>";
- }
-
- if (Parts.Returns) {
- Result << "<ResultDiscussion>";
- 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;
- for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) {
- const Comment *C = Parts.MiscBlocks[i];
- if (FirstParagraphIsBrief && C == Parts.FirstParagraph)
- continue;
- if (!StartTagEmitted) {
- Result << "<Discussion>";
- StartTagEmitted = true;
- }
- visit(C);
- }
- if (StartTagEmitted)
- Result << "</Discussion>";
- }
-
- Result << RootEndTag;
-
- Result.flush();
-}
-
-void CommentASTToXMLConverter::appendToResultWithXMLEscaping(StringRef S) {
- for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) {
- const char C = *I;
- switch (C) {
- case '&':
- Result << "&amp;";
- break;
- case '<':
- Result << "&lt;";
- break;
- case '>':
- Result << "&gt;";
- break;
- case '"':
- Result << "&quot;";
- break;
- case '\'':
- Result << "&apos;";
- break;
- default:
- Result << C;
- break;
- }
- }
-}
-
-extern "C" {
-
CXString clang_FullComment_getAsXML(CXComment CXC) {
const FullComment *FC = getASTNodeAs<FullComment>(CXC);
if (!FC)
return cxstring::createNull();
- ASTContext &Context = FC->getDeclInfo()->CurrentDecl->getASTContext();
+
CXTranslationUnit TU = CXC.TranslationUnit;
- SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
-
- if (!TU->FormatContext) {
- TU->FormatContext = new SimpleFormatContext(Context.getLangOpts());
- } else if ((TU->FormatInMemoryUniqueId % 1000) == 0) {
- // Delete after some number of iterators, so the buffers don't grow
- // too large.
- delete TU->FormatContext;
- TU->FormatContext = new SimpleFormatContext(Context.getLangOpts());
- }
+ if (!TU->CommentToXML)
+ TU->CommentToXML = new clang::index::CommentToXMLConverter();
SmallString<1024> XML;
- CommentASTToXMLConverter Converter(FC, XML, getCommandTraits(CXC), SM,
- *TU->FormatContext,
- TU->FormatInMemoryUniqueId++);
- Converter.visit(FC);
+ TU->CommentToXML
+ ->convertCommentToXML(FC, XML, cxtu::getASTUnit(TU)->getASTContext());
return cxstring::createDup(XML.str());
}
diff --git a/tools/libclang/CXComment.h b/tools/libclang/CXComment.h
index 0780a65..1e2561d 100644
--- a/tools/libclang/CXComment.h
+++ b/tools/libclang/CXComment.h
@@ -27,20 +27,20 @@ namespace comments {
namespace cxcomment {
-inline CXComment createCXComment(const comments::Comment *C,
- CXTranslationUnit TU) {
+static inline CXComment createCXComment(const comments::Comment *C,
+ CXTranslationUnit TU) {
CXComment Result;
Result.ASTNode = C;
Result.TranslationUnit = TU;
return Result;
}
-inline const comments::Comment *getASTNode(CXComment CXC) {
+static inline const comments::Comment *getASTNode(CXComment CXC) {
return static_cast<const comments::Comment *>(CXC.ASTNode);
}
template<typename T>
-inline const T *getASTNodeAs(CXComment CXC) {
+static inline const T *getASTNodeAs(CXComment CXC) {
const comments::Comment *C = getASTNode(CXC);
if (!C)
return NULL;
@@ -48,11 +48,11 @@ inline const T *getASTNodeAs(CXComment CXC) {
return dyn_cast<T>(C);
}
-inline ASTContext &getASTContext(CXComment CXC) {
+static inline ASTContext &getASTContext(CXComment CXC) {
return cxtu::getASTUnit(CXC.TranslationUnit)->getASTContext();
}
-inline comments::CommandTraits &getCommandTraits(CXComment CXC) {
+static inline comments::CommandTraits &getCommandTraits(CXComment CXC) {
return getASTContext(CXC).getCommentCommandTraits();
}
diff --git a/tools/libclang/CXCompilationDatabase.cpp b/tools/libclang/CXCompilationDatabase.cpp
index e35ac27..433caec 100644
--- a/tools/libclang/CXCompilationDatabase.cpp
+++ b/tools/libclang/CXCompilationDatabase.cpp
@@ -1,6 +1,7 @@
#include "clang-c/CXCompilationDatabase.h"
#include "CXString.h"
#include "clang/Tooling/CompilationDatabase.h"
+#include <cstdio>
using namespace clang;
using namespace clang::tooling;
@@ -135,5 +136,41 @@ clang_CompileCommand_getArg(CXCompileCommand CCmd, unsigned Arg)
return cxstring::createRef(Cmd->CommandLine[Arg].c_str());
}
+unsigned
+clang_CompileCommand_getNumMappedSources(CXCompileCommand CCmd)
+{
+ if (!CCmd)
+ return 0;
+
+ return static_cast<CompileCommand *>(CCmd)->MappedSources.size();
+}
+
+CXString
+clang_CompileCommand_getMappedSourcePath(CXCompileCommand CCmd, unsigned I)
+{
+ if (!CCmd)
+ return cxstring::createNull();
+
+ CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
+
+ if (I >= Cmd->MappedSources.size())
+ return cxstring::createNull();
+
+ return cxstring::createRef(Cmd->MappedSources[I].first.c_str());
+}
+
+CXString
+clang_CompileCommand_getMappedSourceContent(CXCompileCommand CCmd, unsigned I)
+{
+ if (!CCmd)
+ return cxstring::createNull();
+
+ CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
+
+ if (I >= Cmd->MappedSources.size())
+ return cxstring::createNull();
+
+ return cxstring::createRef(Cmd->MappedSources[I].second.c_str());
+}
} // end: extern "C"
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index 2cdb71b..c75c061 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -18,6 +18,7 @@
#include "CXString.h"
#include "CXType.h"
#include "clang-c/Index.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
@@ -48,6 +49,7 @@ static CXCursorKind GetCursorKind(const Attr *A) {
case attr::Override: return CXCursor_CXXOverrideAttr;
case attr::Annotate: return CXCursor_AnnotateAttr;
case attr::AsmLabel: return CXCursor_AsmLabelAttr;
+ case attr::Packed: return CXCursor_PackedAttr;
}
return CXCursor_UnexposedAttr;
@@ -75,7 +77,7 @@ CXCursor cxcursor::MakeCXCursor(const Decl *D, CXTranslationUnit TU,
RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
SmallVector<SourceLocation, 16> SelLocs;
cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
- SmallVector<SourceLocation, 16>::iterator
+ SmallVectorImpl<SourceLocation>::iterator
I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
if (I != SelLocs.end())
SelectorIdIndex = I - SelLocs.begin();
@@ -216,6 +218,7 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::CXXBindTemporaryExprClass:
case Stmt::CXXDefaultArgExprClass:
case Stmt::CXXDefaultInitExprClass:
+ case Stmt::CXXStdInitializerListExprClass:
case Stmt::CXXScalarValueInitExprClass:
case Stmt::CXXUuidofExprClass:
case Stmt::ChooseExprClass:
@@ -231,6 +234,7 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::ParenListExprClass:
case Stmt::PredefinedExprClass:
case Stmt::ShuffleVectorExprClass:
+ case Stmt::ConvertVectorExprClass:
case Stmt::UnaryExprOrTypeTraitExprClass:
case Stmt::UnaryTypeTraitExprClass:
case Stmt::VAArgExprClass:
@@ -492,7 +496,7 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
SmallVector<SourceLocation, 16> SelLocs;
cast<ObjCMessageExpr>(S)->getSelectorLocs(SelLocs);
- SmallVector<SourceLocation, 16>::iterator
+ SmallVectorImpl<SourceLocation>::iterator
I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
if (I != SelLocs.end())
SelectorIdIndex = I - SelLocs.begin();
@@ -504,6 +508,10 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::MSDependentExistsStmtClass:
K = CXCursor_UnexposedStmt;
break;
+ case Stmt::OMPParallelDirectiveClass:
+ K = CXCursor_OMPParallelDirective;
+ break;
+
}
CXCursor C = { K, 0, { Parent, S, TU } };
@@ -836,7 +844,7 @@ void cxcursor::getOverriddenCursors(CXCursor cursor,
SmallVector<const NamedDecl *, 8> OverDecls;
D->getASTContext().getOverriddenMethods(D, OverDecls);
- for (SmallVector<const NamedDecl *, 8>::iterator
+ for (SmallVectorImpl<const NamedDecl *>::iterator
I = OverDecls.begin(), E = OverDecls.end(); I != E; ++I) {
overridden.push_back(MakeCXCursor(*I, TU));
}
diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp
index b7c7622..7371177 100644
--- a/tools/libclang/CXSourceLocation.cpp
+++ b/tools/libclang/CXSourceLocation.cpp
@@ -124,6 +124,8 @@ CXSourceLocation clang_getLocation(CXTranslationUnit TU,
unsigned column) {
if (!TU || !file)
return clang_getNullLocation();
+ if (line == 0 || column == 0)
+ return clang_getNullLocation();
LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
@@ -209,6 +211,17 @@ int clang_Location_isInSystemHeader(CXSourceLocation location) {
return SM.isInSystemHeader(Loc);
}
+int clang_Location_isFromMainFile(CXSourceLocation location) {
+ const SourceLocation Loc =
+ SourceLocation::getFromRawEncoding(location.int_data);
+ if (Loc.isInvalid())
+ return 0;
+
+ const SourceManager &SM =
+ *static_cast<const SourceManager*>(location.ptr_data[0]);
+ return SM.isWrittenInMainFile(Loc);
+}
+
void clang_getExpansionLocation(CXSourceLocation location,
CXFile *file,
unsigned *line,
@@ -255,7 +268,7 @@ void clang_getPresumedLocation(CXSourceLocation location,
CXString *filename,
unsigned *line,
unsigned *column) {
-
+
if (!isASTUnitSourceLocation(location)) {
// Other SourceLocation implementations do not support presumed locations
// at this time.
@@ -265,20 +278,22 @@ void clang_getPresumedLocation(CXSourceLocation location,
SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
- if (!location.ptr_data[0] || Loc.isInvalid())
+ if (!location.ptr_data[0] || Loc.isInvalid()) {
createNullLocation(filename, line, column);
- else {
- const SourceManager &SM =
- *static_cast<const SourceManager*>(location.ptr_data[0]);
- PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
-
- if (filename)
- *filename = cxstring::createRef(PreLoc.getFilename());
- if (line)
- *line = PreLoc.getLine();
- if (column)
- *column = PreLoc.getColumn();
+ return;
}
+
+ const SourceManager &SM =
+ *static_cast<const SourceManager *>(location.ptr_data[0]);
+ PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
+ if (PreLoc.isInvalid()) {
+ createNullLocation(filename, line, column);
+ return;
+ }
+
+ if (filename) *filename = cxstring::createRef(PreLoc.getFilename());
+ if (line) *line = PreLoc.getLine();
+ if (column) *column = PreLoc.getColumn();
}
void clang_getInstantiationLocation(CXSourceLocation location,
diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h
index bdc171c..c0014c0 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -20,7 +20,9 @@
namespace clang {
class ASTUnit;
class CIndexer;
- class SimpleFormatContext;
+namespace index {
+class CommentToXMLConverter;
+} // namespace index
} // namespace clang
struct CXTranslationUnitImpl {
@@ -29,8 +31,7 @@ struct CXTranslationUnitImpl {
clang::cxstring::CXStringPool *StringPool;
void *Diagnostics;
void *OverridenCursorsPool;
- clang::SimpleFormatContext *FormatContext;
- unsigned FormatInMemoryUniqueId;
+ clang::index::CommentToXMLConverter *CommentToXML;
};
namespace clang {
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 1482415..1e2cb18 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -85,7 +85,11 @@ static CXTypeKind GetTypeKind(QualType T) {
TKCASE(FunctionNoProto);
TKCASE(FunctionProto);
TKCASE(ConstantArray);
+ TKCASE(IncompleteArray);
+ TKCASE(VariableArray);
+ TKCASE(DependentSizedArray);
TKCASE(Vector);
+ TKCASE(MemberPointer);
default:
return CXType_Unexposed;
}
@@ -107,6 +111,11 @@ CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
else if (Ctx.isObjCSelType(UnqualT))
TK = CXType_ObjCSel;
}
+
+ /* Handle decayed types as the original type */
+ if (const DecayedType *DT = T->getAs<DecayedType>()) {
+ return MakeCXType(DT->getOriginalType(), TU);
+ }
}
if (TK == CXType_Invalid)
TK = GetTypeKind(T);
@@ -357,6 +366,9 @@ CXType clang_getPointeeType(CXType CT) {
case Type::ObjCObjectPointer:
T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
break;
+ case Type::MemberPointer:
+ T = cast<MemberPointerType>(TP)->getPointeeType();
+ break;
default:
T = QualType();
break;
@@ -466,7 +478,11 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
TKIND(FunctionNoProto);
TKIND(FunctionProto);
TKIND(ConstantArray);
+ TKIND(IncompleteArray);
+ TKIND(VariableArray);
+ TKIND(DependentSizedArray);
TKIND(Vector);
+ TKIND(MemberPointer);
}
#undef TKIND
return cxstring::createRef(s);
@@ -498,12 +514,13 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
if (const FunctionType *FD = T->getAs<FunctionType>()) {
#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
switch (FD->getCallConv()) {
- TCALLINGCONV(Default);
TCALLINGCONV(C);
TCALLINGCONV(X86StdCall);
TCALLINGCONV(X86FastCall);
TCALLINGCONV(X86ThisCall);
TCALLINGCONV(X86Pascal);
+ TCALLINGCONV(X86_64Win64);
+ TCALLINGCONV(X86_64SysV);
TCALLINGCONV(AAPCS);
TCALLINGCONV(AAPCS_VFP);
TCALLINGCONV(PnaclCall);
@@ -590,6 +607,15 @@ CXType clang_getElementType(CXType CT) {
case Type::ConstantArray:
ET = cast<ConstantArrayType> (TP)->getElementType();
break;
+ case Type::IncompleteArray:
+ ET = cast<IncompleteArrayType> (TP)->getElementType();
+ break;
+ case Type::VariableArray:
+ ET = cast<VariableArrayType> (TP)->getElementType();
+ break;
+ case Type::DependentSizedArray:
+ ET = cast<DependentSizedArrayType> (TP)->getElementType();
+ break;
case Type::Vector:
ET = cast<VectorType> (TP)->getElementType();
break;
@@ -633,6 +659,15 @@ CXType clang_getArrayElementType(CXType CT) {
case Type::ConstantArray:
ET = cast<ConstantArrayType> (TP)->getElementType();
break;
+ case Type::IncompleteArray:
+ ET = cast<IncompleteArrayType> (TP)->getElementType();
+ break;
+ case Type::VariableArray:
+ ET = cast<VariableArrayType> (TP)->getElementType();
+ break;
+ case Type::DependentSizedArray:
+ ET = cast<DependentSizedArrayType> (TP)->getElementType();
+ break;
default:
break;
}
@@ -677,6 +712,17 @@ long long clang_Type_getAlignOf(CXType T) {
return Ctx.getTypeAlignInChars(QT).getQuantity();
}
+CXType clang_Type_getClassType(CXType CT) {
+ QualType ET = QualType();
+ QualType T = GetQualType(CT);
+ const Type *TP = T.getTypePtrOrNull();
+
+ if (TP && TP->getTypeClass() == Type::MemberPointer) {
+ ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
+ }
+ return MakeCXType(ET, GetTU(CT));
+}
+
long long clang_Type_getSizeOf(CXType T) {
if (T.kind == CXType_Invalid)
return CXTypeLayoutError_Invalid;
@@ -733,11 +779,13 @@ long long clang_Type_getOffsetOf(CXType PT, const char *S) {
return CXTypeLayoutError_Invalid;
const RecordDecl *RD =
dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
- if (!RD)
+ if (!RD || RD->isInvalidDecl())
return CXTypeLayoutError_Invalid;
RD = RD->getDefinition();
if (!RD)
return CXTypeLayoutError_Incomplete;
+ if (RD->isInvalidDecl())
+ return CXTypeLayoutError_Invalid;
QualType RT = GetQualType(PT);
if (RT->isIncompleteType())
return CXTypeLayoutError_Incomplete;
@@ -768,6 +816,24 @@ long long clang_Type_getOffsetOf(CXType PT, const char *S) {
return CXTypeLayoutError_InvalidFieldName;
}
+enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
+ QualType QT = GetQualType(T);
+ if (QT.isNull())
+ return CXRefQualifier_None;
+ const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
+ if (!FD)
+ return CXRefQualifier_None;
+ switch (FD->getRefQualifier()) {
+ case RQ_None:
+ return CXRefQualifier_None;
+ case RQ_LValue:
+ return CXRefQualifier_LValue;
+ case RQ_RValue:
+ return CXRefQualifier_RValue;
+ }
+ return CXRefQualifier_None;
+}
+
unsigned clang_Cursor_isBitField(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp
index 02ab885..e08a346 100644
--- a/tools/libclang/IndexBody.cpp
+++ b/tools/libclang/IndexBody.cpp
@@ -153,9 +153,11 @@ public:
if (C.capturesThis())
return true;
- if (IndexCtx.shouldIndexFunctionLocalSymbols())
+ if (C.capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
IndexCtx.handleReference(C.getCapturedVar(), C.getLocation(),
Parent, ParentDC);
+
+ // FIXME: Lambda init-captures.
return true;
}
diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp
index 756001c..89feb96 100644
--- a/tools/libclang/IndexDecl.cpp
+++ b/tools/libclang/IndexDecl.cpp
@@ -22,6 +22,15 @@ public:
explicit IndexingDeclVisitor(IndexingContext &indexCtx)
: IndexCtx(indexCtx) { }
+ /// \brief Returns true if the given method has been defined explicitly by the
+ /// user.
+ static bool hasUserDefined(const ObjCMethodDecl *D,
+ const ObjCImplDecl *Container) {
+ const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(),
+ D->isInstanceMethod());
+ return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition();
+ }
+
void handleDeclarator(const DeclaratorDecl *D, const NamedDecl *Parent = 0) {
if (!Parent) Parent = D;
@@ -234,12 +243,14 @@ public:
}
if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
- if (MD->isPropertyAccessor())
+ if (MD->isPropertyAccessor() &&
+ !hasUserDefined(MD, cast<ObjCImplDecl>(D->getDeclContext())))
IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation(),
D->getLexicalDeclContext());
}
if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
- if (MD->isPropertyAccessor())
+ if (MD->isPropertyAccessor() &&
+ !hasUserDefined(MD, cast<ObjCImplDecl>(D->getDeclContext())))
IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation(),
D->getLexicalDeclContext());
}
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 15786ac..99fcdb6 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -31,6 +31,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/MutexGuard.h"
+#include <cstdio>
using namespace clang;
using namespace cxtu;
@@ -88,25 +89,23 @@ public:
/// #3 is identified as the location of "#ifdef CAKE"
///
class PPRegion {
- ino_t ino;
+ llvm::sys::fs::UniqueID UniqueID;
time_t ModTime;
- dev_t dev;
unsigned Offset;
public:
- PPRegion() : ino(), ModTime(), dev(), Offset() {}
- PPRegion(dev_t dev, ino_t ino, unsigned offset, time_t modTime)
- : ino(ino), ModTime(modTime), dev(dev), Offset(offset) {}
+ PPRegion() : UniqueID(0, 0), ModTime(), Offset() {}
+ PPRegion(llvm::sys::fs::UniqueID UniqueID, unsigned offset, time_t modTime)
+ : UniqueID(UniqueID), ModTime(modTime), Offset(offset) {}
- ino_t getIno() const { return ino; }
- dev_t getDev() const { return dev; }
+ const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
unsigned getOffset() const { return Offset; }
time_t getModTime() const { return ModTime; }
bool isInvalid() const { return *this == PPRegion(); }
friend bool operator==(const PPRegion &lhs, const PPRegion &rhs) {
- return lhs.dev == rhs.dev && lhs.ino == rhs.ino &&
- lhs.Offset == rhs.Offset && lhs.ModTime == rhs.ModTime;
+ return lhs.UniqueID == rhs.UniqueID && lhs.Offset == rhs.Offset &&
+ lhs.ModTime == rhs.ModTime;
}
};
@@ -122,16 +121,17 @@ namespace llvm {
template <>
struct DenseMapInfo<PPRegion> {
static inline PPRegion getEmptyKey() {
- return PPRegion(0, 0, unsigned(-1), 0);
+ return PPRegion(llvm::sys::fs::UniqueID(0, 0), unsigned(-1), 0);
}
static inline PPRegion getTombstoneKey() {
- return PPRegion(0, 0, unsigned(-2), 0);
+ return PPRegion(llvm::sys::fs::UniqueID(0, 0), unsigned(-2), 0);
}
static unsigned getHashValue(const PPRegion &S) {
llvm::FoldingSetNodeID ID;
- ID.AddInteger(S.getIno());
- ID.AddInteger(S.getDev());
+ const llvm::sys::fs::UniqueID &UniqueID = S.getUniqueID();
+ ID.AddInteger(UniqueID.getFile());
+ ID.AddInteger(UniqueID.getDevice());
ID.AddInteger(S.getOffset());
ID.AddInteger(S.getModTime());
return ID.ComputeHash();
@@ -208,9 +208,10 @@ private:
PPRegion getRegion(SourceLocation Loc, FileID FID, const FileEntry *FE) {
SourceLocation RegionLoc = PPRec.findConditionalDirectiveRegionLoc(Loc);
if (RegionLoc.isInvalid()) {
- if (isParsedOnceInclude(FE))
- return PPRegion(FE->getDevice(), FE->getInode(), 0,
- FE->getModificationTime());
+ if (isParsedOnceInclude(FE)) {
+ const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
+ return PPRegion(ID, 0, FE->getModificationTime());
+ }
return PPRegion();
}
@@ -221,14 +222,15 @@ private:
llvm::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc);
if (RegionFID != FID) {
- if (isParsedOnceInclude(FE))
- return PPRegion(FE->getDevice(), FE->getInode(), 0,
- FE->getModificationTime());
+ if (isParsedOnceInclude(FE)) {
+ const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
+ return PPRegion(ID, 0, FE->getModificationTime());
+ }
return PPRegion();
}
- return PPRegion(FE->getDevice(), FE->getInode(), RegionOffset,
- FE->getModificationTime());
+ const llvm::sys::fs::UniqueID &ID = FE->getUniqueID();
+ return PPRegion(ID, RegionOffset, FE->getModificationTime());
}
bool isParsedOnceInclude(const FileEntry *FE) {
diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp
index 14b430c..41ed6ea 100644
--- a/tools/libclang/IndexingContext.cpp
+++ b/tools/libclang/IndexingContext.cpp
@@ -10,6 +10,7 @@
#include "IndexingContext.h"
#include "CIndexDiagnostic.h"
#include "CXTranslationUnit.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Frontend/ASTUnit.h"
@@ -93,17 +94,19 @@ AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx)
const IBOutletCollectionAttr *
IBAttr = cast<IBOutletCollectionAttr>(IBInfo.A);
+ SourceLocation InterfaceLocStart =
+ IBAttr->getInterfaceLoc()->getTypeLoc().getLocStart();
IBInfo.IBCollInfo.attrInfo = &IBInfo;
- IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(IBAttr->getInterfaceLoc());
+ IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(InterfaceLocStart);
IBInfo.IBCollInfo.objcClass = 0;
IBInfo.IBCollInfo.classCursor = clang_getNullCursor();
QualType Ty = IBAttr->getInterface();
- if (const ObjCInterfaceType *InterTy = Ty->getAs<ObjCInterfaceType>()) {
- if (const ObjCInterfaceDecl *InterD = InterTy->getInterface()) {
+ if (const ObjCObjectType *ObjectTy = Ty->getAs<ObjCObjectType>()) {
+ if (const ObjCInterfaceDecl *InterD = ObjectTy->getInterface()) {
IdxCtx.getEntityInfo(InterD, IBInfo.ClassInfo, SA);
IBInfo.IBCollInfo.objcClass = &IBInfo.ClassInfo;
- IBInfo.IBCollInfo.classCursor = MakeCursorObjCClassRef(InterD,
- IBAttr->getInterfaceLoc(), IdxCtx.CXTU);
+ IBInfo.IBCollInfo.classCursor =
+ MakeCursorObjCClassRef(InterD, InterfaceLocStart, IdxCtx.CXTU);
}
}
}
@@ -210,11 +213,13 @@ bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
return false;
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
- switch (ND->getLinkage()) {
+ switch (ND->getFormalLinkage()) {
case NoLinkage:
+ case VisibleNoLinkage:
case InternalLinkage:
return true;
case UniqueExternalLinkage:
+ llvm_unreachable("Not a sema linkage");
case ExternalLinkage:
return false;
}
@@ -378,14 +383,14 @@ bool IndexingContext::handleFunction(const FunctionDecl *D) {
isContainer = false;
}
- DeclInfo DInfo(!D->isFirstDeclaration(), isDef, isContainer);
+ DeclInfo DInfo(!D->isFirstDecl(), isDef, isContainer);
if (isSkipped)
DInfo.flags |= CXIdxDeclFlag_Skipped;
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
}
bool IndexingContext::handleVar(const VarDecl *D) {
- DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
+ DeclInfo DInfo(!D->isFirstDecl(), D->isThisDeclarationADefinition(),
/*isContainer=*/false);
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
}
@@ -412,13 +417,13 @@ bool IndexingContext::handleTagDecl(const TagDecl *D) {
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(D))
return handleCXXRecordDecl(CXXRD, D);
- DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
+ DeclInfo DInfo(!D->isFirstDecl(), D->isThisDeclarationADefinition(),
D->isThisDeclarationADefinition());
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
}
bool IndexingContext::handleTypedefName(const TypedefNameDecl *D) {
- DeclInfo DInfo(!D->isFirstDeclaration(), /*isDefinition=*/true,
+ DeclInfo DInfo(!D->isFirstDecl(), /*isDefinition=*/true,
/*isContainer=*/false);
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
}
diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h
index 62873be..3437d55 100644
--- a/tools/libclang/IndexingContext.h
+++ b/tools/libclang/IndexingContext.h
@@ -270,14 +270,6 @@ public:
}
};
-struct RefFileOccurence {
- const FileEntry *File;
- const Decl *Dcl;
-
- RefFileOccurence(const FileEntry *File, const Decl *Dcl)
- : File(File), Dcl(Dcl) { }
-};
-
class IndexingContext {
ASTContext *Ctx;
CXClientData ClientData;
@@ -294,6 +286,7 @@ class IndexingContext {
ContainerMapTy ContainerMap;
EntityMapTy EntityMap;
+ typedef std::pair<const FileEntry *, const Decl *> RefFileOccurence;
llvm::DenseSet<RefFileOccurence> RefFileOccurences;
std::deque<DeclGroupRef> TUDeclsInObjCContainer;
@@ -524,29 +517,3 @@ inline T *ScratchAlloc::allocate() {
}
}} // end clang::cxindex
-
-namespace llvm {
- /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
- /// DenseSets.
- template <>
- struct DenseMapInfo<clang::cxindex::RefFileOccurence> {
- static inline clang::cxindex::RefFileOccurence getEmptyKey() {
- return clang::cxindex::RefFileOccurence(0, 0);
- }
-
- static inline clang::cxindex::RefFileOccurence getTombstoneKey() {
- return clang::cxindex::RefFileOccurence((const clang::FileEntry *)~0,
- (const clang::Decl *)~0);
- }
-
- static unsigned getHashValue(clang::cxindex::RefFileOccurence S) {
- typedef std::pair<const clang::FileEntry *, const clang::Decl *> PairTy;
- return DenseMapInfo<PairTy>::getHashValue(PairTy(S.File, S.Dcl));
- }
-
- static bool isEqual(clang::cxindex::RefFileOccurence LHS,
- clang::cxindex::RefFileOccurence RHS) {
- return LHS.File == RHS.File && LHS.Dcl == RHS.Dcl;
- }
- };
-}
diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile
index f33f345..43ecbd1 100644
--- a/tools/libclang/Makefile
+++ b/tools/libclang/Makefile
@@ -16,21 +16,21 @@ LINK_LIBS_IN_SHARED = 1
SHARED_LIBRARY = 1
include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc
-USEDLIBS = clangFrontend.a clangDriver.a \
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
+USEDLIBS = clangIndex.a clangFrontend.a clangDriver.a \
clangTooling.a \
clangSerialization.a \
clangParse.a clangSema.a \
clangARCMigrate.a clangRewriteFrontend.a clangRewriteCore.a \
clangAnalysis.a clangEdit.a \
clangAST.a clangLex.a clangBasic.a \
- clangFormat.a
+ clangFormat.a
include $(CLANG_LEVEL)/Makefile
# Add soname to the library.
-ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD GNU))
- LDFLAGS += -Wl,-soname,lib$(LIBRARYNAME)$(SHLIBEXT)
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD GNU GNU/kFreeBSD))
+ LLVMLibsOptions += -Wl,-soname,lib$(LIBRARYNAME)$(SHLIBEXT)
endif
##===----------------------------------------------------------------------===##
diff --git a/tools/libclang/RecursiveASTVisitor.h b/tools/libclang/RecursiveASTVisitor.h
index e45545e..3ad5acb 100644
--- a/tools/libclang/RecursiveASTVisitor.h
+++ b/tools/libclang/RecursiveASTVisitor.h
@@ -27,6 +27,7 @@
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
@@ -394,6 +395,7 @@ private:
// These are helper methods used by more than one Traverse* method.
bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
bool TraverseClassInstantiations(ClassTemplateDecl *D);
+ bool TraverseVariableInstantiations(VarTemplateDecl *D);
bool TraverseFunctionInstantiations(FunctionTemplateDecl *D) ;
bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
unsigned Count);
@@ -404,6 +406,13 @@ private:
bool TraverseDeclContextHelper(DeclContext *DC);
bool TraverseFunctionHelper(FunctionDecl *D);
bool TraverseVarHelper(VarDecl *D);
+ bool TraverseOMPClause(OMPClause *C);
+#define OPENMP_CLAUSE(Name, Class) \
+ bool Visit##Class(Class *C);
+#include "clang/Basic/OpenMPKinds.def"
+ /// \brief Process clauses with list of variables.
+ template <typename T>
+ void VisitOMPClauseList(T *Node);
typedef SmallVector<Stmt *, 16> StmtsTy;
typedef SmallVector<StmtsTy *, 4> QueuesTy;
@@ -502,7 +511,7 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
}
}
- for (SmallVector<Stmt *, 8>::reverse_iterator
+ for (SmallVectorImpl<Stmt *>::reverse_iterator
RI = StmtsToEnqueu.rbegin(),
RE = StmtsToEnqueu.rend(); RI != RE; ++RI)
Queue.push_back(*RI);
@@ -786,6 +795,10 @@ DEF_TRAVERSE_TYPE(MemberPointerType, {
TRY_TO(TraverseType(T->getPointeeType()));
})
+DEF_TRAVERSE_TYPE(DecayedType, {
+ TRY_TO(TraverseType(T->getOriginalType()));
+ })
+
DEF_TRAVERSE_TYPE(ConstantArrayType, {
TRY_TO(TraverseType(T->getElementType()));
})
@@ -992,6 +1005,10 @@ DEF_TRAVERSE_TYPELOC(MemberPointerType, {
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
})
+DEF_TRAVERSE_TYPELOC(DecayedType, {
+ TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
+ })
+
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
// This isn't available for ArrayType, but is for the ArrayTypeLoc.
@@ -1405,6 +1422,57 @@ DEF_TRAVERSE_DECL(ClassTemplateDecl, {
// it was instantiated, and thus should not be traversed.
})
+// A helper method for traversing the implicit instantiations of a
+// class template.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseVariableInstantiations(
+ VarTemplateDecl *D) {
+ VarTemplateDecl::spec_iterator end = D->spec_end();
+ for (VarTemplateDecl::spec_iterator it = D->spec_begin(); it != end; ++it) {
+ VarTemplateSpecializationDecl *SD = *it;
+
+ switch (SD->getSpecializationKind()) {
+ // Visit the implicit instantiations with the requested pattern.
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ TRY_TO(TraverseDecl(SD));
+ break;
+
+ // We don't need to do anything on an explicit instantiation
+ // or explicit specialization because there will be an explicit
+ // node for it elsewhere.
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ case TSK_ExplicitSpecialization:
+ break;
+ }
+ }
+
+ return true;
+}
+
+DEF_TRAVERSE_DECL(
+ VarTemplateDecl,
+ {
+ VarDecl *TempDecl = D->getTemplatedDecl();
+ TRY_TO(TraverseDecl(TempDecl));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+ // By default, we do not traverse the instantiations of
+ // variable templates since they do not appear in the user code. The
+ // following code optionally traverses them.
+ //
+ // We only traverse the variable instantiations when we see the canonical
+ // declaration of the template, to ensure we only visit them once.
+ if (getDerived().shouldVisitTemplateInstantiations() &&
+ D == D->getCanonicalDecl())
+ TRY_TO(TraverseVariableInstantiations(D));
+
+ // Note that getInstantiatedFromMemberTemplate() is just a link
+ // from a template instantiation back to the template from which
+ // it was instantiated, and thus should not be traversed.
+})
+
// A helper method for traversing the instantiations of a
// function while skipping its specializations.
template<typename Derived>
@@ -1582,7 +1650,8 @@ DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, {
}
// The args that remains unspecialized.
TRY_TO(TraverseTemplateArgumentLocsHelper(
- D->getTemplateArgsAsWritten(), D->getNumTemplateArgsAsWritten()));
+ D->getTemplateArgsAsWritten()->getTemplateArgs(),
+ D->getTemplateArgsAsWritten()->NumTemplateArgs));
// Don't need the ClassTemplatePartialSpecializationHelper, even
// though that's our parent class -- we already visit all the
@@ -1731,6 +1800,44 @@ DEF_TRAVERSE_DECL(VarDecl, {
TRY_TO(TraverseVarHelper(D));
})
+DEF_TRAVERSE_DECL(VarTemplateSpecializationDecl, {
+ // For implicit instantiations, we don't want to
+ // recurse at all, since the instatiated class isn't written in
+ // the source code anywhere.
+ if (TypeSourceInfo *TSI = D->getTypeAsWritten())
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+
+ if (!getDerived().shouldVisitTemplateInstantiations() &&
+ D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
+ // Returning from here skips traversing the
+ // declaration context of the VarTemplateSpecializationDecl
+ // (embedded in the DEF_TRAVERSE_DECL() macro).
+ return true;
+})
+
+DEF_TRAVERSE_DECL(VarTemplatePartialSpecializationDecl,
+ {
+ // The partial specialization.
+ if (TemplateParameterList *TPL = D->getTemplateParameters()) {
+ for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ }
+ // The args that remains unspecialized.
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ D->getTemplateArgsAsWritten()->getTemplateArgs(),
+ D->getTemplateArgsAsWritten()->NumTemplateArgs));
+
+ // Don't need the VarTemplatePartialSpecializationHelper, even
+ // though that's our parent class -- we already visit all the
+ // template args here.
+ TRY_TO(TraverseVarHelper(D));
+
+ // Instantiations will have been visited with the primary
+ // template.
+})
+
DEF_TRAVERSE_DECL(ImplicitParamDecl, {
TRY_TO(TraverseVarHelper(D));
})
@@ -2039,6 +2146,8 @@ DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
// Walk only the visible parts of lambda expressions.
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
+ TRY_TO(WalkUpFromLambdaExpr(S));
+
for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
CEnd = S->explicit_capture_end();
C != CEnd; ++C) {
@@ -2095,6 +2204,7 @@ DEF_TRAVERSE_STMT(CXXDefaultInitExpr, { })
DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
DEF_TRAVERSE_STMT(ExprWithCleanups, { })
DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
+DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { })
DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
@@ -2132,6 +2242,7 @@ DEF_TRAVERSE_STMT(ParenExpr, { })
DEF_TRAVERSE_STMT(ParenListExpr, { })
DEF_TRAVERSE_STMT(PredefinedExpr, { })
DEF_TRAVERSE_STMT(ShuffleVectorExpr, { })
+DEF_TRAVERSE_STMT(ConvertVectorExpr, { })
DEF_TRAVERSE_STMT(StmtExpr, { })
DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
@@ -2191,6 +2302,61 @@ DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { })
// Traverse OpenCL: AsType, Convert.
DEF_TRAVERSE_STMT(AsTypeExpr, { })
+// OpenMP directives.
+DEF_TRAVERSE_STMT(OMPParallelDirective, {
+ ArrayRef<OMPClause *> Clauses = S->clauses();
+ for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
+ I != E; ++I)
+ if (!TraverseOMPClause(*I)) return false;
+})
+
+// OpenMP clauses.
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
+ if (!C) return true;
+ switch (C->getClauseKind()) {
+#define OPENMP_CLAUSE(Name, Class) \
+ case OMPC_##Name: \
+ return getDerived().Visit##Class(static_cast<Class*>(C));
+#include "clang/Basic/OpenMPKinds.def"
+ default: break;
+ }
+ return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
+ return true;
+}
+
+template<typename Derived>
+template<typename T>
+void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+ for (typename T::varlist_iterator I = Node->varlist_begin(),
+ E = Node->varlist_end();
+ I != E; ++I)
+ TraverseStmt(*I);
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
+ VisitOMPClauseList(C);
+ return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
+ OMPFirstprivateClause *C) {
+ VisitOMPClauseList(C);
+ return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
+ VisitOMPClauseList(C);
+ return true;
+}
+
// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods
// returning decls or qualtypes or nestednamespecifier -- though I'm
diff --git a/tools/libclang/SimpleFormatContext.h b/tools/libclang/SimpleFormatContext.h
deleted file mode 100644
index 016d0b6..0000000
--- a/tools/libclang/SimpleFormatContext.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===--- SimpleFormatContext.h ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file
-///
-/// \brief Defines a utility class for use of clang-format in libclang
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SIMPLE_FORM_CONTEXT_H
-#define LLVM_CLANG_SIMPLE_FORM_CONTEXT_H
-
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang {
-
-/// \brief A small class to be used by libclang clients to format
-/// a declaration string in memory. This object is instantiated once
-/// and used each time a formatting is needed.
-class SimpleFormatContext {
-public:
- SimpleFormatContext(LangOptions Options)
- : DiagOpts(new DiagnosticOptions()),
- Diagnostics(new DiagnosticsEngine(new DiagnosticIDs,
- DiagOpts.getPtr())),
- Files((FileSystemOptions())),
- Sources(*Diagnostics, Files),
- Rewrite(Sources, Options) {
- Diagnostics->setClient(new IgnoringDiagConsumer, true);
- }
-
- ~SimpleFormatContext() { }
-
- FileID createInMemoryFile(StringRef Name, StringRef Content) {
- const llvm::MemoryBuffer *Source =
- llvm::MemoryBuffer::getMemBuffer(Content);
- const FileEntry *Entry =
- Files.getVirtualFile(Name, Source->getBufferSize(), 0);
- Sources.overrideFileContents(Entry, Source, true);
- assert(Entry != NULL);
- return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
- }
-
- std::string getRewrittenText(FileID ID) {
- std::string Result;
- llvm::raw_string_ostream OS(Result);
- Rewrite.getEditBuffer(ID).write(OS);
- OS.flush();
- return Result;
- }
-
- IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
- IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
- FileManager Files;
- SourceManager Sources;
- Rewriter Rewrite;
-};
-
-} // end namespace clang
-
-#endif
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 0c9912e..9bf26c9 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -2,6 +2,7 @@ clang_CXCursorSet_contains
clang_CXCursorSet_insert
clang_CXIndex_getGlobalOptions
clang_CXIndex_setGlobalOptions
+clang_CXXMethod_isPureVirtual
clang_CXXMethod_isStatic
clang_CXXMethod_isVirtual
clang_Cursor_getArgument
@@ -19,6 +20,7 @@ clang_Cursor_getReceiverType
clang_Cursor_isBitField
clang_Cursor_isDynamicCall
clang_Cursor_isNull
+clang_Cursor_isObjCOptional
clang_Cursor_isVariadic
clang_Cursor_getModule
clang_Module_getASTFile
@@ -59,8 +61,10 @@ clang_TParamCommandComment_isParamPositionValid
clang_TParamCommandComment_getDepth
clang_TParamCommandComment_getIndex
clang_Type_getAlignOf
+clang_Type_getClassType
clang_Type_getSizeOf
clang_Type_getOffsetOf
+clang_Type_getCXXRefQualifier
clang_VerbatimBlockLineComment_getText
clang_VerbatimLineComment_getText
clang_HTMLTagComment_getAsString
@@ -253,6 +257,7 @@ clang_isVirtualBase
clang_isVolatileQualifiedType
clang_loadDiagnostics
clang_Location_isInSystemHeader
+clang_Location_isFromMainFile
clang_parseTranslationUnit
clang_remap_dispose
clang_remap_getFilenames
OpenPOWER on IntegriCloud