summaryrefslogtreecommitdiffstats
path: root/tools/libclang
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libclang')
-rw-r--r--tools/libclang/ARCMigrate.cpp11
-rw-r--r--tools/libclang/CIndex.cpp1826
-rw-r--r--tools/libclang/CIndexCXX.cpp25
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp108
-rw-r--r--tools/libclang/CIndexDiagnostic.cpp35
-rw-r--r--tools/libclang/CIndexHigh.cpp254
-rw-r--r--tools/libclang/CIndexInclusionStack.cpp7
-rw-r--r--tools/libclang/CIndexUSRs.cpp174
-rw-r--r--tools/libclang/CIndexer.cpp6
-rw-r--r--tools/libclang/CIndexer.h33
-rw-r--r--tools/libclang/CLog.h101
-rw-r--r--tools/libclang/CMakeLists.txt7
-rw-r--r--tools/libclang/CXComment.cpp212
-rw-r--r--tools/libclang/CXComment.h7
-rw-r--r--tools/libclang/CXCompilationDatabase.cpp24
-rw-r--r--tools/libclang/CXCursor.cpp255
-rw-r--r--tools/libclang/CXCursor.h100
-rw-r--r--tools/libclang/CXLoadedDiagnostic.cpp129
-rw-r--r--tools/libclang/CXLoadedDiagnostic.h4
-rw-r--r--tools/libclang/CXSourceLocation.cpp99
-rw-r--r--tools/libclang/CXSourceLocation.h6
-rw-r--r--tools/libclang/CXStoredDiagnostic.cpp17
-rw-r--r--tools/libclang/CXString.cpp147
-rw-r--r--tools/libclang/CXString.h82
-rw-r--r--tools/libclang/CXTranslationUnit.h30
-rw-r--r--tools/libclang/CXType.cpp110
-rw-r--r--tools/libclang/CursorVisitor.h29
-rw-r--r--tools/libclang/IndexBody.cpp1
-rw-r--r--tools/libclang/IndexDecl.cpp75
-rw-r--r--tools/libclang/IndexTypeSourceInfo.cpp1
-rw-r--r--tools/libclang/Indexing.cpp340
-rw-r--r--tools/libclang/IndexingContext.cpp79
-rw-r--r--tools/libclang/IndexingContext.h9
-rw-r--r--tools/libclang/Makefile15
-rw-r--r--tools/libclang/RecursiveASTVisitor.h16
-rw-r--r--tools/libclang/SimpleFormatContext.h75
-rw-r--r--tools/libclang/libclang.exports7
37 files changed, 2881 insertions, 1575 deletions
diff --git a/tools/libclang/ARCMigrate.cpp b/tools/libclang/ARCMigrate.cpp
index 5ee5cf6..3941794 100644
--- a/tools/libclang/ARCMigrate.cpp
+++ b/tools/libclang/ARCMigrate.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "clang-c/Index.h"
-
#include "CXString.h"
#include "clang/ARCMigrate/ARCMT.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
@@ -123,13 +122,11 @@ unsigned clang_remap_getNumFiles(CXRemapping map) {
void clang_remap_getFilenames(CXRemapping map, unsigned index,
CXString *original, CXString *transformed) {
if (original)
- *original = cxstring::createCXString(
- static_cast<Remap *>(map)->Vec[index].first,
- /*DupString =*/ true);
+ *original = cxstring::createDup(
+ static_cast<Remap *>(map)->Vec[index].first);
if (transformed)
- *transformed = cxstring::createCXString(
- static_cast<Remap *>(map)->Vec[index].second,
- /*DupString =*/ true);
+ *transformed = cxstring::createDup(
+ static_cast<Remap *>(map)->Vec[index].second);
}
void clang_remap_dispose(CXRemapping map) {
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 3a6c408..a81f1e4 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -13,56 +13,63 @@
//===----------------------------------------------------------------------===//
#include "CIndexer.h"
+#include "CIndexDiagnostic.h"
+#include "CLog.h"
#include "CXComment.h"
#include "CXCursor.h"
-#include "CXTranslationUnit.h"
+#include "CXSourceLocation.h"
#include "CXString.h"
+#include "CXTranslationUnit.h"
#include "CXType.h"
-#include "CXSourceLocation.h"
-#include "CIndexDiagnostic.h"
#include "CursorVisitor.h"
-
-#include "clang/Basic/Version.h"
-
+#include "SimpleFormatContext.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/Lex/Lexer.h"
#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/Lexer.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/CrashRecoveryContext.h"
-#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Timer.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"
#include "llvm/Support/Threading.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Timer.h"
+#include "llvm/Support/raw_ostream.h"
+
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
using namespace clang;
using namespace clang::cxcursor;
-using namespace clang::cxstring;
using namespace clang::cxtu;
using namespace clang::cxindex;
-CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *TU) {
- if (!TU)
+CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
+ if (!AU)
return 0;
CXTranslationUnit D = new CXTranslationUnitImpl();
D->CIdx = CIdx;
- D->TUData = TU;
- D->StringPool = createCXStringPool();
+ D->TheASTUnit = AU;
+ D->StringPool = new cxstring::CXStringPool();
D->Diagnostics = 0;
D->OverridenCursorsPool = createOverridenCXCursorsPool();
+ D->FormatContext = 0;
+ D->FormatInMemoryUniqueId = 0;
return D;
}
@@ -122,9 +129,11 @@ CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
EndLoc = EndLoc.getLocWithOffset(Length);
}
- CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
- R.getBegin().getRawEncoding(),
- EndLoc.getRawEncoding() };
+ CXSourceRange Result = {
+ { &SM, &LangOpts },
+ R.getBegin().getRawEncoding(),
+ EndLoc.getRawEncoding()
+ };
return Result;
}
@@ -155,7 +164,7 @@ bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
return false;
if (clang_isDeclaration(Cursor.kind)) {
- Decl *D = getCursorDecl(Cursor);
+ const Decl *D = getCursorDecl(Cursor);
if (!D) {
assert(0 && "Invalid declaration cursor");
return true; // abort.
@@ -214,11 +223,11 @@ static bool visitPreprocessedEntitiesInRange(SourceRange R,
PPRec, FID);
}
-void CursorVisitor::visitFileRegion() {
+bool CursorVisitor::visitFileRegion() {
if (RegionOfInterest.isInvalid())
- return;
+ return false;
- ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
SourceManager &SM = Unit->getSourceManager();
std::pair<FileID, unsigned>
@@ -234,7 +243,7 @@ void CursorVisitor::visitFileRegion() {
assert(Begin.first == End.first);
if (Begin.second > End.second)
- return;
+ return false;
FileID File = Begin.first;
unsigned Offset = Begin.second;
@@ -242,12 +251,15 @@ void CursorVisitor::visitFileRegion() {
if (!VisitDeclsOnly && !VisitPreprocessorLast)
if (visitPreprocessedEntitiesInRegion())
- return; // visitation break.
+ return true; // visitation break.
- visitDeclsFromFileRegion(File, Offset, Length);
+ if (visitDeclsFromFileRegion(File, Offset, Length))
+ return true; // visitation break.
if (!VisitDeclsOnly && VisitPreprocessorLast)
- visitPreprocessedEntitiesInRegion();
+ return visitPreprocessedEntitiesInRegion();
+
+ return false;
}
static bool isInLexicalContext(Decl *D, DeclContext *DC) {
@@ -262,9 +274,9 @@ static bool isInLexicalContext(Decl *D, DeclContext *DC) {
return false;
}
-void CursorVisitor::visitDeclsFromFileRegion(FileID File,
+bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
unsigned Offset, unsigned Length) {
- ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
SourceManager &SM = Unit->getSourceManager();
SourceRange Range = RegionOfInterest;
@@ -277,7 +289,7 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File,
bool Invalid = false;
const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
if (Invalid)
- return;
+ return false;
SourceLocation Outer;
if (SLEntry.isFile())
@@ -285,7 +297,7 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File,
else
Outer = SLEntry.getExpansion().getExpansionLocStart();
if (Outer.isInvalid())
- return;
+ return false;
llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Length = 0;
@@ -328,11 +340,11 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File,
}
if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
- break;
+ return true; // visitation break.
}
if (VisitedAtLeastOnce)
- return;
+ return false;
// No Decls overlapped with the range. Move up the lexical context until there
// is a context that contains the range or we reach the translation unit
@@ -347,12 +359,14 @@ void CursorVisitor::visitDeclsFromFileRegion(FileID File,
break;
if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
- Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true);
- break;
+ if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
+ return true; // visitation break.
}
DC = D->getLexicalDeclContext();
}
+
+ return false;
}
bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
@@ -453,7 +467,7 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
SetParentRAII SetParent(Parent, StmtParent, Cursor);
if (clang_isDeclaration(Cursor.kind)) {
- Decl *D = getCursorDecl(Cursor);
+ Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
if (!D)
return false;
@@ -461,22 +475,22 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
}
if (clang_isStatement(Cursor.kind)) {
- if (Stmt *S = getCursorStmt(Cursor))
+ if (const Stmt *S = getCursorStmt(Cursor))
return Visit(S);
return false;
}
if (clang_isExpression(Cursor.kind)) {
- if (Expr *E = getCursorExpr(Cursor))
+ if (const Expr *E = getCursorExpr(Cursor))
return Visit(E);
return false;
}
if (clang_isTranslationUnit(Cursor.kind)) {
- CXTranslationUnit tu = getCursorTU(Cursor);
- ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
+ CXTranslationUnit TU = getCursorTU(Cursor);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
for (unsigned I = 0; I != 2; ++I) {
@@ -486,7 +500,7 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
TLEnd = CXXUnit->top_level_end();
TL != TLEnd; ++TL) {
- if (Visit(MakeCXCursor(*TL, tu, RegionOfInterest), true))
+ if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
return true;
}
} else if (VisitDeclContext(
@@ -504,7 +518,7 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
}
if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
- if (CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
+ if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
return Visit(BaseTSInfo->getTypeLoc());
}
@@ -512,13 +526,27 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
}
if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
- IBOutletCollectionAttr *A =
+ 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 pointing inside a macro definition, check if the token is an identifier
+ // that was ever defined as a macro. In such a case, create a "pseudo" macro
+ // expansion cursor for that token.
+ SourceLocation BeginLoc = RegionOfInterest.getBegin();
+ if (Cursor.kind == CXCursor_MacroDefinition &&
+ BeginLoc == RegionOfInterest.getEnd()) {
+ SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
+ const MacroInfo *MI =
+ getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
+ if (MacroDefinition *MacroDef =
+ checkForMacroInMacroDefinition(MI, Loc, TU))
+ return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
+ }
+
// Nothing to visit at the moment.
return false;
}
@@ -534,16 +562,16 @@ bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
return false;
}
-llvm::Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
+Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
if (RegionOfInterest.isValid()) {
SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
if (Range.isInvalid())
- return llvm::Optional<bool>();
+ return None;
switch (CompareRegionOfInterest(Range)) {
case RangeBefore:
// This declaration comes before the region of interest; skip it.
- return llvm::Optional<bool>();
+ return None;
case RangeAfter:
// This declaration comes after the region of interest; we're done.
@@ -594,7 +622,7 @@ bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
}
- const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
+ const Optional<bool> &V = shouldVisitCursor(Cursor);
if (!V.hasValue())
continue;
if (!V.getValue())
@@ -648,10 +676,10 @@ bool CursorVisitor::VisitClassTemplateSpecializationDecl(
// Visit the template arguments used in the specialization.
if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
TypeLoc TL = SpecType->getTypeLoc();
- if (TemplateSpecializationTypeLoc *TSTLoc
- = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
- for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
- if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
+ if (TemplateSpecializationTypeLoc TSTLoc =
+ TL.getAs<TemplateSpecializationTypeLoc>()) {
+ for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
+ if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
return true;
}
}
@@ -727,12 +755,12 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
// Visit the function declaration's syntactic components in the order
// written. This requires a bit of work.
TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
- FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL);
+ FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
// If we have a function declared directly (without the use of a typedef),
// visit just the return type. Otherwise, just visit the function's type
// now.
- if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL->getResultLoc())) ||
+ if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
(!FTL && Visit(TL)))
return true;
@@ -748,7 +776,7 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
// FIXME: Visit explicitly-specified template arguments!
// Visit the function parameters, if we have a function type.
- if (FTL && VisitFunctionTypeLoc(*FTL, true))
+ if (FTL && VisitFunctionTypeLoc(FTL, true))
return true;
// FIXME: Attributes?
@@ -958,7 +986,7 @@ bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
E = DeclsInContainer.end(); I != E; ++I) {
CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
- const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
+ const Optional<bool> &V = shouldVisitCursor(Cursor);
if (!V.hasValue())
continue;
if (!V.getValue())
@@ -1369,6 +1397,14 @@ bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
case BuiltinType::Void:
case BuiltinType::NullPtr:
case BuiltinType::Dependent:
+ case BuiltinType::OCLImage1d:
+ case BuiltinType::OCLImage1dArray:
+ case BuiltinType::OCLImage1dBuffer:
+ case BuiltinType::OCLImage2d:
+ case BuiltinType::OCLImage2dArray:
+ case BuiltinType::OCLImage3d:
+ case BuiltinType::OCLSampler:
+ case BuiltinType::OCLEvent:
#define BUILTIN_TYPE(Id, SingletonId)
#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
@@ -1629,9 +1665,10 @@ namespace {
#define DEF_JOB(NAME, DATA, KIND)\
class NAME : public VisitorJob {\
public:\
- NAME(DATA *d, CXCursor parent) : VisitorJob(parent, VisitorJob::KIND, d) {} \
+ NAME(const DATA *d, CXCursor parent) : \
+ VisitorJob(parent, VisitorJob::KIND, d) {} \
static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
- DATA *get() const { return static_cast<DATA*>(data[0]); }\
+ const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
};
DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
@@ -1647,13 +1684,13 @@ DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
class DeclVisit : public VisitorJob {
public:
- DeclVisit(Decl *d, CXCursor parent, bool isFirst) :
+ DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
VisitorJob(parent, VisitorJob::DeclVisitKind,
- d, isFirst ? (void*) 1 : (void*) 0) {}
+ D, isFirst ? (void*) 1 : (void*) 0) {}
static bool classof(const VisitorJob *VJ) {
return VJ->getKind() == DeclVisitKind;
}
- Decl *get() const { return static_cast<Decl*>(data[0]); }
+ const Decl *get() const { return static_cast<const Decl *>(data[0]); }
bool isFirst() const { return data[1] ? true : false; }
};
class TypeLocVisit : public VisitorJob {
@@ -1668,7 +1705,7 @@ public:
TypeLoc get() const {
QualType T = QualType::getFromOpaquePtr(data[0]);
- return TypeLoc(T, data[1]);
+ return TypeLoc(T, const_cast<void *>(data[1]));
}
};
@@ -1681,7 +1718,9 @@ public:
static bool classof(const VisitorJob *VJ) {
return VJ->getKind() == VisitorJob::LabelRefVisitKind;
}
- LabelDecl *get() const { return static_cast<LabelDecl*>(data[0]); }
+ const LabelDecl *get() const {
+ return static_cast<const LabelDecl *>(data[0]);
+ }
SourceLocation getLoc() const {
return SourceLocation::getFromPtrEncoding(data[1]); }
};
@@ -1698,20 +1737,22 @@ public:
}
NestedNameSpecifierLoc get() const {
- return NestedNameSpecifierLoc(static_cast<NestedNameSpecifier*>(data[0]),
- data[1]);
+ return NestedNameSpecifierLoc(
+ const_cast<NestedNameSpecifier *>(
+ static_cast<const NestedNameSpecifier *>(data[0])),
+ const_cast<void *>(data[1]));
}
};
class DeclarationNameInfoVisit : public VisitorJob {
public:
- DeclarationNameInfoVisit(Stmt *S, CXCursor parent)
+ DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
: VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
static bool classof(const VisitorJob *VJ) {
return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
}
DeclarationNameInfo get() const {
- Stmt *S = static_cast<Stmt*>(data[0]);
+ const Stmt *S = static_cast<const Stmt *>(data[0]);
switch (S->getStmtClass()) {
default:
llvm_unreachable("Unhandled Stmt");
@@ -1726,85 +1767,85 @@ public:
};
class MemberRefVisit : public VisitorJob {
public:
- MemberRefVisit(FieldDecl *D, SourceLocation L, CXCursor parent)
+ MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
: VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
L.getPtrEncoding()) {}
static bool classof(const VisitorJob *VJ) {
return VJ->getKind() == VisitorJob::MemberRefVisitKind;
}
- FieldDecl *get() const {
- return static_cast<FieldDecl*>(data[0]);
+ const FieldDecl *get() const {
+ return static_cast<const FieldDecl *>(data[0]);
}
SourceLocation getLoc() const {
return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
}
};
-class EnqueueVisitor : public StmtVisitor<EnqueueVisitor, void> {
+class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
VisitorWorkList &WL;
CXCursor Parent;
public:
EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
: WL(wl), Parent(parent) {}
- void VisitAddrLabelExpr(AddrLabelExpr *E);
- void VisitBlockExpr(BlockExpr *B);
- void VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
- void VisitCompoundStmt(CompoundStmt *S);
- void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { /* Do nothing. */ }
- void VisitMSDependentExistsStmt(MSDependentExistsStmt *S);
- void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
- void VisitCXXNewExpr(CXXNewExpr *E);
- void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
- void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
- void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
- void VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
- void VisitCXXTypeidExpr(CXXTypeidExpr *E);
- void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
- void VisitCXXUuidofExpr(CXXUuidofExpr *E);
- void VisitCXXCatchStmt(CXXCatchStmt *S);
- void VisitDeclRefExpr(DeclRefExpr *D);
- void VisitDeclStmt(DeclStmt *S);
- void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
- void VisitDesignatedInitExpr(DesignatedInitExpr *E);
- void VisitExplicitCastExpr(ExplicitCastExpr *E);
- void VisitForStmt(ForStmt *FS);
- void VisitGotoStmt(GotoStmt *GS);
- void VisitIfStmt(IfStmt *If);
- void VisitInitListExpr(InitListExpr *IE);
- void VisitMemberExpr(MemberExpr *M);
- void VisitOffsetOfExpr(OffsetOfExpr *E);
- void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
- void VisitObjCMessageExpr(ObjCMessageExpr *M);
- void VisitOverloadExpr(OverloadExpr *E);
- void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
- void VisitStmt(Stmt *S);
- void VisitSwitchStmt(SwitchStmt *S);
- void VisitWhileStmt(WhileStmt *W);
- void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
- void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
- void VisitTypeTraitExpr(TypeTraitExpr *E);
- void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
- void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
- void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
- void VisitVAArgExpr(VAArgExpr *E);
- void VisitSizeOfPackExpr(SizeOfPackExpr *E);
- void VisitPseudoObjectExpr(PseudoObjectExpr *E);
- void VisitOpaqueValueExpr(OpaqueValueExpr *E);
- void VisitLambdaExpr(LambdaExpr *E);
-
+ void VisitAddrLabelExpr(const AddrLabelExpr *E);
+ void VisitBlockExpr(const BlockExpr *B);
+ void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
+ void VisitCompoundStmt(const CompoundStmt *S);
+ void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
+ void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
+ void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
+ void VisitCXXNewExpr(const CXXNewExpr *E);
+ void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
+ void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
+ void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
+ void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
+ void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
+ void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
+ void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
+ void VisitCXXCatchStmt(const CXXCatchStmt *S);
+ void VisitDeclRefExpr(const DeclRefExpr *D);
+ void VisitDeclStmt(const DeclStmt *S);
+ void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
+ void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
+ void VisitExplicitCastExpr(const ExplicitCastExpr *E);
+ void VisitForStmt(const ForStmt *FS);
+ void VisitGotoStmt(const GotoStmt *GS);
+ void VisitIfStmt(const IfStmt *If);
+ void VisitInitListExpr(const InitListExpr *IE);
+ void VisitMemberExpr(const MemberExpr *M);
+ void VisitOffsetOfExpr(const OffsetOfExpr *E);
+ void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
+ void VisitObjCMessageExpr(const ObjCMessageExpr *M);
+ void VisitOverloadExpr(const OverloadExpr *E);
+ void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
+ void VisitStmt(const Stmt *S);
+ void VisitSwitchStmt(const SwitchStmt *S);
+ void VisitWhileStmt(const WhileStmt *W);
+ void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
+ void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
+ void VisitTypeTraitExpr(const TypeTraitExpr *E);
+ void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
+ void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
+ void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
+ void VisitVAArgExpr(const VAArgExpr *E);
+ void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
+ void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
+ void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
+ void VisitLambdaExpr(const LambdaExpr *E);
+
private:
- void AddDeclarationNameInfo(Stmt *S);
+ void AddDeclarationNameInfo(const Stmt *S);
void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
- void AddMemberRef(FieldDecl *D, SourceLocation L);
- void AddStmt(Stmt *S);
- void AddDecl(Decl *D, bool isFirst = true);
+ void AddMemberRef(const FieldDecl *D, SourceLocation L);
+ void AddStmt(const Stmt *S);
+ void AddDecl(const Decl *D, bool isFirst = true);
void AddTypeLoc(TypeSourceInfo *TI);
- void EnqueueChildren(Stmt *S);
+ void EnqueueChildren(const Stmt *S);
};
} // end anonyous namespace
-void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
+void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
// 'S' should always be non-null, since it comes from the
// statement we are visiting.
WL.push_back(DeclarationNameInfoVisit(S, Parent));
@@ -1816,21 +1857,20 @@ EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
}
-void EnqueueVisitor::AddStmt(Stmt *S) {
+void EnqueueVisitor::AddStmt(const Stmt *S) {
if (S)
WL.push_back(StmtVisit(S, Parent));
}
-void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
+void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
if (D)
WL.push_back(DeclVisit(D, Parent, isFirst));
}
void EnqueueVisitor::
AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
if (A)
- WL.push_back(ExplicitTemplateArgsVisit(
- const_cast<ASTTemplateArgumentListInfo*>(A), Parent));
+ WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
}
-void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
+void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
if (D)
WL.push_back(MemberRefVisit(D, L, Parent));
}
@@ -1838,9 +1878,9 @@ void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
if (TI)
WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
}
-void EnqueueVisitor::EnqueueChildren(Stmt *S) {
+void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
unsigned size = WL.size();
- for (Stmt::child_range Child = S->children(); Child; ++Child) {
+ for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
AddStmt(*Child);
}
if (size == WL.size())
@@ -1850,24 +1890,24 @@ void EnqueueVisitor::EnqueueChildren(Stmt *S) {
VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
std::reverse(I, E);
}
-void EnqueueVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) {
+void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
}
-void EnqueueVisitor::VisitBlockExpr(BlockExpr *B) {
+void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
AddDecl(B->getBlockDecl());
}
-void EnqueueVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
EnqueueChildren(E);
AddTypeLoc(E->getTypeSourceInfo());
}
-void EnqueueVisitor::VisitCompoundStmt(CompoundStmt *S) {
- for (CompoundStmt::reverse_body_iterator I = S->body_rbegin(),
+void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
+ for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
E = S->body_rend(); I != E; ++I) {
AddStmt(*I);
}
}
void EnqueueVisitor::
-VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
+VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
AddStmt(S->getSubStmt());
AddDeclarationNameInfo(S);
if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
@@ -1875,7 +1915,7 @@ VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
}
void EnqueueVisitor::
-VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
+VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
AddDeclarationNameInfo(E);
if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
@@ -1883,7 +1923,7 @@ VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
if (!E->isImplicitAccess())
AddStmt(E->getBase());
}
-void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
+void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
// Enqueue the initializer , if any.
AddStmt(E->getInitializer());
// Enqueue the array size, if any.
@@ -1894,13 +1934,14 @@ void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
AddStmt(E->getPlacementArg(I-1));
}
-void EnqueueVisitor::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *CE) {
+void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
AddStmt(CE->getArg(I-1));
AddStmt(CE->getCallee());
AddStmt(CE->getArg(0));
}
-void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
+void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
+ const CXXPseudoDestructorExpr *E) {
// Visit the name of the type being destroyed.
AddTypeLoc(E->getDestroyedTypeInfo());
// Visit the scope type that looks disturbingly like the nested-name-specifier
@@ -1912,50 +1953,53 @@ void EnqueueVisitor::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
// Visit base expression.
AddStmt(E->getBase());
}
-void EnqueueVisitor::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
+void EnqueueVisitor::VisitCXXScalarValueInitExpr(
+ const CXXScalarValueInitExpr *E) {
AddTypeLoc(E->getTypeSourceInfo());
}
-void EnqueueVisitor::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
+void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
+ const CXXTemporaryObjectExpr *E) {
EnqueueChildren(E);
AddTypeLoc(E->getTypeSourceInfo());
}
-void EnqueueVisitor::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
EnqueueChildren(E);
if (E->isTypeOperand())
AddTypeLoc(E->getTypeOperandSourceInfo());
}
-void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr
- *E) {
+void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
+ const CXXUnresolvedConstructExpr *E) {
EnqueueChildren(E);
AddTypeLoc(E->getTypeSourceInfo());
}
-void EnqueueVisitor::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
+void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
EnqueueChildren(E);
if (E->isTypeOperand())
AddTypeLoc(E->getTypeOperandSourceInfo());
}
-void EnqueueVisitor::VisitCXXCatchStmt(CXXCatchStmt *S) {
+void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
EnqueueChildren(S);
AddDecl(S->getExceptionDecl());
}
-void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) {
+void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
if (DR->hasExplicitTemplateArgs()) {
AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
}
WL.push_back(DeclRefExprParts(DR, Parent));
}
-void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
+ const DependentScopeDeclRefExpr *E) {
AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
AddDeclarationNameInfo(E);
AddNestedNameSpecifierLoc(E->getQualifierLoc());
}
-void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
+void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
unsigned size = WL.size();
bool isFirst = true;
- for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
+ for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
D != DEnd; ++D) {
AddDecl(*D, isFirst);
isFirst = false;
@@ -1967,10 +2011,10 @@ void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) {
VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
std::reverse(I, E);
}
-void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
AddStmt(E->getInit());
typedef DesignatedInitExpr::Designator Designator;
- for (DesignatedInitExpr::reverse_designators_iterator
+ for (DesignatedInitExpr::const_reverse_designators_iterator
D = E->designators_rbegin(), DEnd = E->designators_rend();
D != DEnd; ++D) {
if (D->isFieldDesignator()) {
@@ -1987,33 +2031,33 @@ void EnqueueVisitor::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
AddStmt(E->getArrayRangeStart(*D));
}
}
-void EnqueueVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) {
+void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
EnqueueChildren(E);
AddTypeLoc(E->getTypeInfoAsWritten());
}
-void EnqueueVisitor::VisitForStmt(ForStmt *FS) {
+void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
AddStmt(FS->getBody());
AddStmt(FS->getInc());
AddStmt(FS->getCond());
AddDecl(FS->getConditionVariable());
AddStmt(FS->getInit());
}
-void EnqueueVisitor::VisitGotoStmt(GotoStmt *GS) {
+void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
}
-void EnqueueVisitor::VisitIfStmt(IfStmt *If) {
+void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
AddStmt(If->getElse());
AddStmt(If->getThen());
AddStmt(If->getCond());
AddDecl(If->getConditionVariable());
}
-void EnqueueVisitor::VisitInitListExpr(InitListExpr *IE) {
+void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
// We care about the syntactic form of the initializer list, only.
if (InitListExpr *Syntactic = IE->getSyntacticForm())
IE = Syntactic;
EnqueueChildren(IE);
}
-void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
+void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
WL.push_back(MemberExprParts(M, Parent));
// If the base of the member access expression is an implicit 'this', don't
@@ -2023,14 +2067,14 @@ void EnqueueVisitor::VisitMemberExpr(MemberExpr *M) {
if (!M->isImplicitAccess())
AddStmt(M->getBase());
}
-void EnqueueVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
AddTypeLoc(E->getEncodedTypeSourceInfo());
}
-void EnqueueVisitor::VisitObjCMessageExpr(ObjCMessageExpr *M) {
+void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
EnqueueChildren(M);
AddTypeLoc(M->getClassReceiverTypeInfo());
}
-void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
+void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
// Visit the components of the offsetof expression.
for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
@@ -2050,81 +2094,81 @@ void EnqueueVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
// Visit the type into which we're computing the offset.
AddTypeLoc(E->getTypeSourceInfo());
}
-void EnqueueVisitor::VisitOverloadExpr(OverloadExpr *E) {
+void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
WL.push_back(OverloadExprParts(E, Parent));
}
void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
- UnaryExprOrTypeTraitExpr *E) {
+ const UnaryExprOrTypeTraitExpr *E) {
EnqueueChildren(E);
if (E->isArgumentType())
AddTypeLoc(E->getArgumentTypeInfo());
}
-void EnqueueVisitor::VisitStmt(Stmt *S) {
+void EnqueueVisitor::VisitStmt(const Stmt *S) {
EnqueueChildren(S);
}
-void EnqueueVisitor::VisitSwitchStmt(SwitchStmt *S) {
+void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
AddStmt(S->getBody());
AddStmt(S->getCond());
AddDecl(S->getConditionVariable());
}
-void EnqueueVisitor::VisitWhileStmt(WhileStmt *W) {
+void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
AddStmt(W->getBody());
AddStmt(W->getCond());
AddDecl(W->getConditionVariable());
}
-void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
+void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
AddTypeLoc(E->getQueriedTypeSourceInfo());
}
-void EnqueueVisitor::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
+void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
AddTypeLoc(E->getRhsTypeSourceInfo());
AddTypeLoc(E->getLhsTypeSourceInfo());
}
-void EnqueueVisitor::VisitTypeTraitExpr(TypeTraitExpr *E) {
+void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
for (unsigned I = E->getNumArgs(); I > 0; --I)
AddTypeLoc(E->getArg(I-1));
}
-void EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
+void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
AddTypeLoc(E->getQueriedTypeSourceInfo());
}
-void EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
+void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
EnqueueChildren(E);
}
-void EnqueueVisitor::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U) {
+void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
VisitOverloadExpr(U);
if (!U->isImplicitAccess())
AddStmt(U->getBase());
}
-void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) {
+void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
AddStmt(E->getSubExpr());
AddTypeLoc(E->getWrittenTypeInfo());
}
-void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
+void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
WL.push_back(SizeOfPackExprParts(E, Parent));
}
-void EnqueueVisitor::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
+void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
// If the opaque value has a source expression, just transparently
// visit that. This is useful for (e.g.) pseudo-object expressions.
if (Expr *SourceExpr = E->getSourceExpr())
return Visit(SourceExpr);
}
-void EnqueueVisitor::VisitLambdaExpr(LambdaExpr *E) {
+void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
AddStmt(E->getBody());
WL.push_back(LambdaExprParts(E, Parent));
}
-void EnqueueVisitor::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
+void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
// Treat the expression like its syntactic form.
Visit(E->getSyntacticForm());
}
-void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
+void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
}
@@ -2148,7 +2192,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
switch (LI.getKind()) {
case VisitorJob::DeclVisitKind: {
- Decl *D = cast<DeclVisit>(&LI)->get();
+ const Decl *D = cast<DeclVisit>(&LI)->get();
if (!D)
continue;
@@ -2177,7 +2221,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
}
case VisitorJob::LabelRefVisitKind: {
- LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
+ const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
if (LabelStmt *stmt = LS->getStmt()) {
if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
TU))) {
@@ -2207,7 +2251,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
}
case VisitorJob::StmtVisitKind: {
- Stmt *S = cast<StmtVisit>(&LI)->get();
+ const Stmt *S = cast<StmtVisit>(&LI)->get();
if (!S)
continue;
@@ -2228,7 +2272,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
}
case VisitorJob::MemberExprPartsKind: {
// Handle the other pieces in the MemberExpr besides the base.
- MemberExpr *M = cast<MemberExprParts>(&LI)->get();
+ const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
// Visit the nested-name-specifier
if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
@@ -2251,7 +2295,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
}
case VisitorJob::DeclRefExprPartsKind: {
- DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
+ const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
// Visit nested-name-specifier, if present.
if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
if (VisitNestedNameSpecifierLoc(QualifierLoc))
@@ -2262,7 +2306,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
}
case VisitorJob::OverloadExprPartsKind: {
- OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
+ const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
// Visit the nested-name-specifier.
if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
if (VisitNestedNameSpecifierLoc(QualifierLoc))
@@ -2276,7 +2320,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
}
case VisitorJob::SizeOfPackExprPartsKind: {
- SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
+ const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
NamedDecl *Pack = E->getPack();
if (isa<TemplateTypeParmDecl>(Pack)) {
if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
@@ -2301,7 +2345,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
case VisitorJob::LambdaExprPartsKind: {
// Visit captures.
- LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
+ const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
CEnd = E->explicit_capture_end();
C != CEnd; ++C) {
@@ -2321,8 +2365,8 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
// Visit the whole type.
if (Visit(TL))
return true;
- } else if (isa<FunctionProtoTypeLoc>(TL)) {
- FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
+ } else if (FunctionProtoTypeLoc Proto =
+ TL.getAs<FunctionProtoTypeLoc>()) {
if (E->hasExplicitParameters()) {
// Visit parameters.
for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
@@ -2347,7 +2391,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
return false;
}
-bool CursorVisitor::Visit(Stmt *S) {
+bool CursorVisitor::Visit(const Stmt *S) {
VisitorWorkList *WL = 0;
if (!WorkListFreeList.empty()) {
WL = WorkListFreeList.back();
@@ -2365,7 +2409,7 @@ bool CursorVisitor::Visit(Stmt *S) {
}
namespace {
-typedef llvm::SmallVector<SourceRange, 4> RefNamePieces;
+typedef SmallVector<SourceRange, 4> RefNamePieces;
RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
const DeclarationNameInfo &NI,
const SourceRange &QLoc,
@@ -2412,7 +2456,8 @@ RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
static llvm::sys::Mutex EnableMultithreadingMutex;
static bool EnabledMultithreading;
-static void fatal_error_handler(void *user_data, const std::string& reason) {
+static void fatal_error_handler(void *user_data, const std::string& reason,
+ bool gen_crash_diag) {
// Write the result out to stderr avoiding errs() because raw_ostreams can
// call report_fatal_error.
fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
@@ -2486,7 +2531,6 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
FileSystemOptions FileSystemOpts;
- FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
@@ -2560,9 +2604,7 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
// Configure the diagnostics.
IntrusiveRefCntPtr<DiagnosticsEngine>
- Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
- num_command_line_args,
- command_line_args));
+ Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
// Recover resources if we crash before exiting this function.
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
@@ -2662,6 +2704,12 @@ CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
struct CXUnsavedFile *unsaved_files,
unsigned num_unsaved_files,
unsigned options) {
+ LOG_FUNC_SECTION {
+ *Log << source_filename << ": ";
+ for (int i = 0; i != num_command_line_args; ++i)
+ *Log << command_line_args[i] << " ";
+ }
+
ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
num_command_line_args, unsaved_files,
num_unsaved_files, options, 0 };
@@ -2715,20 +2763,24 @@ static void clang_saveTranslationUnit_Impl(void *UserData) {
SaveTranslationUnitInfo *STUI =
static_cast<SaveTranslationUnitInfo*>(UserData);
- CIndexer *CXXIdx = (CIndexer*)STUI->TU->CIdx;
+ CIndexer *CXXIdx = STUI->TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
setThreadBackgroundPriority();
- bool hadError = static_cast<ASTUnit *>(STUI->TU->TUData)->Save(STUI->FileName);
+ bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
}
int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
unsigned options) {
+ LOG_FUNC_SECTION {
+ *Log << TU << ' ' << FileName;
+ }
+
if (!TU)
return CXSaveError_InvalidTU;
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
if (!CXXUnit->hasSema())
return CXSaveError_InvalidTU;
@@ -2769,13 +2821,14 @@ void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
if (CTUnit) {
// If the translation unit has been marked as unsafe to free, just discard
// it.
- if (static_cast<ASTUnit *>(CTUnit->TUData)->isUnsafeToFree())
+ if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
return;
- delete static_cast<ASTUnit *>(CTUnit->TUData);
- disposeCXStringPool(CTUnit->StringPool);
+ delete cxtu::getASTUnit(CTUnit);
+ delete CTUnit->StringPool;
delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
+ delete CTUnit->FormatContext;
delete CTUnit;
}
}
@@ -2796,6 +2849,8 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) {
ReparseTranslationUnitInfo *RTUI =
static_cast<ReparseTranslationUnitInfo*>(UserData);
CXTranslationUnit TU = RTUI->TU;
+ if (!TU)
+ return;
// Reset the associated diagnostics.
delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
@@ -2807,14 +2862,11 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) {
(void) options;
RTUI->result = 1;
- if (!TU)
- return;
-
- CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
+ CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
setThreadBackgroundPriority();
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
OwningPtr<std::vector<ASTUnit::RemappedFile> >
@@ -2841,6 +2893,10 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU,
unsigned num_unsaved_files,
struct CXUnsavedFile *unsaved_files,
unsigned options) {
+ LOG_FUNC_SECTION {
+ *Log << TU;
+ }
+
ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
options, 0 };
@@ -2853,7 +2909,7 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU,
if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
fprintf(stderr, "libclang: crash detected during reparsing\n");
- static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
+ cxtu::getASTUnit(TU)->setUnsafeToFree(true);
return 1;
} else if (getenv("LIBCLANG_RESOURCE_USAGE"))
PrintLibclangResourceUsage(TU);
@@ -2864,14 +2920,17 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU,
CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
if (!CTUnit)
- return createCXString("");
+ return cxstring::createEmpty();
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit->TUData);
- return createCXString(CXXUnit->getOriginalSourceFileName(), true);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
+ return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
}
CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
- ASTUnit *CXXUnit = static_cast<ASTUnit*>(TU->TUData);
+ if (!TU)
+ return clang_getNullCursor();
+
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
}
@@ -2884,10 +2943,10 @@ CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
extern "C" {
CXString clang_getFileName(CXFile SFile) {
if (!SFile)
- return createCXString((const char*)NULL);
+ return cxstring::createNull();
FileEntry *FEnt = static_cast<FileEntry *>(SFile);
- return createCXString(FEnt->getName());
+ return cxstring::createRef(FEnt->getName());
}
time_t clang_getFileTime(CXFile SFile) {
@@ -2898,43 +2957,58 @@ time_t clang_getFileTime(CXFile SFile) {
return FEnt->getModificationTime();
}
-CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) {
- if (!tu)
+CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
+ if (!TU)
return 0;
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
FileManager &FMgr = CXXUnit->getFileManager();
return const_cast<FileEntry *>(FMgr.getFile(file_name));
}
-unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file) {
- if (!tu || !file)
+unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
+ if (!TU || !file)
return 0;
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
FileEntry *FEnt = static_cast<FileEntry *>(file);
return CXXUnit->getPreprocessor().getHeaderSearchInfo()
.isFileMultipleIncludeGuarded(FEnt);
}
+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();
+ outID->data[2] = FEnt->getModificationTime();
+ return 0;
+#endif
+}
+
} // end: extern "C"
//===----------------------------------------------------------------------===//
// CXCursor Operations.
//===----------------------------------------------------------------------===//
-static Decl *getDeclFromExpr(Stmt *E) {
- if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
+static const Decl *getDeclFromExpr(const Stmt *E) {
+ if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
return getDeclFromExpr(CE->getSubExpr());
- if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
+ if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
return RefExpr->getDecl();
- if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
+ if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
return ME->getMemberDecl();
- if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
+ if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
return RE->getDecl();
- if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
+ if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
if (PRE->isExplicitProperty())
return PRE->getExplicitProperty();
// It could be messaging both getter and setter as in:
@@ -2945,26 +3019,26 @@ static Decl *getDeclFromExpr(Stmt *E) {
return PRE->getImplicitPropertySetter();
return PRE->getImplicitPropertyGetter();
}
- if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
+ if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
return getDeclFromExpr(POE->getSyntacticForm());
- if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
+ if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
if (Expr *Src = OVE->getSourceExpr())
return getDeclFromExpr(Src);
- if (CallExpr *CE = dyn_cast<CallExpr>(E))
+ if (const CallExpr *CE = dyn_cast<CallExpr>(E))
return getDeclFromExpr(CE->getCallee());
- if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
+ if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
if (!CE->isElidable())
return CE->getConstructor();
- if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
+ if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
return OME->getMethodDecl();
- if (ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
+ if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
return PE->getProtocol();
- if (SubstNonTypeTemplateParmPackExpr *NTTP
+ if (const SubstNonTypeTemplateParmPackExpr *NTTP
= dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
return NTTP->getParameterPack();
- if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
+ if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
isa<ParmVarDecl>(SizeOfPack->getPack()))
return SizeOfPack->getPack();
@@ -2972,21 +3046,21 @@ static Decl *getDeclFromExpr(Stmt *E) {
return 0;
}
-static SourceLocation getLocationFromExpr(Expr *E) {
- if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
+static SourceLocation getLocationFromExpr(const Expr *E) {
+ if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
return getLocationFromExpr(CE->getSubExpr());
- if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
+ if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
return /*FIXME:*/Msg->getLeftLoc();
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
return DRE->getLocation();
- if (MemberExpr *Member = dyn_cast<MemberExpr>(E))
+ if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
return Member->getMemberLoc();
- if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
+ if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
return Ivar->getLocation();
- if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
+ if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
return SizeOfPack->getPackLoc();
- if (ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
+ if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
return PropRef->getLocation();
return E->getLocStart();
@@ -3039,169 +3113,169 @@ unsigned clang_visitChildrenWithBlock(CXCursor parent,
return clang_visitChildren(parent, visitWithBlock, block);
}
-static CXString getDeclSpelling(Decl *D) {
+static CXString getDeclSpelling(const Decl *D) {
if (!D)
- return createCXString("");
+ return cxstring::createEmpty();
- NamedDecl *ND = dyn_cast<NamedDecl>(D);
+ const NamedDecl *ND = dyn_cast<NamedDecl>(D);
if (!ND) {
- if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
+ if (const ObjCPropertyImplDecl *PropImpl =
+ dyn_cast<ObjCPropertyImplDecl>(D))
if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
- return createCXString(Property->getIdentifier()->getName());
+ return cxstring::createDup(Property->getIdentifier()->getName());
- if (ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
+ if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
if (Module *Mod = ImportD->getImportedModule())
- return createCXString(Mod->getFullModuleName());
+ return cxstring::createDup(Mod->getFullModuleName());
- return createCXString("");
+ return cxstring::createEmpty();
}
- if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
- return createCXString(OMD->getSelector().getAsString());
+ if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
+ return cxstring::createDup(OMD->getSelector().getAsString());
- if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
+ if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
// No, this isn't the same as the code below. getIdentifier() is non-virtual
// and returns different names. NamedDecl returns the class name and
// ObjCCategoryImplDecl returns the category name.
- return createCXString(CIMP->getIdentifier()->getNameStart());
+ return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
if (isa<UsingDirectiveDecl>(D))
- return createCXString("");
+ return cxstring::createEmpty();
SmallString<1024> S;
llvm::raw_svector_ostream os(S);
ND->printName(os);
- return createCXString(os.str());
+ return cxstring::createDup(os.str());
}
CXString clang_getCursorSpelling(CXCursor C) {
if (clang_isTranslationUnit(C.kind))
- return clang_getTranslationUnitSpelling(
- static_cast<CXTranslationUnit>(C.data[2]));
+ return clang_getTranslationUnitSpelling(getCursorTU(C));
if (clang_isReference(C.kind)) {
switch (C.kind) {
case CXCursor_ObjCSuperClassRef: {
- ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
- return createCXString(Super->getIdentifier()->getNameStart());
+ const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
+ return cxstring::createRef(Super->getIdentifier()->getNameStart());
}
case CXCursor_ObjCClassRef: {
- ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
- return createCXString(Class->getIdentifier()->getNameStart());
+ const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
+ return cxstring::createRef(Class->getIdentifier()->getNameStart());
}
case CXCursor_ObjCProtocolRef: {
- ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
+ const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
assert(OID && "getCursorSpelling(): Missing protocol decl");
- return createCXString(OID->getIdentifier()->getNameStart());
+ return cxstring::createRef(OID->getIdentifier()->getNameStart());
}
case CXCursor_CXXBaseSpecifier: {
- CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
- return createCXString(B->getType().getAsString());
+ const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
+ return cxstring::createDup(B->getType().getAsString());
}
case CXCursor_TypeRef: {
- TypeDecl *Type = getCursorTypeRef(C).first;
+ const TypeDecl *Type = getCursorTypeRef(C).first;
assert(Type && "Missing type decl");
- return createCXString(getCursorContext(C).getTypeDeclType(Type).
+ return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
getAsString());
}
case CXCursor_TemplateRef: {
- TemplateDecl *Template = getCursorTemplateRef(C).first;
+ const TemplateDecl *Template = getCursorTemplateRef(C).first;
assert(Template && "Missing template decl");
- return createCXString(Template->getNameAsString());
+ return cxstring::createDup(Template->getNameAsString());
}
case CXCursor_NamespaceRef: {
- NamedDecl *NS = getCursorNamespaceRef(C).first;
+ const NamedDecl *NS = getCursorNamespaceRef(C).first;
assert(NS && "Missing namespace decl");
- return createCXString(NS->getNameAsString());
+ return cxstring::createDup(NS->getNameAsString());
}
case CXCursor_MemberRef: {
- FieldDecl *Field = getCursorMemberRef(C).first;
+ const FieldDecl *Field = getCursorMemberRef(C).first;
assert(Field && "Missing member decl");
- return createCXString(Field->getNameAsString());
+ return cxstring::createDup(Field->getNameAsString());
}
case CXCursor_LabelRef: {
- LabelStmt *Label = getCursorLabelRef(C).first;
+ const LabelStmt *Label = getCursorLabelRef(C).first;
assert(Label && "Missing label");
- return createCXString(Label->getName());
+ return cxstring::createRef(Label->getName());
}
case CXCursor_OverloadedDeclRef: {
OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
- if (Decl *D = Storage.dyn_cast<Decl *>()) {
- if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
- return createCXString(ND->getNameAsString());
- return createCXString("");
+ if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
+ if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
+ return cxstring::createDup(ND->getNameAsString());
+ return cxstring::createEmpty();
}
- if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
- return createCXString(E->getName().getAsString());
+ if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
+ return cxstring::createDup(E->getName().getAsString());
OverloadedTemplateStorage *Ovl
= Storage.get<OverloadedTemplateStorage*>();
if (Ovl->size() == 0)
- return createCXString("");
- return createCXString((*Ovl->begin())->getNameAsString());
+ return cxstring::createEmpty();
+ return cxstring::createDup((*Ovl->begin())->getNameAsString());
}
case CXCursor_VariableRef: {
- VarDecl *Var = getCursorVariableRef(C).first;
+ const VarDecl *Var = getCursorVariableRef(C).first;
assert(Var && "Missing variable decl");
- return createCXString(Var->getNameAsString());
+ return cxstring::createDup(Var->getNameAsString());
}
default:
- return createCXString("<not implemented>");
+ return cxstring::createRef("<not implemented>");
}
}
if (clang_isExpression(C.kind)) {
- Decl *D = getDeclFromExpr(getCursorExpr(C));
+ const Decl *D = getDeclFromExpr(getCursorExpr(C));
if (D)
return getDeclSpelling(D);
- return createCXString("");
+ return cxstring::createEmpty();
}
if (clang_isStatement(C.kind)) {
- Stmt *S = getCursorStmt(C);
- if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
- return createCXString(Label->getName());
+ const Stmt *S = getCursorStmt(C);
+ if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
+ return cxstring::createRef(Label->getName());
- return createCXString("");
+ return cxstring::createEmpty();
}
if (C.kind == CXCursor_MacroExpansion)
- return createCXString(getCursorMacroExpansion(C)->getName()
+ return cxstring::createRef(getCursorMacroExpansion(C).getName()
->getNameStart());
if (C.kind == CXCursor_MacroDefinition)
- return createCXString(getCursorMacroDefinition(C)->getName()
+ return cxstring::createRef(getCursorMacroDefinition(C)->getName()
->getNameStart());
if (C.kind == CXCursor_InclusionDirective)
- return createCXString(getCursorInclusionDirective(C)->getFileName());
+ return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
if (clang_isDeclaration(C.kind))
return getDeclSpelling(getCursorDecl(C));
if (C.kind == CXCursor_AnnotateAttr) {
- AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
- return createCXString(AA->getAnnotation());
+ const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
+ return cxstring::createDup(AA->getAnnotation());
}
if (C.kind == CXCursor_AsmLabelAttr) {
- AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
- return createCXString(AA->getLabel());
+ const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
+ return cxstring::createDup(AA->getLabel());
}
- return createCXString("");
+ return cxstring::createEmpty();
}
CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
@@ -3213,8 +3287,8 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
ASTContext &Ctx = getCursorContext(C);
if (clang_isStatement(C.kind)) {
- Stmt *S = getCursorStmt(C);
- if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
+ const Stmt *S = getCursorStmt(C);
+ if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
if (pieceIndex > 0)
return clang_getNullRange();
return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
@@ -3224,7 +3298,7 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
}
if (C.kind == CXCursor_ObjCMessageExpr) {
- if (ObjCMessageExpr *
+ if (const ObjCMessageExpr *
ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
if (pieceIndex >= ME->getNumSelectorLocs())
return clang_getNullRange();
@@ -3234,7 +3308,7 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
C.kind == CXCursor_ObjCClassMethodDecl) {
- if (ObjCMethodDecl *
+ if (const ObjCMethodDecl *
MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
if (pieceIndex >= MD->getNumSelectorLocs())
return clang_getNullRange();
@@ -3246,10 +3320,10 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
C.kind == CXCursor_ObjCCategoryImplDecl) {
if (pieceIndex > 0)
return clang_getNullRange();
- if (ObjCCategoryDecl *
+ if (const ObjCCategoryDecl *
CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
- if (ObjCCategoryImplDecl *
+ if (const ObjCCategoryImplDecl *
CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
}
@@ -3257,7 +3331,8 @@ CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
if (C.kind == CXCursor_ModuleImportDecl) {
if (pieceIndex > 0)
return clang_getNullRange();
- if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
+ if (const ImportDecl *ImportD =
+ dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
if (!Locs.empty())
return cxloc::translateSourceRange(Ctx,
@@ -3289,15 +3364,15 @@ CXString clang_getCursorDisplayName(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getCursorSpelling(C);
- Decl *D = getCursorDecl(C);
+ const Decl *D = getCursorDecl(C);
if (!D)
- return createCXString("");
+ return cxstring::createEmpty();
PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
- if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
+ if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
D = FunTmpl->getTemplatedDecl();
- if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+ if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
SmallString<64> Str;
llvm::raw_svector_ostream OS(Str);
OS << *Function;
@@ -3316,10 +3391,10 @@ CXString clang_getCursorDisplayName(CXCursor C) {
OS << "...";
}
OS << ")";
- return createCXString(OS.str());
+ return cxstring::createDup(OS.str());
}
- if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
+ if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
SmallString<64> Str;
llvm::raw_svector_ostream OS(Str);
OS << *ClassTemplate;
@@ -3347,23 +3422,23 @@ CXString clang_getCursorDisplayName(CXCursor C) {
}
OS << ">";
- return createCXString(OS.str());
+ return cxstring::createDup(OS.str());
}
- if (ClassTemplateSpecializationDecl *ClassSpec
+ if (const ClassTemplateSpecializationDecl *ClassSpec
= dyn_cast<ClassTemplateSpecializationDecl>(D)) {
// If the type was explicitly written, use that.
if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
- return createCXString(TSInfo->getType().getAsString(Policy));
+ return cxstring::createDup(TSInfo->getType().getAsString(Policy));
- SmallString<64> Str;
+ SmallString<128> Str;
llvm::raw_svector_ostream OS(Str);
OS << *ClassSpec;
- OS << TemplateSpecializationType::PrintTemplateArgumentList(
+ TemplateSpecializationType::PrintTemplateArgumentList(OS,
ClassSpec->getTemplateArgs().data(),
ClassSpec->getTemplateArgs().size(),
Policy);
- return createCXString(OS.str());
+ return cxstring::createDup(OS.str());
}
return clang_getCursorSpelling(C);
@@ -3372,297 +3447,297 @@ CXString clang_getCursorDisplayName(CXCursor C) {
CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
switch (Kind) {
case CXCursor_FunctionDecl:
- return createCXString("FunctionDecl");
+ return cxstring::createRef("FunctionDecl");
case CXCursor_TypedefDecl:
- return createCXString("TypedefDecl");
+ return cxstring::createRef("TypedefDecl");
case CXCursor_EnumDecl:
- return createCXString("EnumDecl");
+ return cxstring::createRef("EnumDecl");
case CXCursor_EnumConstantDecl:
- return createCXString("EnumConstantDecl");
+ return cxstring::createRef("EnumConstantDecl");
case CXCursor_StructDecl:
- return createCXString("StructDecl");
+ return cxstring::createRef("StructDecl");
case CXCursor_UnionDecl:
- return createCXString("UnionDecl");
+ return cxstring::createRef("UnionDecl");
case CXCursor_ClassDecl:
- return createCXString("ClassDecl");
+ return cxstring::createRef("ClassDecl");
case CXCursor_FieldDecl:
- return createCXString("FieldDecl");
+ return cxstring::createRef("FieldDecl");
case CXCursor_VarDecl:
- return createCXString("VarDecl");
+ return cxstring::createRef("VarDecl");
case CXCursor_ParmDecl:
- return createCXString("ParmDecl");
+ return cxstring::createRef("ParmDecl");
case CXCursor_ObjCInterfaceDecl:
- return createCXString("ObjCInterfaceDecl");
+ return cxstring::createRef("ObjCInterfaceDecl");
case CXCursor_ObjCCategoryDecl:
- return createCXString("ObjCCategoryDecl");
+ return cxstring::createRef("ObjCCategoryDecl");
case CXCursor_ObjCProtocolDecl:
- return createCXString("ObjCProtocolDecl");
+ return cxstring::createRef("ObjCProtocolDecl");
case CXCursor_ObjCPropertyDecl:
- return createCXString("ObjCPropertyDecl");
+ return cxstring::createRef("ObjCPropertyDecl");
case CXCursor_ObjCIvarDecl:
- return createCXString("ObjCIvarDecl");
+ return cxstring::createRef("ObjCIvarDecl");
case CXCursor_ObjCInstanceMethodDecl:
- return createCXString("ObjCInstanceMethodDecl");
+ return cxstring::createRef("ObjCInstanceMethodDecl");
case CXCursor_ObjCClassMethodDecl:
- return createCXString("ObjCClassMethodDecl");
+ return cxstring::createRef("ObjCClassMethodDecl");
case CXCursor_ObjCImplementationDecl:
- return createCXString("ObjCImplementationDecl");
+ return cxstring::createRef("ObjCImplementationDecl");
case CXCursor_ObjCCategoryImplDecl:
- return createCXString("ObjCCategoryImplDecl");
+ return cxstring::createRef("ObjCCategoryImplDecl");
case CXCursor_CXXMethod:
- return createCXString("CXXMethod");
+ return cxstring::createRef("CXXMethod");
case CXCursor_UnexposedDecl:
- return createCXString("UnexposedDecl");
+ return cxstring::createRef("UnexposedDecl");
case CXCursor_ObjCSuperClassRef:
- return createCXString("ObjCSuperClassRef");
+ return cxstring::createRef("ObjCSuperClassRef");
case CXCursor_ObjCProtocolRef:
- return createCXString("ObjCProtocolRef");
+ return cxstring::createRef("ObjCProtocolRef");
case CXCursor_ObjCClassRef:
- return createCXString("ObjCClassRef");
+ return cxstring::createRef("ObjCClassRef");
case CXCursor_TypeRef:
- return createCXString("TypeRef");
+ return cxstring::createRef("TypeRef");
case CXCursor_TemplateRef:
- return createCXString("TemplateRef");
+ return cxstring::createRef("TemplateRef");
case CXCursor_NamespaceRef:
- return createCXString("NamespaceRef");
+ return cxstring::createRef("NamespaceRef");
case CXCursor_MemberRef:
- return createCXString("MemberRef");
+ return cxstring::createRef("MemberRef");
case CXCursor_LabelRef:
- return createCXString("LabelRef");
+ return cxstring::createRef("LabelRef");
case CXCursor_OverloadedDeclRef:
- return createCXString("OverloadedDeclRef");
+ return cxstring::createRef("OverloadedDeclRef");
case CXCursor_VariableRef:
- return createCXString("VariableRef");
+ return cxstring::createRef("VariableRef");
case CXCursor_IntegerLiteral:
- return createCXString("IntegerLiteral");
+ return cxstring::createRef("IntegerLiteral");
case CXCursor_FloatingLiteral:
- return createCXString("FloatingLiteral");
+ return cxstring::createRef("FloatingLiteral");
case CXCursor_ImaginaryLiteral:
- return createCXString("ImaginaryLiteral");
+ return cxstring::createRef("ImaginaryLiteral");
case CXCursor_StringLiteral:
- return createCXString("StringLiteral");
+ return cxstring::createRef("StringLiteral");
case CXCursor_CharacterLiteral:
- return createCXString("CharacterLiteral");
+ return cxstring::createRef("CharacterLiteral");
case CXCursor_ParenExpr:
- return createCXString("ParenExpr");
+ return cxstring::createRef("ParenExpr");
case CXCursor_UnaryOperator:
- return createCXString("UnaryOperator");
+ return cxstring::createRef("UnaryOperator");
case CXCursor_ArraySubscriptExpr:
- return createCXString("ArraySubscriptExpr");
+ return cxstring::createRef("ArraySubscriptExpr");
case CXCursor_BinaryOperator:
- return createCXString("BinaryOperator");
+ return cxstring::createRef("BinaryOperator");
case CXCursor_CompoundAssignOperator:
- return createCXString("CompoundAssignOperator");
+ return cxstring::createRef("CompoundAssignOperator");
case CXCursor_ConditionalOperator:
- return createCXString("ConditionalOperator");
+ return cxstring::createRef("ConditionalOperator");
case CXCursor_CStyleCastExpr:
- return createCXString("CStyleCastExpr");
+ return cxstring::createRef("CStyleCastExpr");
case CXCursor_CompoundLiteralExpr:
- return createCXString("CompoundLiteralExpr");
+ return cxstring::createRef("CompoundLiteralExpr");
case CXCursor_InitListExpr:
- return createCXString("InitListExpr");
+ return cxstring::createRef("InitListExpr");
case CXCursor_AddrLabelExpr:
- return createCXString("AddrLabelExpr");
+ return cxstring::createRef("AddrLabelExpr");
case CXCursor_StmtExpr:
- return createCXString("StmtExpr");
+ return cxstring::createRef("StmtExpr");
case CXCursor_GenericSelectionExpr:
- return createCXString("GenericSelectionExpr");
+ return cxstring::createRef("GenericSelectionExpr");
case CXCursor_GNUNullExpr:
- return createCXString("GNUNullExpr");
+ return cxstring::createRef("GNUNullExpr");
case CXCursor_CXXStaticCastExpr:
- return createCXString("CXXStaticCastExpr");
+ return cxstring::createRef("CXXStaticCastExpr");
case CXCursor_CXXDynamicCastExpr:
- return createCXString("CXXDynamicCastExpr");
+ return cxstring::createRef("CXXDynamicCastExpr");
case CXCursor_CXXReinterpretCastExpr:
- return createCXString("CXXReinterpretCastExpr");
+ return cxstring::createRef("CXXReinterpretCastExpr");
case CXCursor_CXXConstCastExpr:
- return createCXString("CXXConstCastExpr");
+ return cxstring::createRef("CXXConstCastExpr");
case CXCursor_CXXFunctionalCastExpr:
- return createCXString("CXXFunctionalCastExpr");
+ return cxstring::createRef("CXXFunctionalCastExpr");
case CXCursor_CXXTypeidExpr:
- return createCXString("CXXTypeidExpr");
+ return cxstring::createRef("CXXTypeidExpr");
case CXCursor_CXXBoolLiteralExpr:
- return createCXString("CXXBoolLiteralExpr");
+ return cxstring::createRef("CXXBoolLiteralExpr");
case CXCursor_CXXNullPtrLiteralExpr:
- return createCXString("CXXNullPtrLiteralExpr");
+ return cxstring::createRef("CXXNullPtrLiteralExpr");
case CXCursor_CXXThisExpr:
- return createCXString("CXXThisExpr");
+ return cxstring::createRef("CXXThisExpr");
case CXCursor_CXXThrowExpr:
- return createCXString("CXXThrowExpr");
+ return cxstring::createRef("CXXThrowExpr");
case CXCursor_CXXNewExpr:
- return createCXString("CXXNewExpr");
+ return cxstring::createRef("CXXNewExpr");
case CXCursor_CXXDeleteExpr:
- return createCXString("CXXDeleteExpr");
+ return cxstring::createRef("CXXDeleteExpr");
case CXCursor_UnaryExpr:
- return createCXString("UnaryExpr");
+ return cxstring::createRef("UnaryExpr");
case CXCursor_ObjCStringLiteral:
- return createCXString("ObjCStringLiteral");
+ return cxstring::createRef("ObjCStringLiteral");
case CXCursor_ObjCBoolLiteralExpr:
- return createCXString("ObjCBoolLiteralExpr");
+ return cxstring::createRef("ObjCBoolLiteralExpr");
case CXCursor_ObjCEncodeExpr:
- return createCXString("ObjCEncodeExpr");
+ return cxstring::createRef("ObjCEncodeExpr");
case CXCursor_ObjCSelectorExpr:
- return createCXString("ObjCSelectorExpr");
+ return cxstring::createRef("ObjCSelectorExpr");
case CXCursor_ObjCProtocolExpr:
- return createCXString("ObjCProtocolExpr");
+ return cxstring::createRef("ObjCProtocolExpr");
case CXCursor_ObjCBridgedCastExpr:
- return createCXString("ObjCBridgedCastExpr");
+ return cxstring::createRef("ObjCBridgedCastExpr");
case CXCursor_BlockExpr:
- return createCXString("BlockExpr");
+ return cxstring::createRef("BlockExpr");
case CXCursor_PackExpansionExpr:
- return createCXString("PackExpansionExpr");
+ return cxstring::createRef("PackExpansionExpr");
case CXCursor_SizeOfPackExpr:
- return createCXString("SizeOfPackExpr");
+ return cxstring::createRef("SizeOfPackExpr");
case CXCursor_LambdaExpr:
- return createCXString("LambdaExpr");
+ return cxstring::createRef("LambdaExpr");
case CXCursor_UnexposedExpr:
- return createCXString("UnexposedExpr");
+ return cxstring::createRef("UnexposedExpr");
case CXCursor_DeclRefExpr:
- return createCXString("DeclRefExpr");
+ return cxstring::createRef("DeclRefExpr");
case CXCursor_MemberRefExpr:
- return createCXString("MemberRefExpr");
+ return cxstring::createRef("MemberRefExpr");
case CXCursor_CallExpr:
- return createCXString("CallExpr");
+ return cxstring::createRef("CallExpr");
case CXCursor_ObjCMessageExpr:
- return createCXString("ObjCMessageExpr");
+ return cxstring::createRef("ObjCMessageExpr");
case CXCursor_UnexposedStmt:
- return createCXString("UnexposedStmt");
+ return cxstring::createRef("UnexposedStmt");
case CXCursor_DeclStmt:
- return createCXString("DeclStmt");
+ return cxstring::createRef("DeclStmt");
case CXCursor_LabelStmt:
- return createCXString("LabelStmt");
+ return cxstring::createRef("LabelStmt");
case CXCursor_CompoundStmt:
- return createCXString("CompoundStmt");
+ return cxstring::createRef("CompoundStmt");
case CXCursor_CaseStmt:
- return createCXString("CaseStmt");
+ return cxstring::createRef("CaseStmt");
case CXCursor_DefaultStmt:
- return createCXString("DefaultStmt");
+ return cxstring::createRef("DefaultStmt");
case CXCursor_IfStmt:
- return createCXString("IfStmt");
+ return cxstring::createRef("IfStmt");
case CXCursor_SwitchStmt:
- return createCXString("SwitchStmt");
+ return cxstring::createRef("SwitchStmt");
case CXCursor_WhileStmt:
- return createCXString("WhileStmt");
+ return cxstring::createRef("WhileStmt");
case CXCursor_DoStmt:
- return createCXString("DoStmt");
+ return cxstring::createRef("DoStmt");
case CXCursor_ForStmt:
- return createCXString("ForStmt");
+ return cxstring::createRef("ForStmt");
case CXCursor_GotoStmt:
- return createCXString("GotoStmt");
+ return cxstring::createRef("GotoStmt");
case CXCursor_IndirectGotoStmt:
- return createCXString("IndirectGotoStmt");
+ return cxstring::createRef("IndirectGotoStmt");
case CXCursor_ContinueStmt:
- return createCXString("ContinueStmt");
+ return cxstring::createRef("ContinueStmt");
case CXCursor_BreakStmt:
- return createCXString("BreakStmt");
+ return cxstring::createRef("BreakStmt");
case CXCursor_ReturnStmt:
- return createCXString("ReturnStmt");
+ return cxstring::createRef("ReturnStmt");
case CXCursor_GCCAsmStmt:
- return createCXString("GCCAsmStmt");
+ return cxstring::createRef("GCCAsmStmt");
case CXCursor_MSAsmStmt:
- return createCXString("MSAsmStmt");
+ return cxstring::createRef("MSAsmStmt");
case CXCursor_ObjCAtTryStmt:
- return createCXString("ObjCAtTryStmt");
+ return cxstring::createRef("ObjCAtTryStmt");
case CXCursor_ObjCAtCatchStmt:
- return createCXString("ObjCAtCatchStmt");
+ return cxstring::createRef("ObjCAtCatchStmt");
case CXCursor_ObjCAtFinallyStmt:
- return createCXString("ObjCAtFinallyStmt");
+ return cxstring::createRef("ObjCAtFinallyStmt");
case CXCursor_ObjCAtThrowStmt:
- return createCXString("ObjCAtThrowStmt");
+ return cxstring::createRef("ObjCAtThrowStmt");
case CXCursor_ObjCAtSynchronizedStmt:
- return createCXString("ObjCAtSynchronizedStmt");
+ return cxstring::createRef("ObjCAtSynchronizedStmt");
case CXCursor_ObjCAutoreleasePoolStmt:
- return createCXString("ObjCAutoreleasePoolStmt");
+ return cxstring::createRef("ObjCAutoreleasePoolStmt");
case CXCursor_ObjCForCollectionStmt:
- return createCXString("ObjCForCollectionStmt");
+ return cxstring::createRef("ObjCForCollectionStmt");
case CXCursor_CXXCatchStmt:
- return createCXString("CXXCatchStmt");
+ return cxstring::createRef("CXXCatchStmt");
case CXCursor_CXXTryStmt:
- return createCXString("CXXTryStmt");
+ return cxstring::createRef("CXXTryStmt");
case CXCursor_CXXForRangeStmt:
- return createCXString("CXXForRangeStmt");
+ return cxstring::createRef("CXXForRangeStmt");
case CXCursor_SEHTryStmt:
- return createCXString("SEHTryStmt");
+ return cxstring::createRef("SEHTryStmt");
case CXCursor_SEHExceptStmt:
- return createCXString("SEHExceptStmt");
+ return cxstring::createRef("SEHExceptStmt");
case CXCursor_SEHFinallyStmt:
- return createCXString("SEHFinallyStmt");
+ return cxstring::createRef("SEHFinallyStmt");
case CXCursor_NullStmt:
- return createCXString("NullStmt");
+ return cxstring::createRef("NullStmt");
case CXCursor_InvalidFile:
- return createCXString("InvalidFile");
+ return cxstring::createRef("InvalidFile");
case CXCursor_InvalidCode:
- return createCXString("InvalidCode");
+ return cxstring::createRef("InvalidCode");
case CXCursor_NoDeclFound:
- return createCXString("NoDeclFound");
+ return cxstring::createRef("NoDeclFound");
case CXCursor_NotImplemented:
- return createCXString("NotImplemented");
+ return cxstring::createRef("NotImplemented");
case CXCursor_TranslationUnit:
- return createCXString("TranslationUnit");
+ return cxstring::createRef("TranslationUnit");
case CXCursor_UnexposedAttr:
- return createCXString("UnexposedAttr");
+ return cxstring::createRef("UnexposedAttr");
case CXCursor_IBActionAttr:
- return createCXString("attribute(ibaction)");
+ return cxstring::createRef("attribute(ibaction)");
case CXCursor_IBOutletAttr:
- return createCXString("attribute(iboutlet)");
+ return cxstring::createRef("attribute(iboutlet)");
case CXCursor_IBOutletCollectionAttr:
- return createCXString("attribute(iboutletcollection)");
+ return cxstring::createRef("attribute(iboutletcollection)");
case CXCursor_CXXFinalAttr:
- return createCXString("attribute(final)");
+ return cxstring::createRef("attribute(final)");
case CXCursor_CXXOverrideAttr:
- return createCXString("attribute(override)");
+ return cxstring::createRef("attribute(override)");
case CXCursor_AnnotateAttr:
- return createCXString("attribute(annotate)");
+ return cxstring::createRef("attribute(annotate)");
case CXCursor_AsmLabelAttr:
- return createCXString("asm label");
+ return cxstring::createRef("asm label");
case CXCursor_PreprocessingDirective:
- return createCXString("preprocessing directive");
+ return cxstring::createRef("preprocessing directive");
case CXCursor_MacroDefinition:
- return createCXString("macro definition");
+ return cxstring::createRef("macro definition");
case CXCursor_MacroExpansion:
- return createCXString("macro expansion");
+ return cxstring::createRef("macro expansion");
case CXCursor_InclusionDirective:
- return createCXString("inclusion directive");
+ return cxstring::createRef("inclusion directive");
case CXCursor_Namespace:
- return createCXString("Namespace");
+ return cxstring::createRef("Namespace");
case CXCursor_LinkageSpec:
- return createCXString("LinkageSpec");
+ return cxstring::createRef("LinkageSpec");
case CXCursor_CXXBaseSpecifier:
- return createCXString("C++ base class specifier");
+ return cxstring::createRef("C++ base class specifier");
case CXCursor_Constructor:
- return createCXString("CXXConstructor");
+ return cxstring::createRef("CXXConstructor");
case CXCursor_Destructor:
- return createCXString("CXXDestructor");
+ return cxstring::createRef("CXXDestructor");
case CXCursor_ConversionFunction:
- return createCXString("CXXConversion");
+ return cxstring::createRef("CXXConversion");
case CXCursor_TemplateTypeParameter:
- return createCXString("TemplateTypeParameter");
+ return cxstring::createRef("TemplateTypeParameter");
case CXCursor_NonTypeTemplateParameter:
- return createCXString("NonTypeTemplateParameter");
+ return cxstring::createRef("NonTypeTemplateParameter");
case CXCursor_TemplateTemplateParameter:
- return createCXString("TemplateTemplateParameter");
+ return cxstring::createRef("TemplateTemplateParameter");
case CXCursor_FunctionTemplate:
- return createCXString("FunctionTemplate");
+ return cxstring::createRef("FunctionTemplate");
case CXCursor_ClassTemplate:
- return createCXString("ClassTemplate");
+ return cxstring::createRef("ClassTemplate");
case CXCursor_ClassTemplatePartialSpecialization:
- return createCXString("ClassTemplatePartialSpecialization");
+ return cxstring::createRef("ClassTemplatePartialSpecialization");
case CXCursor_NamespaceAlias:
- return createCXString("NamespaceAlias");
+ return cxstring::createRef("NamespaceAlias");
case CXCursor_UsingDirective:
- return createCXString("UsingDirective");
+ return cxstring::createRef("UsingDirective");
case CXCursor_UsingDeclaration:
- return createCXString("UsingDeclaration");
+ return cxstring::createRef("UsingDeclaration");
case CXCursor_TypeAliasDecl:
- return createCXString("TypeAliasDecl");
+ return cxstring::createRef("TypeAliasDecl");
case CXCursor_ObjCSynthesizeDecl:
- return createCXString("ObjCSynthesizeDecl");
+ return cxstring::createRef("ObjCSynthesizeDecl");
case CXCursor_ObjCDynamicDecl:
- return createCXString("ObjCDynamicDecl");
+ return cxstring::createRef("ObjCDynamicDecl");
case CXCursor_CXXAccessSpecifier:
- return createCXString("CXXAccessSpecifier");
+ return cxstring::createRef("CXXAccessSpecifier");
case CXCursor_ModuleImportDecl:
- return createCXString("ModuleImport");
+ return cxstring::createRef("ModuleImport");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -3697,12 +3772,12 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
if (clang_isDeclaration(cursor.kind)) {
// Avoid having the implicit methods override the property decls.
- if (ObjCMethodDecl *MD
+ if (const ObjCMethodDecl *MD
= dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
if (MD->isImplicit())
return CXChildVisit_Break;
- } else if (ObjCInterfaceDecl *ID
+ } else if (const ObjCInterfaceDecl *ID
= dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
// Check that when we have multiple @class references in the same line,
// that later ones do not override the previous ones.
@@ -3712,7 +3787,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
// 'Foo' even though the cursor location was at 'Foo'.
if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
BestCursor->kind == CXCursor_ObjCClassRef)
- if (ObjCInterfaceDecl *PrevID
+ if (const ObjCInterfaceDecl *PrevID
= dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
if (PrevID != ID &&
!PrevID->isThisDeclarationADefinition() &&
@@ -3720,7 +3795,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
return CXChildVisit_Break;
}
- } else if (DeclaratorDecl *DD
+ } else if (const DeclaratorDecl *DD
= dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
SourceLocation StartLoc = DD->getSourceRange().getBegin();
// Check that when we have multiple declarators in the same line,
@@ -3733,7 +3808,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
return CXChildVisit_Break;
Data->VisitedDeclaratorDeclStartLoc = StartLoc;
- } else if (ObjCPropertyImplDecl *PropImp
+ } else if (const ObjCPropertyImplDecl *PropImp
= dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
(void)PropImp;
// Check that when we have multiple @synthesize in the same line,
@@ -3750,7 +3825,7 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
if (clang_isExpression(cursor.kind) &&
clang_isDeclaration(BestCursor->kind)) {
- if (Decl *D = getCursorDecl(*BestCursor)) {
+ if (const Decl *D = getCursorDecl(*BestCursor)) {
// Avoid having the cursor of an expression replace the declaration cursor
// when the expression source range overlaps the declaration range.
// This can happen for C++ constructor expressions whose range generally
@@ -3782,14 +3857,13 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
if (!TU)
return clang_getNullCursor();
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
CXCursor Result = cxcursor::getCursor(TU, SLoc);
- bool Logging = getenv("LIBCLANG_LOGGING");
- if (Logging) {
+ LOG_FUNC_SECTION {
CXFile SearchFile;
unsigned SearchLine, SearchColumn;
CXFile ResultFile;
@@ -3798,18 +3872,19 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
- clang_getExpansionLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
- clang_getExpansionLocation(ResultLoc, &ResultFile, &ResultLine,
+ clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
+ clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
&ResultColumn, 0);
SearchFileName = clang_getFileName(SearchFile);
ResultFileName = clang_getFileName(ResultFile);
KindSpelling = clang_getCursorKindSpelling(Result.kind);
USR = clang_getCursorUSR(Result);
- fprintf(stderr, "clang_getCursor(%s:%d:%d) = %s(%s:%d:%d):%s%s\n",
- clang_getCString(SearchFileName), SearchLine, SearchColumn,
- clang_getCString(KindSpelling),
- clang_getCString(ResultFileName), ResultLine, ResultColumn,
- clang_getCString(USR), IsDef);
+ *Log << llvm::format("(%s:%d:%d) = %s",
+ clang_getCString(SearchFileName), SearchLine, SearchColumn,
+ clang_getCString(KindSpelling))
+ << llvm::format("(%s:%d:%d):%s%s",
+ clang_getCString(ResultFileName), ResultLine, ResultColumn,
+ clang_getCString(USR), IsDef);
clang_disposeString(SearchFileName);
clang_disposeString(ResultFileName);
clang_disposeString(KindSpelling);
@@ -3822,13 +3897,13 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
= clang_getCursorKindSpelling(Definition.kind);
CXFile DefinitionFile;
unsigned DefinitionLine, DefinitionColumn;
- clang_getExpansionLocation(DefinitionLoc, &DefinitionFile,
+ clang_getFileLocation(DefinitionLoc, &DefinitionFile,
&DefinitionLine, &DefinitionColumn, 0);
CXString DefinitionFileName = clang_getFileName(DefinitionFile);
- fprintf(stderr, " -> %s(%s:%d:%d)\n",
- clang_getCString(DefinitionKindSpelling),
- clang_getCString(DefinitionFileName),
- DefinitionLine, DefinitionColumn);
+ *Log << llvm::format(" -> %s(%s:%d:%d)",
+ clang_getCString(DefinitionKindSpelling),
+ clang_getCString(DefinitionFileName),
+ DefinitionLine, DefinitionColumn);
clang_disposeString(DefinitionFileName);
clang_disposeString(DefinitionKindSpelling);
}
@@ -3842,6 +3917,18 @@ CXCursor clang_getNullCursor(void) {
}
unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
+ // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
+ // can't set consistently. For example, when visiting a DeclStmt we will set
+ // it but we don't set it on the result of clang_getCursorDefinition for
+ // a reference of the same declaration.
+ // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
+ // when visiting a DeclStmt currently, the AST should be enhanced to be able
+ // to provide that kind of info.
+ if (clang_isDeclaration(X.kind))
+ X.data[1] = 0;
+ if (clang_isDeclaration(Y.kind))
+ Y.data[1] = 0;
+
return X == Y;
}
@@ -3850,7 +3937,7 @@ unsigned clang_hashCursor(CXCursor C) {
if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
Index = 1;
- return llvm::DenseMapInfo<std::pair<unsigned, void*> >::getHashValue(
+ return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
std::make_pair(C.kind, C.data[Index]));
}
@@ -3907,50 +3994,51 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
if (clang_isReference(C.kind)) {
switch (C.kind) {
case CXCursor_ObjCSuperClassRef: {
- std::pair<ObjCInterfaceDecl *, SourceLocation> P
+ std::pair<const ObjCInterfaceDecl *, SourceLocation> P
= getCursorObjCSuperClassRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_ObjCProtocolRef: {
- std::pair<ObjCProtocolDecl *, SourceLocation> P
+ std::pair<const ObjCProtocolDecl *, SourceLocation> P
= getCursorObjCProtocolRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_ObjCClassRef: {
- std::pair<ObjCInterfaceDecl *, SourceLocation> P
+ std::pair<const ObjCInterfaceDecl *, SourceLocation> P
= getCursorObjCClassRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_TypeRef: {
- std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
+ std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_TemplateRef: {
- std::pair<TemplateDecl *, SourceLocation> P = getCursorTemplateRef(C);
+ std::pair<const TemplateDecl *, SourceLocation> P =
+ getCursorTemplateRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_NamespaceRef: {
- std::pair<NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
+ std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_MemberRef: {
- std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
+ std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_VariableRef: {
- std::pair<VarDecl *, SourceLocation> P = getCursorVariableRef(C);
+ std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
case CXCursor_CXXBaseSpecifier: {
- CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
+ const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
if (!BaseSpec)
return clang_getNullLocation();
@@ -3963,7 +4051,7 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
}
case CXCursor_LabelRef: {
- std::pair<LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
+ std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
return cxloc::translateSourceLocation(getCursorContext(C), P.second);
}
@@ -3992,7 +4080,7 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
if (C.kind == CXCursor_MacroExpansion) {
SourceLocation L
- = cxcursor::getCursorMacroExpansion(C)->getSourceRange().getBegin();
+ = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
return cxloc::translateSourceLocation(getCursorContext(C), L);
}
@@ -4010,7 +4098,7 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getNullLocation();
- Decl *D = getCursorDecl(C);
+ const Decl *D = getCursorDecl(C);
if (!D)
return clang_getNullLocation();
@@ -4020,13 +4108,13 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
// ranges when accounting for the type-specifier. We use context
// stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
// and if so, whether it is the first decl.
- if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (!cxcursor::isFirstInDeclGroup(C))
Loc = VD->getLocation();
}
// For ObjC methods, give the start location of the method name.
- if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Loc = MD->getSelectorStartLoc();
return cxloc::translateSourceLocation(getCursorContext(C), Loc);
@@ -4042,7 +4130,7 @@ CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
if (SLoc.isInvalid())
return clang_getNullCursor();
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
// Translate the given source location to make it point at the beginning of
// the token under the cursor.
@@ -4118,7 +4206,7 @@ static SourceRange getRawCursorExtent(CXCursor C) {
if (C.kind == CXCursor_MacroExpansion) {
ASTUnit *TU = getCursorASTUnit(C);
- SourceRange Range = cxcursor::getCursorMacroExpansion(C)->getSourceRange();
+ SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
return TU->mapRangeFromPreamble(Range);
}
@@ -4143,7 +4231,7 @@ static SourceRange getRawCursorExtent(CXCursor C) {
}
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (!D)
return SourceRange();
@@ -4153,7 +4241,7 @@ static SourceRange getRawCursorExtent(CXCursor C) {
// ranges when accounting for the type-specifier. We use context
// stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
// and if so, whether it is the first decl.
- if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (!cxcursor::isFirstInDeclGroup(C))
R.setBegin(VD->getLocation());
}
@@ -4166,7 +4254,7 @@ static SourceRange getRawCursorExtent(CXCursor C) {
/// the decl-specifier-seq for declarations.
static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (!D)
return SourceRange();
@@ -4178,7 +4266,7 @@ static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
StartLoc = TI->getTypeLoc().getLocStart();
- } else if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
+ } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
StartLoc = TI->getTypeLoc().getLocStart();
}
@@ -4192,7 +4280,7 @@ static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
// ranges when accounting for the type-specifier. We use context
// stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
// and if so, whether it is the first decl.
- if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (!cxcursor::isFirstInDeclGroup(C))
R.setBegin(VD->getLocation());
}
@@ -4219,12 +4307,13 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
CXTranslationUnit tu = getCursorTU(C);
if (clang_isDeclaration(C.kind)) {
- Decl *D = getCursorDecl(C);
+ const Decl *D = getCursorDecl(C);
if (!D)
return clang_getNullCursor();
- if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
+ if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
- if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
+ if (const ObjCPropertyImplDecl *PropImpl =
+ dyn_cast<ObjCPropertyImplDecl>(D))
if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
return MakeCXCursor(Property, tu);
@@ -4232,8 +4321,8 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
}
if (clang_isExpression(C.kind)) {
- Expr *E = getCursorExpr(C);
- Decl *D = getDeclFromExpr(E);
+ const Expr *E = getCursorExpr(C);
+ const Decl *D = getDeclFromExpr(E);
if (D) {
CXCursor declCursor = MakeCXCursor(D, tu);
declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
@@ -4241,15 +4330,15 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
return declCursor;
}
- if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
+ if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
return MakeCursorOverloadedDeclRef(Ovl, tu);
return clang_getNullCursor();
}
if (clang_isStatement(C.kind)) {
- Stmt *S = getCursorStmt(C);
- if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
+ const Stmt *S = getCursorStmt(C);
+ if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
if (LabelDecl *label = Goto->getLabel())
if (LabelStmt *labelS = label->getStmt())
return MakeCXCursor(labelS, getCursorDecl(C), tu);
@@ -4258,7 +4347,7 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
}
if (C.kind == CXCursor_MacroExpansion) {
- if (MacroDefinition *Def = getCursorMacroExpansion(C)->getDefinition())
+ if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
return MakeMacroDefinitionCursor(Def, tu);
}
@@ -4270,16 +4359,16 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
case CXCursor_ObjCProtocolRef: {
- ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
- if (ObjCProtocolDecl *Def = Prot->getDefinition())
+ const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
+ if (const ObjCProtocolDecl *Def = Prot->getDefinition())
return MakeCXCursor(Def, tu);
return MakeCXCursor(Prot, tu);
}
case CXCursor_ObjCClassRef: {
- ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
- if (ObjCInterfaceDecl *Def = Class->getDefinition())
+ const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
+ if (const ObjCInterfaceDecl *Def = Class->getDefinition())
return MakeCXCursor(Def, tu);
return MakeCXCursor(Class, tu);
@@ -4298,7 +4387,7 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
return MakeCXCursor(getCursorMemberRef(C).first, tu );
case CXCursor_CXXBaseSpecifier: {
- CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
+ const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
tu ));
}
@@ -4306,9 +4395,9 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
case CXCursor_LabelRef:
// FIXME: We end up faking the "parent" declaration here because we
// don't want to make CXCursor larger.
- return MakeCXCursor(getCursorLabelRef(C).first,
- static_cast<ASTUnit*>(tu->TUData)->getASTContext()
- .getTranslationUnitDecl(),
+ return MakeCXCursor(getCursorLabelRef(C).first,
+ cxtu::getASTUnit(tu)->getASTContext()
+ .getTranslationUnitDecl(),
tu);
case CXCursor_OverloadedDeclRef:
@@ -4341,7 +4430,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getNullCursor();
- Decl *D = getCursorDecl(C);
+ const Decl *D = getCursorDecl(C);
if (!D)
return clang_getNullCursor();
@@ -4373,10 +4462,12 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
case Decl::Label: // FIXME: Is this right??
case Decl::ClassScopeFunctionSpecialization:
case Decl::Import:
+ case Decl::OMPThreadPrivate:
return C;
// Declaration kinds that don't make any sense here, but are
// nonetheless harmless.
+ case Decl::Empty:
case Decl::TranslationUnit:
break;
@@ -4408,13 +4499,13 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
case Decl::CXXConversion: {
const FunctionDecl *Def = 0;
if (cast<FunctionDecl>(D)->getBody(Def))
- return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
+ return MakeCXCursor(Def, TU);
return clang_getNullCursor();
}
case Decl::Var: {
// Ask the variable if it has a definition.
- if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
+ if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
return MakeCXCursor(Def, TU);
return clang_getNullCursor();
}
@@ -4444,14 +4535,14 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
TU));
case Decl::ObjCMethod: {
- ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
+ const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
if (Method->isThisDeclarationADefinition())
return C;
// Dig out the method definition in the associated
// @implementation, if we have it.
// FIXME: The ASTs should make finding the definition easier.
- if (ObjCInterfaceDecl *Class
+ if (const ObjCInterfaceDecl *Class
= dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
@@ -4469,7 +4560,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
return clang_getNullCursor();
case Decl::ObjCProtocol:
- if (ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
+ if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
return MakeCXCursor(Def, TU);
return clang_getNullCursor();
@@ -4479,9 +4570,9 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
// reference to an Objective-C class, produce the @interface as
// the definition; when we were provided with the interface,
// produce the @implementation as the definition.
- ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
+ const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
if (WasReference) {
- if (ObjCInterfaceDecl *Def = IFace->getDefinition())
+ if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
return MakeCXCursor(Def, TU);
} else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
return MakeCXCursor(Impl, TU);
@@ -4494,9 +4585,9 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
return clang_getNullCursor();
case Decl::ObjCCompatibleAlias:
- if (ObjCInterfaceDecl *Class
+ if (const ObjCInterfaceDecl *Class
= cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
- if (ObjCInterfaceDecl *Def = Class->getDefinition())
+ if (const ObjCInterfaceDecl *Def = Class->getDefinition())
return MakeCXCursor(Def, TU);
return clang_getNullCursor();
@@ -4526,13 +4617,13 @@ CXCursor clang_getCanonicalCursor(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return C;
- if (Decl *D = getCursorDecl(C)) {
- if (ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
+ if (const Decl *D = getCursorDecl(C)) {
+ if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
return MakeCXCursor(CatD, getCursorTU(C));
- if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
- if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
+ if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
+ if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
return MakeCXCursor(IFD, getCursorTU(C));
return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
@@ -4550,15 +4641,15 @@ unsigned clang_getNumOverloadedDecls(CXCursor C) {
return 0;
OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
- if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
+ if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
return E->getNumDecls();
if (OverloadedTemplateStorage *S
= Storage.dyn_cast<OverloadedTemplateStorage*>())
return S->size();
- Decl *D = Storage.get<Decl*>();
- if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
+ const Decl *D = Storage.get<const Decl *>();
+ if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
return Using->shadow_size();
return 0;
@@ -4573,15 +4664,15 @@ CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
CXTranslationUnit TU = getCursorTU(cursor);
OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
- if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
+ if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
return MakeCXCursor(E->decls_begin()[index], TU);
if (OverloadedTemplateStorage *S
= Storage.dyn_cast<OverloadedTemplateStorage*>())
return MakeCXCursor(S->begin()[index], TU);
- Decl *D = Storage.get<Decl*>();
- if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
+ const Decl *D = Storage.get<const Decl *>();
+ if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
// FIXME: This is, unfortunately, linear time.
UsingDecl::shadow_iterator Pos = Using->shadow_begin();
std::advance(Pos, index);
@@ -4599,8 +4690,7 @@ void clang_getDefinitionSpellingAndExtent(CXCursor C,
unsigned *endLine,
unsigned *endColumn) {
assert(getCursorDecl(C) && "CXCursor has null decl");
- NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C));
- FunctionDecl *FD = dyn_cast<FunctionDecl>(ND);
+ const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
SourceManager &SM = FD->getASTContext().getSourceManager();
@@ -4619,26 +4709,26 @@ CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
switch (C.kind) {
case CXCursor_MemberRefExpr:
- if (MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
+ if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
E->getQualifierLoc().getSourceRange());
break;
case CXCursor_DeclRefExpr:
- if (DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
+ if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
E->getQualifierLoc().getSourceRange(),
E->getOptionalExplicitTemplateArgs());
break;
case CXCursor_CallExpr:
- if (CXXOperatorCallExpr *OCE =
+ if (const CXXOperatorCallExpr *OCE =
dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
- Expr *Callee = OCE->getCallee();
- if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
+ const Expr *Callee = OCE->getCallee();
+ if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Callee = ICE->getSubExpr();
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
DRE->getQualifierLoc().getSourceRange());
}
@@ -4694,13 +4784,13 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
case CXToken_Identifier:
case CXToken_Keyword:
// We know we have an IdentifierInfo*, so use that.
- return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data)
+ return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
->getNameStart());
case CXToken_Literal: {
// We have stashed the starting pointer in the ptr_data field. Use it.
const char *Text = static_cast<const char *>(CXTok.ptr_data);
- return createCXString(StringRef(Text, CXTok.int_data[2]));
+ return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
}
case CXToken_Punctuation:
@@ -4710,9 +4800,9 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
// We have to find the starting buffer pointer the hard way, by
// deconstructing the source location.
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
- return createCXString("");
+ return cxstring::createEmpty();
SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
std::pair<FileID, unsigned> LocInfo
@@ -4721,13 +4811,13 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
StringRef Buffer
= CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
if (Invalid)
- return createCXString("");
+ return cxstring::createEmpty();
- return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
+ return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
}
CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
return clang_getNullLocation();
@@ -4736,7 +4826,7 @@ CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
}
CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
return clang_getNullRange();
@@ -4748,9 +4838,9 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
SmallVectorImpl<CXToken> &CXTokens) {
SourceManager &SourceMgr = CXXUnit->getSourceManager();
std::pair<FileID, unsigned> BeginLocInfo
- = SourceMgr.getDecomposedLoc(Range.getBegin());
+ = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
std::pair<FileID, unsigned> EndLocInfo
- = SourceMgr.getDecomposedLoc(Range.getEnd());
+ = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
// Cannot tokenize across files.
if (BeginLocInfo.first != EndLocInfo.first)
@@ -4789,7 +4879,7 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
// - Kind-specific fields
if (Tok.isLiteral()) {
CXTok.int_data[0] = CXToken_Literal;
- CXTok.ptr_data = (void *)Tok.getLiteralData();
+ CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
} else if (Tok.is(tok::raw_identifier)) {
// Lookup the identifier to determine whether we have a keyword.
IdentifierInfo *II
@@ -4818,12 +4908,19 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
CXToken **Tokens, unsigned *NumTokens) {
+ LOG_FUNC_SECTION {
+ *Log << TU << ' ' << Range;
+ }
+
if (Tokens)
*Tokens = 0;
if (NumTokens)
*NumTokens = 0;
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ if (!TU)
+ return;
+
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit || !Tokens || !NumTokens)
return;
@@ -4855,7 +4952,6 @@ void clang_disposeTokens(CXTranslationUnit TU,
// Token annotation APIs.
//===----------------------------------------------------------------------===//
-typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData;
static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
CXCursor parent,
CXClientData client_data);
@@ -4864,7 +4960,6 @@ static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
namespace {
class AnnotateTokensWorker {
- AnnotateTokensData &Annotated;
CXToken *Tokens;
CXCursor *Cursors;
unsigned NumTokens;
@@ -4877,9 +4972,10 @@ class AnnotateTokensWorker {
struct PostChildrenInfo {
CXCursor Cursor;
SourceRange CursorRange;
+ unsigned BeforeReachingCursorIdx;
unsigned BeforeChildrenTokenIdx;
};
- llvm::SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
+ SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
bool MoreTokens() const { return TokIdx < NumTokens; }
unsigned NextToken() const { return TokIdx; }
@@ -4895,23 +4991,22 @@ class AnnotateTokensWorker {
}
void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
- void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
+ bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
SourceRange);
public:
- AnnotateTokensWorker(AnnotateTokensData &annotated,
- CXToken *tokens, CXCursor *cursors, unsigned numTokens,
- CXTranslationUnit tu, SourceRange RegionOfInterest)
- : Annotated(annotated), Tokens(tokens), Cursors(cursors),
+ AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
+ CXTranslationUnit TU, SourceRange RegionOfInterest)
+ : Tokens(tokens), Cursors(cursors),
NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
- AnnotateVis(tu,
+ AnnotateVis(TU,
AnnotateTokensVisitor, this,
/*VisitPreprocessorLast=*/true,
/*VisitIncludedEntities=*/false,
RegionOfInterest,
/*VisitDeclsOnly=*/false,
AnnotateTokensPostChildrenVisitor),
- SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
+ SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
HasContextSensitiveKeywords(false) { }
void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
@@ -4935,27 +5030,13 @@ void AnnotateTokensWorker::AnnotateTokens() {
// Walk the AST within the region of interest, annotating tokens
// along the way.
AnnotateVis.visitFileRegion();
+}
- for (unsigned I = 0 ; I < TokIdx ; ++I) {
- AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
- if (Pos != Annotated.end() &&
- (clang_isInvalid(Cursors[I].kind) ||
- Pos->second.kind != CXCursor_PreprocessingDirective))
- Cursors[I] = Pos->second;
- }
-
- // Finish up annotating any tokens left.
- if (!MoreTokens())
+static inline void updateCursorAnnotation(CXCursor &Cursor,
+ const CXCursor &updateC) {
+ if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
return;
-
- const CXCursor &C = clang_getNullCursor();
- for (unsigned I = TokIdx ; I < NumTokens ; ++I) {
- if (I < PreprocessingTokIdx && clang_isPreprocessing(Cursors[I].kind))
- continue;
-
- AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]);
- Cursors[I] = (Pos == Annotated.end()) ? C : Pos->second;
- }
+ Cursor = updateC;
}
/// \brief It annotates and advances tokens with a cursor until the comparison
@@ -4970,11 +5051,12 @@ void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
while (MoreTokens()) {
const unsigned I = NextToken();
if (isFunctionMacroToken(I))
- return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range);
+ if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
+ return;
SourceLocation TokLoc = GetTokenLoc(I);
if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
- Cursors[I] = updateC;
+ updateCursorAnnotation(Cursors[I], updateC);
AdvanceToken();
continue;
}
@@ -4983,7 +5065,8 @@ void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
}
/// \brief Special annotation handling for macro argument tokens.
-void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
+/// \returns true if it advanced beyond all macro tokens, false otherwise.
+bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
CXCursor updateC,
RangeComparisonResult compResult,
SourceRange range) {
@@ -5013,13 +5096,15 @@ void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
atLeastOneCompFail = true;
}
- if (!atLeastOneCompFail)
- TokIdx = I; // All of the tokens were handled, advance beyond all of them.
+ if (atLeastOneCompFail)
+ return false;
+
+ TokIdx = I; // All of the tokens were handled, advance beyond all of them.
+ return true;
}
enum CXChildVisitResult
AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
- CXSourceLocation Loc = clang_getCursorLocation(cursor);
SourceRange cursorRange = getRawCursorExtent(cursor);
if (cursorRange.isInvalid())
return CXChildVisit_Recurse;
@@ -5027,20 +5112,20 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
if (!HasContextSensitiveKeywords) {
// Objective-C properties can have context-sensitive keywords.
if (cursor.kind == CXCursor_ObjCPropertyDecl) {
- if (ObjCPropertyDecl *Property
+ if (const ObjCPropertyDecl *Property
= dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
}
// Objective-C methods can have context-sensitive keywords.
else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
cursor.kind == CXCursor_ObjCClassMethodDecl) {
- if (ObjCMethodDecl *Method
+ if (const ObjCMethodDecl *Method
= dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
if (Method->getObjCDeclQualifier())
HasContextSensitiveKeywords = true;
else {
- for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
- PEnd = Method->param_end();
+ for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
+ PEnd = Method->param_end();
P != PEnd; ++P) {
if ((*P)->getObjCDeclQualifier()) {
HasContextSensitiveKeywords = true;
@@ -5052,7 +5137,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
}
// C++ methods can have context-sensitive keywords.
else if (cursor.kind == CXCursor_CXXMethod) {
- if (CXXMethodDecl *Method
+ if (const CXXMethodDecl *Method
= dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
HasContextSensitiveKeywords = true;
@@ -5063,20 +5148,13 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
cursor.kind == CXCursor_ClassDecl ||
cursor.kind == CXCursor_ClassTemplate ||
cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
- if (Decl *D = getCursorDecl(cursor))
+ if (const Decl *D = getCursorDecl(cursor))
if (D->hasAttr<FinalAttr>())
HasContextSensitiveKeywords = true;
}
}
if (clang_isPreprocessing(cursor.kind)) {
- // For macro expansions, just note where the beginning of the macro
- // expansion occurs.
- if (cursor.kind == CXCursor_MacroExpansion) {
- Annotated[Loc.int_data] = cursor;
- return CXChildVisit_Recurse;
- }
-
// Items in the preprocessing record are kept separate from items in
// declarations, so we keep a separate token index.
unsigned SavedTokIdx = TokIdx;
@@ -5108,7 +5186,17 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
case RangeAfter:
break;
case RangeOverlap:
- Cursors[I] = cursor;
+ // For macro expansions, just note where the beginning of the macro
+ // expansion occurs.
+ if (cursor.kind == CXCursor_MacroExpansion) {
+ if (TokLoc == cursorRange.getBegin())
+ Cursors[I] = cursor;
+ AdvanceToken();
+ break;
+ }
+ // We may have already annotated macro names inside macro definitions.
+ if (Cursors[I].kind != CXCursor_MacroExpansion)
+ Cursors[I] = cursor;
AdvanceToken();
continue;
}
@@ -5124,48 +5212,14 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
if (cursorRange.isInvalid())
return CXChildVisit_Continue;
-
- SourceLocation L = SourceLocation::getFromRawEncoding(Loc.int_data);
- // Adjust the annotated range based specific declarations.
+ unsigned BeforeReachingCursorIdx = NextToken();
const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
- if (clang_isDeclaration(cursorK)) {
- Decl *D = cxcursor::getCursorDecl(cursor);
-
- SourceLocation StartLoc;
- if (const DeclaratorDecl *DD = dyn_cast_or_null<DeclaratorDecl>(D)) {
- if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
- StartLoc = TI->getTypeLoc().getLocStart();
- } else if (TypedefDecl *Typedef = dyn_cast_or_null<TypedefDecl>(D)) {
- if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
- StartLoc = TI->getTypeLoc().getLocStart();
- }
-
- if (StartLoc.isValid() && L.isValid() &&
- SrcMgr.isBeforeInTranslationUnit(StartLoc, L))
- cursorRange.setBegin(StartLoc);
- }
-
- // If the location of the cursor occurs within a macro instantiation, record
- // the spelling location of the cursor in our annotation map. We can then
- // paper over the token labelings during a post-processing step to try and
- // get cursor mappings for tokens that are the *arguments* of a macro
- // instantiation.
- if (L.isMacroID()) {
- unsigned rawEncoding = SrcMgr.getSpellingLoc(L).getRawEncoding();
- // Only invalidate the old annotation if it isn't part of a preprocessing
- // directive. Here we assume that the default construction of CXCursor
- // results in CXCursor.kind being an initialized value (i.e., 0). If
- // this isn't the case, we can fix by doing lookup + insertion.
-
- CXCursor &oldC = Annotated[rawEncoding];
- if (!clang_isPreprocessing(oldC.kind))
- oldC = cursor;
- }
-
const enum CXCursorKind K = clang_getCursorKind(parent);
const CXCursor updateC =
- (clang_isInvalid(K) || K == CXCursor_TranslationUnit)
+ (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
+ // Attributes are annotated out-of-order, skip tokens until we reach it.
+ clang_isAttribute(cursor.kind))
? clang_getNullCursor() : parent;
annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
@@ -5176,13 +5230,13 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
// include the variable declaration, e.g.:
// MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
if (clang_isExpression(cursorK)) {
- Expr *E = getCursorExpr(cursor);
- if (Decl *D = getCursorParentDecl(cursor)) {
+ const Expr *E = getCursorExpr(cursor);
+ if (const Decl *D = getCursorParentDecl(cursor)) {
const unsigned I = NextToken();
if (E->getLocStart().isValid() && D->getLocation().isValid() &&
E->getLocStart() == D->getLocation() &&
E->getLocStart() == GetTokenLoc(I)) {
- Cursors[I] = updateC;
+ updateCursorAnnotation(Cursors[I], updateC);
AdvanceToken();
}
}
@@ -5197,6 +5251,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
PostChildrenInfo Info;
Info.Cursor = cursor;
Info.CursorRange = cursorRange;
+ Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Info.BeforeChildrenTokenIdx = NextToken();
PostChildrenInfos.push_back(Info);
@@ -5227,6 +5282,11 @@ bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
Cursors[I] = cursor;
}
+ // Attributes are annotated out-of-order, rewind TokIdx to when we first
+ // encountered the attribute cursor.
+ if (clang_isAttribute(cursor.kind))
+ TokIdx = Info.BeforeReachingCursorIdx;
+
PostChildrenInfos.pop_back();
return false;
}
@@ -5263,7 +5323,7 @@ public:
if (cursor.kind != CXCursor_MacroExpansion)
return CXChildVisit_Continue;
- SourceRange macroRange = getCursorMacroExpansion(cursor)->getSourceRange();
+ SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
if (macroRange.getBegin() == macroRange.getEnd())
return CXChildVisit_Continue; // it's not a function macro.
@@ -5321,16 +5381,34 @@ namespace {
};
}
+/// \brief Used by \c annotatePreprocessorTokens.
+/// \returns true if lexing was finished, false otherwise.
+static bool lexNext(Lexer &Lex, Token &Tok,
+ unsigned &NextIdx, unsigned NumTokens) {
+ if (NextIdx >= NumTokens)
+ return true;
+
+ ++NextIdx;
+ Lex.LexFromRawLexer(Tok);
+ if (Tok.is(tok::eof))
+ return true;
+
+ return false;
+}
+
static void annotatePreprocessorTokens(CXTranslationUnit TU,
SourceRange RegionOfInterest,
- AnnotateTokensData &Annotated) {
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ CXCursor *Cursors,
+ CXToken *Tokens,
+ unsigned NumTokens) {
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
+ Preprocessor &PP = CXXUnit->getPreprocessor();
SourceManager &SourceMgr = CXXUnit->getSourceManager();
std::pair<FileID, unsigned> BeginLocInfo
- = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
+ = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
std::pair<FileID, unsigned> EndLocInfo
- = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
+ = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
if (BeginLocInfo.first != EndLocInfo.first)
return;
@@ -5347,44 +5425,77 @@ static void annotatePreprocessorTokens(CXTranslationUnit TU,
Buffer.end());
Lex.SetCommentRetentionState(true);
+ unsigned NextIdx = 0;
// Lex tokens in raw mode until we hit the end of the range, to avoid
// entering #includes or expanding macros.
while (true) {
Token Tok;
- Lex.LexFromRawLexer(Tok);
+ if (lexNext(Lex, Tok, NextIdx, NumTokens))
+ break;
+ unsigned TokIdx = NextIdx-1;
+ assert(Tok.getLocation() ==
+ SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
reprocess:
if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
- // We have found a preprocessing directive. Gobble it up so that we
- // don't see it while preprocessing these tokens later, but keep track
- // of all of the token locations inside this preprocessing directive so
- // that we can annotate them appropriately.
+ // We have found a preprocessing directive. Annotate the tokens
+ // appropriately.
//
// FIXME: Some simple tests here could identify macro definitions and
// #undefs, to provide specific cursor kinds for those.
- SmallVector<SourceLocation, 32> Locations;
- do {
- Locations.push_back(Tok.getLocation());
- Lex.LexFromRawLexer(Tok);
- } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof));
-
- using namespace cxcursor;
- CXCursor Cursor
- = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(),
- Locations.back()),
- TU);
- for (unsigned I = 0, N = Locations.size(); I != N; ++I) {
- Annotated[Locations[I].getRawEncoding()] = Cursor;
+
+ SourceLocation BeginLoc = Tok.getLocation();
+ if (lexNext(Lex, Tok, NextIdx, NumTokens))
+ break;
+
+ MacroInfo *MI = 0;
+ if (Tok.is(tok::raw_identifier) &&
+ StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
+ if (lexNext(Lex, Tok, NextIdx, NumTokens))
+ break;
+
+ if (Tok.is(tok::raw_identifier)) {
+ StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
+ IdentifierInfo &II = PP.getIdentifierTable().get(Name);
+ SourceLocation MappedTokLoc =
+ CXXUnit->mapLocationToPreamble(Tok.getLocation());
+ MI = getMacroInfo(II, MappedTokLoc, TU);
+ }
}
+
+ bool finished = false;
+ do {
+ if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
+ finished = true;
+ break;
+ }
+ // If we are in a macro definition, check if the token was ever a
+ // macro name and annotate it if that's the case.
+ if (MI) {
+ SourceLocation SaveLoc = Tok.getLocation();
+ Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
+ MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
+ Tok.setLocation(SaveLoc);
+ if (MacroDef)
+ Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
+ Tok.getLocation(), TU);
+ }
+ } while (!Tok.isAtStartOfLine());
+
+ unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
+ assert(TokIdx <= LastIdx);
+ SourceLocation EndLoc =
+ SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
+ CXCursor Cursor =
+ MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
+
+ for (; TokIdx <= LastIdx; ++TokIdx)
+ updateCursorAnnotation(Cursors[TokIdx], Cursor);
- if (Tok.isAtStartOfLine())
- goto reprocess;
-
- continue;
+ if (finished)
+ break;
+ goto reprocess;
}
-
- if (Tok.is(tok::eof))
- break;
}
}
@@ -5396,7 +5507,7 @@ static void clang_annotateTokensImpl(void *UserData) {
const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
- CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
+ CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
setThreadBackgroundPriority();
@@ -5408,14 +5519,20 @@ static void clang_annotateTokensImpl(void *UserData) {
cxloc::translateSourceLocation(clang_getTokenLocation(TU,
Tokens[NumTokens-1])));
- // A mapping from the source locations found when re-lexing or traversing the
- // region of interest to the corresponding cursors.
- AnnotateTokensData Annotated;
-
// Relex the tokens within the source range to look for preprocessing
// directives.
- annotatePreprocessorTokens(TU, RegionOfInterest, Annotated);
-
+ annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
+
+ // If begin location points inside a macro argument, set it to the expansion
+ // location so we can have the full context when annotating semantically.
+ {
+ SourceManager &SM = CXXUnit->getSourceManager();
+ SourceLocation Loc =
+ SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
+ if (Loc.isMacroID())
+ RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
+ }
+
if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
// Search and mark tokens that are macro argument expansions.
MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
@@ -5430,8 +5547,7 @@ static void clang_annotateTokensImpl(void *UserData) {
// Annotate all of the source locations in the region of interest that map to
// a specific cursor.
- AnnotateTokensWorker W(Annotated, Tokens, Cursors, NumTokens,
- TU, RegionOfInterest);
+ AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
// FIXME: We use a ridiculous stack size here because the data-recursion
// algorithm uses a large stack frame than the non-data recursive version,
@@ -5449,7 +5565,7 @@ static void clang_annotateTokensImpl(void *UserData) {
if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
- if (ObjCPropertyDecl *Property
+ if (const ObjCPropertyDecl *Property
= dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
if (Property->getPropertyAttributesAsWritten() != 0 &&
llvm::StringSwitch<bool>(II->getName())
@@ -5500,16 +5616,24 @@ extern "C" {
void clang_annotateTokens(CXTranslationUnit TU,
CXToken *Tokens, unsigned NumTokens,
CXCursor *Cursors) {
-
- if (NumTokens == 0 || !Tokens || !Cursors)
+ if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
+ LOG_FUNC_SECTION { *Log << "<null input>"; }
return;
+ }
+
+ LOG_FUNC_SECTION {
+ *Log << TU << ' ';
+ CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
+ CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
+ *Log << clang_getRange(bloc, eloc);
+ }
// Any token we don't specifically annotate will have a NULL cursor.
CXCursor C = clang_getNullCursor();
for (unsigned I = 0; I != NumTokens; ++I)
Cursors[I] = C;
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
return;
@@ -5534,8 +5658,8 @@ CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
if (!clang_isDeclaration(cursor.kind))
return CXLinkage_Invalid;
- Decl *D = cxcursor::getCursorDecl(cursor);
- if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
+ const Decl *D = cxcursor::getCursorDecl(cursor);
+ if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
switch (ND->getLinkage()) {
case NoLinkage: return CXLinkage_NoLinkage;
case InternalLinkage: return CXLinkage_Internal;
@@ -5604,7 +5728,7 @@ extern "C" {
enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
if (clang_isDeclaration(cursor.kind))
- if (Decl *D = cxcursor::getCursorDecl(cursor)) {
+ if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
return CXAvailability_Available;
@@ -5631,12 +5755,14 @@ static CXVersion convertVersion(VersionTuple In) {
Out.Major = In.getMajor();
- if (llvm::Optional<unsigned> Minor = In.getMinor())
+ Optional<unsigned> Minor = In.getMinor();
+ if (Minor.hasValue())
Out.Minor = *Minor;
else
return Out;
- if (llvm::Optional<unsigned> Subminor = In.getSubminor())
+ Optional<unsigned> Subminor = In.getSubminor();
+ if (Subminor.hasValue())
Out.Subminor = *Subminor;
return Out;
@@ -5652,16 +5778,16 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
if (always_deprecated)
*always_deprecated = 0;
if (deprecated_message)
- *deprecated_message = cxstring::createCXString("", /*DupString=*/false);
+ *deprecated_message = cxstring::createEmpty();
if (always_unavailable)
*always_unavailable = 0;
if (unavailable_message)
- *unavailable_message = cxstring::createCXString("", /*DupString=*/false);
+ *unavailable_message = cxstring::createEmpty();
if (!clang_isDeclaration(cursor.kind))
return 0;
- Decl *D = cxcursor::getCursorDecl(cursor);
+ const Decl *D = cxcursor::getCursorDecl(cursor);
if (!D)
return 0;
@@ -5672,7 +5798,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
if (always_deprecated)
*always_deprecated = 1;
if (deprecated_message)
- *deprecated_message = cxstring::createCXString(Deprecated->getMessage());
+ *deprecated_message = cxstring::createDup(Deprecated->getMessage());
continue;
}
@@ -5680,8 +5806,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
if (always_unavailable)
*always_unavailable = 1;
if (unavailable_message) {
- *unavailable_message
- = cxstring::createCXString(Unavailable->getMessage());
+ *unavailable_message = cxstring::createDup(Unavailable->getMessage());
}
continue;
}
@@ -5689,12 +5814,12 @@ int clang_getCursorPlatformAvailability(CXCursor cursor,
if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
if (N < availability_size) {
availability[N].Platform
- = cxstring::createCXString(Avail->getPlatform()->getName());
+ = cxstring::createDup(Avail->getPlatform()->getName());
availability[N].Introduced = convertVersion(Avail->getIntroduced());
availability[N].Deprecated = convertVersion(Avail->getDeprecated());
availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
availability[N].Unavailable = Avail->getUnavailable();
- availability[N].Message = cxstring::createCXString(Avail->getMessage());
+ availability[N].Message = cxstring::createDup(Avail->getMessage());
}
++N;
}
@@ -5718,15 +5843,15 @@ CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
/// \brief If the given cursor is the "templated" declaration
/// descibing a class or function template, return the class or
/// function template.
-static Decl *maybeGetTemplateCursor(Decl *D) {
+static const Decl *maybeGetTemplateCursor(const Decl *D) {
if (!D)
return 0;
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
return FunTmpl;
- if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
return ClassTmpl;
@@ -5735,8 +5860,8 @@ static Decl *maybeGetTemplateCursor(Decl *D) {
CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
if (clang_isDeclaration(cursor.kind)) {
- if (Decl *D = getCursorDecl(cursor)) {
- DeclContext *DC = D->getDeclContext();
+ if (const Decl *D = getCursorDecl(cursor)) {
+ const DeclContext *DC = D->getDeclContext();
if (!DC)
return clang_getNullCursor();
@@ -5746,7 +5871,7 @@ CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
}
if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
- if (Decl *D = getCursorDecl(cursor))
+ if (const Decl *D = getCursorDecl(cursor))
return MakeCXCursor(D, getCursorTU(cursor));
}
@@ -5755,8 +5880,8 @@ CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
if (clang_isDeclaration(cursor.kind)) {
- if (Decl *D = getCursorDecl(cursor)) {
- DeclContext *DC = D->getLexicalDeclContext();
+ if (const Decl *D = getCursorDecl(cursor)) {
+ const DeclContext *DC = D->getLexicalDeclContext();
if (!DC)
return clang_getNullCursor();
@@ -5774,8 +5899,8 @@ CXFile clang_getIncludedFile(CXCursor cursor) {
if (cursor.kind != CXCursor_InclusionDirective)
return 0;
- InclusionDirective *ID = getCursorInclusionDirective(cursor);
- return (void *)ID->getFile();
+ const InclusionDirective *ID = getCursorInclusionDirective(cursor);
+ return const_cast<FileEntry *>(ID->getFile());
}
CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
@@ -5793,7 +5918,7 @@ CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
CXString clang_Cursor_getRawCommentText(CXCursor C) {
if (!clang_isDeclaration(C.kind))
- return createCXString((const char *) NULL);
+ return cxstring::createNull();
const Decl *D = getCursorDecl(C);
ASTContext &Context = getCursorContext(C);
@@ -5803,12 +5928,12 @@ CXString clang_Cursor_getRawCommentText(CXCursor C) {
// Don't duplicate the string because RawText points directly into source
// code.
- return createCXString(RawText, false);
+ return cxstring::createRef(RawText);
}
CXString clang_Cursor_getBriefCommentText(CXCursor C) {
if (!clang_isDeclaration(C.kind))
- return createCXString((const char *) NULL);
+ return cxstring::createNull();
const Decl *D = getCursorDecl(C);
const ASTContext &Context = getCursorContext(C);
@@ -5819,10 +5944,10 @@ CXString clang_Cursor_getBriefCommentText(CXCursor C) {
// Don't duplicate the string because RawComment ensures that this memory
// will not go away.
- return createCXString(BriefText, false);
+ return cxstring::createRef(BriefText);
}
- return createCXString((const char *) NULL);
+ return cxstring::createNull();
}
CXComment clang_Cursor_getParsedComment(CXCursor C) {
@@ -5838,7 +5963,8 @@ CXComment clang_Cursor_getParsedComment(CXCursor C) {
CXModule clang_Cursor_getModule(CXCursor C) {
if (C.kind == CXCursor_ModuleImportDecl) {
- if (ImportDecl *ImportD = dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
+ if (const ImportDecl *ImportD =
+ dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
return ImportD->getImportedModule();
}
@@ -5854,32 +5980,38 @@ CXModule clang_Module_getParent(CXModule CXMod) {
CXString clang_Module_getName(CXModule CXMod) {
if (!CXMod)
- return createCXString("");
+ return cxstring::createEmpty();
Module *Mod = static_cast<Module*>(CXMod);
- return createCXString(Mod->Name);
+ return cxstring::createDup(Mod->Name);
}
CXString clang_Module_getFullName(CXModule CXMod) {
if (!CXMod)
- return createCXString("");
+ return cxstring::createEmpty();
Module *Mod = static_cast<Module*>(CXMod);
- return createCXString(Mod->getFullModuleName());
+ return cxstring::createDup(Mod->getFullModuleName());
}
-unsigned clang_Module_getNumTopLevelHeaders(CXModule CXMod) {
- if (!CXMod)
+unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
+ CXModule CXMod) {
+ if (!TU || !CXMod)
return 0;
Module *Mod = static_cast<Module*>(CXMod);
- return Mod->TopHeaders.size();
+ FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
+ ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
+ return TopHeaders.size();
}
-CXFile clang_Module_getTopLevelHeader(CXModule CXMod, unsigned Index) {
- if (!CXMod)
+CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
+ CXModule CXMod, unsigned Index) {
+ if (!TU || !CXMod)
return 0;
Module *Mod = static_cast<Module*>(CXMod);
+ FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
- if (Index < Mod->TopHeaders.size())
- return const_cast<FileEntry *>(Mod->TopHeaders[Index]);
+ ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
+ if (Index < TopHeaders.size())
+ return const_cast<FileEntry *>(TopHeaders[Index]);
return 0;
}
@@ -5895,9 +6027,10 @@ unsigned clang_CXXMethod_isStatic(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
- CXXMethodDecl *Method = 0;
- Decl *D = cxcursor::getCursorDecl(C);
- if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
+ 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);
@@ -5908,9 +6041,10 @@ unsigned clang_CXXMethod_isVirtual(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
- CXXMethodDecl *Method = 0;
- Decl *D = cxcursor::getCursorDecl(C);
- if (FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
+ 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);
@@ -5927,7 +6061,7 @@ CXType clang_getIBOutletCollectionType(CXCursor C) {
if (C.kind != CXCursor_IBOutletCollectionAttr)
return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
- IBOutletCollectionAttr *A =
+ const IBOutletCollectionAttr *A =
cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
@@ -6004,7 +6138,7 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
return usage;
}
- ASTUnit *astUnit = static_cast<ASTUnit*>(TU->TUData);
+ ASTUnit *astUnit = cxtu::getASTUnit(TU);
OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
ASTContext &astContext = astUnit->getASTContext();
@@ -6167,11 +6301,205 @@ void cxindex::printDiagsToStderr(ASTUnit *Unit) {
#endif
}
+MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
+ SourceLocation MacroDefLoc,
+ CXTranslationUnit TU){
+ if (MacroDefLoc.isInvalid() || !TU)
+ return 0;
+ if (!II.hadMacroDefinition())
+ return 0;
+
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
+ Preprocessor &PP = Unit->getPreprocessor();
+ MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
+ if (MD) {
+ for (MacroDirective::DefInfo
+ Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
+ if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
+ return Def.getMacroInfo();
+ }
+ }
+
+ return 0;
+}
+
+const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
+ CXTranslationUnit TU) {
+ if (!MacroDef || !TU)
+ return 0;
+ const IdentifierInfo *II = MacroDef->getName();
+ if (!II)
+ return 0;
+
+ return getMacroInfo(*II, MacroDef->getLocation(), TU);
+}
+
+MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
+ const Token &Tok,
+ CXTranslationUnit TU) {
+ if (!MI || !TU)
+ return 0;
+ if (Tok.isNot(tok::raw_identifier))
+ return 0;
+
+ if (MI->getNumTokens() == 0)
+ return 0;
+ SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
+ MI->getDefinitionEndLoc());
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
+
+ // Check that the token is inside the definition and not its argument list.
+ SourceManager &SM = Unit->getSourceManager();
+ if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
+ return 0;
+ if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
+ return 0;
+
+ Preprocessor &PP = Unit->getPreprocessor();
+ PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
+ if (!PPRec)
+ return 0;
+
+ StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
+ IdentifierInfo &II = PP.getIdentifierTable().get(Name);
+ if (!II.hadMacroDefinition())
+ return 0;
+
+ // Check that the identifier is not one of the macro arguments.
+ if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
+ return 0;
+
+ MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
+ if (!InnerMD)
+ return 0;
+
+ return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
+}
+
+MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
+ SourceLocation Loc,
+ CXTranslationUnit TU) {
+ if (Loc.isInvalid() || !MI || !TU)
+ return 0;
+
+ if (MI->getNumTokens() == 0)
+ return 0;
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
+ Preprocessor &PP = Unit->getPreprocessor();
+ if (!PP.getPreprocessingRecord())
+ return 0;
+ Loc = Unit->getSourceManager().getSpellingLoc(Loc);
+ Token Tok;
+ if (PP.getRawToken(Loc, Tok))
+ return 0;
+
+ return checkForMacroInMacroDefinition(MI, Tok, TU);
+}
+
extern "C" {
CXString clang_getClangVersion() {
- return createCXString(getClangFullVersion());
+ return cxstring::createDup(getClangFullVersion());
}
} // end: extern "C"
+Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
+ if (TU) {
+ if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
+ LogOS << '<' << Unit->getMainFileName() << '>';
+ if (Unit->isMainFileAST())
+ LogOS << " (" << Unit->getASTFileName() << ')';
+ return *this;
+ }
+ }
+
+ LogOS << "<NULL TU>";
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
+ *this << FE->getName();
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(CXCursor cursor) {
+ CXString cursorName = clang_getCursorDisplayName(cursor);
+ *this << cursorName << "@" << clang_getCursorLocation(cursor);
+ clang_disposeString(cursorName);
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
+ CXFile File;
+ unsigned Line, Column;
+ clang_getFileLocation(Loc, &File, &Line, &Column, 0);
+ CXString FileName = clang_getFileName(File);
+ *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
+ clang_disposeString(FileName);
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(CXSourceRange range) {
+ CXSourceLocation BLoc = clang_getRangeStart(range);
+ CXSourceLocation ELoc = clang_getRangeEnd(range);
+
+ CXFile BFile;
+ unsigned BLine, BColumn;
+ clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
+
+ CXFile EFile;
+ unsigned ELine, EColumn;
+ clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
+
+ CXString BFileName = clang_getFileName(BFile);
+ if (BFile == EFile) {
+ *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
+ BLine, BColumn, ELine, EColumn);
+ } else {
+ CXString EFileName = clang_getFileName(EFile);
+ *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
+ BLine, BColumn)
+ << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
+ ELine, EColumn);
+ clang_disposeString(EFileName);
+ }
+ clang_disposeString(BFileName);
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(CXString Str) {
+ *this << clang_getCString(Str);
+ return *this;
+}
+
+Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
+ LogOS << Fmt;
+ return *this;
+}
+
+cxindex::Logger::~Logger() {
+ LogOS.flush();
+
+ llvm::sys::ScopedLock L(EnableMultithreadingMutex);
+
+ static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
+
+ raw_ostream &OS = llvm::errs();
+ OS << "[libclang:" << Name << ':';
+
+ // FIXME: Portability.
+#if HAVE_PTHREAD_H && __APPLE__
+ mach_port_t tid = pthread_mach_thread_np(pthread_self());
+ OS << tid << ':';
+#endif
+
+ llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
+ OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
+ OS << Msg.str() << '\n';
+
+ if (Trace) {
+ llvm::sys::PrintStackTrace(stderr);
+ OS << "--------------------------------------------------\n";
+ }
+}
diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp
index 9bc3efa..c68dde7 100644
--- a/tools/libclang/CIndexCXX.cpp
+++ b/tools/libclang/CIndexCXX.cpp
@@ -26,7 +26,7 @@ unsigned clang_isVirtualBase(CXCursor C) {
if (C.kind != CXCursor_CXXBaseSpecifier)
return 0;
- CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
+ const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
return B->isVirtual();
}
@@ -56,14 +56,13 @@ enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) {
switch (C.kind) {
case CXCursor_ClassTemplate:
case CXCursor_FunctionTemplate:
- if (TemplateDecl *Template
+ if (const TemplateDecl *Template
= dyn_cast_or_null<TemplateDecl>(getCursorDecl(C)))
- return MakeCXCursor(Template->getTemplatedDecl(),
- static_cast<CXTranslationUnit>(C.data[2])).kind;
+ return MakeCXCursor(Template->getTemplatedDecl(), getCursorTU(C)).kind;
break;
case CXCursor_ClassTemplatePartialSpecialization:
- if (ClassTemplateSpecializationDecl *PartialSpec
+ if (const ClassTemplateSpecializationDecl *PartialSpec
= dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(
getCursorDecl(C))) {
switch (PartialSpec->getTagKind()) {
@@ -87,16 +86,16 @@ CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getNullCursor();
- Decl *D = getCursorDecl(C);
+ const Decl *D = getCursorDecl(C);
if (!D)
return clang_getNullCursor();
Decl *Template = 0;
- if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
- if (ClassTemplatePartialSpecializationDecl *PartialSpec
+ if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
+ if (const ClassTemplatePartialSpecializationDecl *PartialSpec
= dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
Template = PartialSpec->getSpecializedTemplate();
- else if (ClassTemplateSpecializationDecl *ClassSpec
+ else if (const ClassTemplateSpecializationDecl *ClassSpec
= dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *> Result
@@ -108,21 +107,21 @@ CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
} else
Template = CXXRecord->getInstantiatedFromMemberClass();
- } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+ } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Template = Function->getPrimaryTemplate();
if (!Template)
Template = Function->getInstantiatedFromMemberFunction();
- } else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
if (Var->isStaticDataMember())
Template = Var->getInstantiatedFromStaticDataMember();
- } else if (RedeclarableTemplateDecl *Tmpl
+ } else if (const RedeclarableTemplateDecl *Tmpl
= dyn_cast<RedeclarableTemplateDecl>(D))
Template = Tmpl->getInstantiatedFromMemberTemplate();
if (!Template)
return clang_getNullCursor();
- return MakeCXCursor(Template, static_cast<CXTranslationUnit>(C.data[2]));
+ return MakeCXCursor(Template, getCursorTU(C));
}
} // end extern "C"
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 46af661..f79de29 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -13,16 +13,16 @@
//===----------------------------------------------------------------------===//
#include "CIndexer.h"
-#include "CXTranslationUnit.h"
-#include "CXString.h"
+#include "CIndexDiagnostic.h"
+#include "CLog.h"
#include "CXCursor.h"
#include "CXString.h"
-#include "CIndexDiagnostic.h"
-#include "clang/AST/Type.h"
+#include "CXTranslationUnit.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
-#include "clang/Basic/SourceManager.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
@@ -32,11 +32,12 @@
#include "llvm/Support/Atomic.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Program.h"
-#include <cstdlib>
#include <cstdio>
+#include <cstdlib>
+#include <string>
#ifdef UDP_CODE_COMPLETION_LOGGER
@@ -48,7 +49,7 @@
#endif
using namespace clang;
-using namespace clang::cxstring;
+using namespace clang::cxindex;
extern "C" {
@@ -111,7 +112,7 @@ CXString clang_getCompletionChunkText(CXCompletionString completion_string,
unsigned chunk_number) {
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
if (!CCStr || chunk_number >= CCStr->size())
- return createCXString((const char*)0);
+ return cxstring::createNull();
switch ((*CCStr)[chunk_number].Kind) {
case CodeCompletionString::CK_TypedText:
@@ -134,11 +135,11 @@ CXString clang_getCompletionChunkText(CXCompletionString completion_string,
case CodeCompletionString::CK_Equal:
case CodeCompletionString::CK_HorizontalSpace:
case CodeCompletionString::CK_VerticalSpace:
- return createCXString((*CCStr)[chunk_number].Text, false);
+ return cxstring::createRef((*CCStr)[chunk_number].Text);
case CodeCompletionString::CK_Optional:
// Note: treated as an empty text block.
- return createCXString("");
+ return cxstring::createEmpty();
}
llvm_unreachable("Invalid CodeCompletionString Kind!");
@@ -209,8 +210,8 @@ unsigned clang_getCompletionNumAnnotations(CXCompletionString completion_string)
CXString clang_getCompletionAnnotation(CXCompletionString completion_string,
unsigned annotation_number) {
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
- return CCStr ? createCXString(CCStr->getAnnotation(annotation_number))
- : createCXString((const char *) 0);
+ return CCStr ? cxstring::createRef(CCStr->getAnnotation(annotation_number))
+ : cxstring::createNull();
}
CXString
@@ -221,9 +222,9 @@ clang_getCompletionParent(CXCompletionString completion_string,
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
if (!CCStr)
- return createCXString((const char *)0);
+ return cxstring::createNull();
- return createCXString(CCStr->getParentContextName(), /*DupString=*/false);
+ return cxstring::createRef(CCStr->getParentContextName());
}
CXString
@@ -231,14 +232,20 @@ clang_getCompletionBriefComment(CXCompletionString completion_string) {
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
if (!CCStr)
- return createCXString((const char *) NULL);
+ return cxstring::createNull();
- return createCXString(CCStr->getBriefComment(), /*DupString=*/false);
+ return cxstring::createRef(CCStr->getBriefComment());
}
-
+namespace {
+
/// \brief The CXCodeCompleteResults structure we allocate internally;
/// the client only sees the initial CXCodeCompleteResults structure.
+///
+/// Normally, clients of CXString shouldn't care whether or not a CXString is
+/// managed by a pool or by explicitly malloc'ed memory. But
+/// AllocatedCXCodeCompleteResults outlives the CXTranslationUnit, so we can
+/// not rely on the StringPool in the TU.
struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
AllocatedCXCodeCompleteResults(const FileSystemOptions& FileSystemOpts);
~AllocatedCXCodeCompleteResults();
@@ -287,8 +294,10 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
/// \brief The kind of the container for the current context for completions.
enum CXCursorKind ContainerKind;
+
/// \brief The USR of the container for the current context for completions.
- CXString ContainerUSR;
+ std::string ContainerUSR;
+
/// \brief a boolean value indicating whether there is complete information
/// about the container
unsigned ContainerIsIncomplete;
@@ -298,6 +307,8 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
std::string Selector;
};
+} // end anonymous namespace
+
/// \brief Tracks the number of code-completion result objects that are
/// currently active.
///
@@ -317,7 +328,6 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
Contexts(CXCompletionContext_Unknown),
ContainerKind(CXCursor_InvalidCode),
- ContainerUSR(createCXString("")),
ContainerIsIncomplete(1)
{
if (getenv("LIBCLANG_OBJTRACKING")) {
@@ -328,9 +338,7 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
delete [] Results;
-
- clang_disposeString(ContainerUSR);
-
+
for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
TemporaryFiles[I].eraseFromDisk();
for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
@@ -587,24 +595,13 @@ namespace {
if (D != NULL) {
CXCursor cursor = cxcursor::MakeCXCursor(D, *TU);
-
- CXCursorKind cursorKind = clang_getCursorKind(cursor);
- CXString cursorUSR = clang_getCursorUSR(cursor);
-
- // Normally, clients of CXString shouldn't care whether or not
- // a CXString is managed by a pool or by explicitly malloc'ed memory.
- // However, there are cases when AllocatedResults outlives the
- // CXTranslationUnit. This is a workaround that failure mode.
- if (cxstring::isManagedByPool(cursorUSR)) {
- CXString heapStr =
- cxstring::createCXString(clang_getCString(cursorUSR), true);
- clang_disposeString(cursorUSR);
- cursorUSR = heapStr;
- }
-
- AllocatedResults.ContainerKind = cursorKind;
- AllocatedResults.ContainerUSR = cursorUSR;
-
+
+ AllocatedResults.ContainerKind = clang_getCursorKind(cursor);
+
+ CXString CursorUSR = clang_getCursorUSR(cursor);
+ AllocatedResults.ContainerUSR = clang_getCString(CursorUSR);
+ clang_disposeString(CursorUSR);
+
const Type *type = baseType.getTypePtrOrNull();
if (type != NULL) {
AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
@@ -615,7 +612,7 @@ namespace {
}
else {
AllocatedResults.ContainerKind = CXCursor_InvalidCode;
- AllocatedResults.ContainerUSR = createCXString("");
+ AllocatedResults.ContainerUSR.clear();
AllocatedResults.ContainerIsIncomplete = 1;
}
}
@@ -684,11 +681,11 @@ void clang_codeCompleteAt_Impl(void *UserData) {
bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
- ASTUnit *AST = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *AST = cxtu::getASTUnit(TU);
if (!AST)
return;
- CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
+ CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
setThreadBackgroundPriority();
@@ -819,14 +816,25 @@ CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
struct CXUnsavedFile *unsaved_files,
unsigned num_unsaved_files,
unsigned options) {
+ LOG_FUNC_SECTION {
+ *Log << TU << ' '
+ << complete_filename << ':' << complete_line << ':' << complete_column;
+ }
+
CodeCompleteAtInfo CCAI = { TU, complete_filename, complete_line,
complete_column, unsaved_files, num_unsaved_files,
options, 0 };
+
+ if (getenv("LIBCLANG_NOTHREADS")) {
+ clang_codeCompleteAt_Impl(&CCAI);
+ return CCAI.result;
+ }
+
llvm::CrashRecoveryContext CRC;
if (!RunSafely(CRC, clang_codeCompleteAt_Impl, &CCAI)) {
fprintf(stderr, "libclang: crash detected in code completion\n");
- static_cast<ASTUnit *>(TU->TUData)->setUnsafeToFree(true);
+ cxtu::getASTUnit(TU)->setUnsafeToFree(true);
return 0;
} else if (getenv("LIBCLANG_RESOURCE_USAGE"))
PrintLibclangResourceUsage(TU);
@@ -897,9 +905,9 @@ CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
AllocatedCXCodeCompleteResults *Results =
static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
if (!Results)
- return createCXString("");
-
- return createCXString(clang_getCString(Results->ContainerUSR));
+ return cxstring::createEmpty();
+
+ return cxstring::createRef(Results->ContainerUSR.c_str());
}
@@ -907,9 +915,9 @@ CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
AllocatedCXCodeCompleteResults *Results =
static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
if (!Results)
- return createCXString("");
+ return cxstring::createEmpty();
- return createCXString(Results->Selector);
+ return cxstring::createDup(Results->Selector);
}
} // end extern "C"
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 3154480..0e9dde8 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -27,7 +27,6 @@
using namespace clang;
using namespace clang::cxloc;
-using namespace clang::cxstring;
using namespace clang::cxdiag;
using namespace llvm;
@@ -62,17 +61,17 @@ public:
}
CXString getSpelling() const {
- return createCXString(StringRef(Message), false);
+ return cxstring::createRef(Message.c_str());
}
CXString getDiagnosticOption(CXString *Disable) const {
if (Disable)
- *Disable = createCXString("", false);
- return createCXString("", false);
+ *Disable = cxstring::createEmpty();
+ return cxstring::createEmpty();
}
unsigned getCategory() const { return 0; }
- CXString getCategoryText() const { return createCXString(""); }
+ CXString getCategoryText() const { return cxstring::createEmpty(); }
unsigned getNumRanges() const { return 0; }
CXSourceRange getRange(unsigned Range) const { return clang_getNullRange(); }
@@ -80,7 +79,7 @@ public:
CXString getFixIt(unsigned FixIt, CXSourceRange *ReplacementRange) const {
if (ReplacementRange)
*ReplacementRange = clang_getNullRange();
- return createCXString("", false);
+ return cxstring::createEmpty();
}
};
@@ -158,7 +157,7 @@ public:
CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
bool checkIfChanged) {
- ASTUnit *AU = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *AU = cxtu::getASTUnit(TU);
if (TU->Diagnostics && checkIfChanged) {
// In normal use, ASTUnit's diagnostics should not change unless we reparse.
@@ -191,7 +190,7 @@ CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
if (!TU->Diagnostics) {
CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
TU->Diagnostics = Set;
- llvm::IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
+ IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
&*DOpts, Set);
@@ -209,7 +208,7 @@ CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
extern "C" {
unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
- if (!Unit->TUData)
+ if (!cxtu::getASTUnit(Unit))
return 0;
return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
}
@@ -227,7 +226,7 @@ CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
}
CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
- if (!Unit->TUData)
+ if (!cxtu::getASTUnit(Unit))
return 0;
return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
}
@@ -239,7 +238,7 @@ void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
if (!Diagnostic)
- return createCXString("");
+ return cxstring::createEmpty();
CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
@@ -354,7 +353,7 @@ CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
Out << "]";
}
- return createCXString(Out.str(), true);
+ return cxstring::createDup(Out.str());
}
unsigned clang_defaultDiagnosticDisplayOptions() {
@@ -377,17 +376,17 @@ CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getSpelling();
- return createCXString("");
+ return cxstring::createEmpty();
}
CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
if (Disable)
- *Disable = createCXString("");
+ *Disable = cxstring::createEmpty();
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getDiagnosticOption(Disable);
- return createCXString("");
+ return cxstring::createEmpty();
}
unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
@@ -398,13 +397,13 @@ unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
CXString clang_getDiagnosticCategoryName(unsigned Category) {
// Kept for backwards compatibility.
- return createCXString(DiagnosticIDs::getCategoryNameFromID(Category));
+ return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(Category));
}
CXString clang_getDiagnosticCategoryText(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getCategoryText();
- return createCXString("");
+ return cxstring::createEmpty();
}
unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
@@ -432,7 +431,7 @@ CXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt,
if (!D || FixIt >= D->getNumFixIts()) {
if (ReplacementRange)
*ReplacementRange = clang_getNullRange();
- return createCXString("");
+ return cxstring::createEmpty();
}
return D->getFixIt(FixIt, ReplacementRange);
}
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
index ec76898..2a55af5 100644
--- a/tools/libclang/CIndexHigh.cpp
+++ b/tools/libclang/CIndexHigh.cpp
@@ -8,19 +8,21 @@
//===----------------------------------------------------------------------===//
#include "CursorVisitor.h"
+#include "CLog.h"
#include "CXCursor.h"
#include "CXSourceLocation.h"
#include "CXTranslationUnit.h"
-
-#include "clang/Frontend/ASTUnit.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "llvm/Support/Compiler.h"
using namespace clang;
using namespace cxcursor;
+using namespace cxindex;
static void getTopOverriddenMethods(CXTranslationUnit TU,
- Decl *D,
- SmallVectorImpl<Decl *> &Methods) {
+ const Decl *D,
+ SmallVectorImpl<const Decl *> &Methods) {
if (!D)
return;
if (!isa<ObjCMethodDecl>(D) && !isa<CXXMethodDecl>(D))
@@ -44,15 +46,15 @@ namespace {
struct FindFileIdRefVisitData {
CXTranslationUnit TU;
FileID FID;
- Decl *Dcl;
+ const Decl *Dcl;
int SelectorIdIdx;
CXCursorAndRangeVisitor visitor;
- typedef SmallVector<Decl *, 8> TopMethodsTy;
+ typedef SmallVector<const Decl *, 8> TopMethodsTy;
TopMethodsTy TopMethods;
FindFileIdRefVisitData(CXTranslationUnit TU, FileID FID,
- Decl *D, int selectorIdIdx,
+ const Decl *D, int selectorIdIdx,
CXCursorAndRangeVisitor visitor)
: TU(TU), FID(FID), SelectorIdIdx(selectorIdIdx), visitor(visitor) {
Dcl = getCanonical(D);
@@ -60,7 +62,7 @@ struct FindFileIdRefVisitData {
}
ASTContext &getASTContext() const {
- return static_cast<ASTUnit *>(TU->TUData)->getASTContext();
+ return cxtu::getASTUnit(TU)->getASTContext();
}
/// \brief We are looking to find all semantically relevant identifiers,
@@ -74,24 +76,25 @@ struct FindFileIdRefVisitData {
///
/// we consider the canonical decl of the constructor decl to be the class
/// itself, so both 'C' can be highlighted.
- Decl *getCanonical(Decl *D) const {
+ const Decl *getCanonical(const Decl *D) const {
if (!D)
return 0;
D = D->getCanonicalDecl();
- if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D)) {
+ if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D)) {
if (ImplD->getClassInterface())
return getCanonical(ImplD->getClassInterface());
- } else if (CXXConstructorDecl *CXXCtorD = dyn_cast<CXXConstructorDecl>(D)) {
+ } else if (const CXXConstructorDecl *CXXCtorD =
+ dyn_cast<CXXConstructorDecl>(D)) {
return getCanonical(CXXCtorD->getParent());
}
return D;
}
- bool isHit(Decl *D) const {
+ bool isHit(const Decl *D) const {
if (!D)
return false;
@@ -106,7 +109,7 @@ struct FindFileIdRefVisitData {
}
private:
- bool isOverriddingMethod(Decl *D) const {
+ bool isOverriddingMethod(const Decl *D) const {
if (std::find(TopMethods.begin(), TopMethods.end(), D) !=
TopMethods.end())
return true;
@@ -148,7 +151,7 @@ static enum CXChildVisitResult findFileIdRefVisit(CXCursor cursor,
if (!clang_isDeclaration(declCursor.kind))
return CXChildVisit_Recurse;
- Decl *D = cxcursor::getCursorDecl(declCursor);
+ const Decl *D = cxcursor::getCursorDecl(declCursor);
if (!D)
return CXChildVisit_Continue;
@@ -202,32 +205,31 @@ static enum CXChildVisitResult findFileIdRefVisit(CXCursor cursor,
return CXChildVisit_Recurse;
}
- data->visitor.visit(data->visitor.context, cursor,
- cxloc::translateSourceRange(Ctx, Loc));
+ if (data->visitor.visit(data->visitor.context, cursor,
+ cxloc::translateSourceRange(Ctx, Loc)) == CXVisit_Break)
+ return CXChildVisit_Break;
}
return CXChildVisit_Recurse;
}
-static void findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor,
- const FileEntry *File,
- CXCursorAndRangeVisitor Visitor) {
+static bool findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor,
+ const FileEntry *File,
+ CXCursorAndRangeVisitor Visitor) {
assert(clang_isDeclaration(declCursor.kind));
- ASTUnit *Unit = static_cast<ASTUnit*>(TU->TUData);
- SourceManager &SM = Unit->getSourceManager();
+ SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
FileID FID = SM.translateFile(File);
- Decl *Dcl = cxcursor::getCursorDecl(declCursor);
+ const Decl *Dcl = cxcursor::getCursorDecl(declCursor);
if (!Dcl)
- return;
+ return false;
FindFileIdRefVisitData data(TU, FID, Dcl,
cxcursor::getSelectorIdentifierIndex(declCursor),
Visitor);
- if (DeclContext *DC = Dcl->getParentFunctionOrMethod()) {
- clang_visitChildren(cxcursor::MakeCXCursor(cast<Decl>(DC), TU),
- findFileIdRefVisit, &data);
- return;
+ if (const DeclContext *DC = Dcl->getParentFunctionOrMethod()) {
+ return clang_visitChildren(cxcursor::MakeCXCursor(cast<Decl>(DC), TU),
+ findFileIdRefVisit, &data);
}
SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID));
@@ -237,7 +239,7 @@ static void findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor,
/*VisitIncludedEntities=*/false,
Range,
/*VisitDeclsOnly=*/true);
- FindIdRefsVisitor.visitFileRegion();
+ return FindIdRefsVisitor.visitFileRegion();
}
namespace {
@@ -267,7 +269,7 @@ static enum CXChildVisitResult findFileMacroRefVisit(CXCursor cursor,
if (cursor.kind == CXCursor_MacroDefinition)
Macro = getCursorMacroDefinition(cursor)->getName();
else if (cursor.kind == CXCursor_MacroExpansion)
- Macro = getCursorMacroExpansion(cursor)->getName();
+ Macro = getCursorMacroExpansion(cursor).getName();
if (!Macro)
return CXChildVisit_Continue;
@@ -298,19 +300,20 @@ static enum CXChildVisitResult findFileMacroRefVisit(CXCursor cursor,
return CXChildVisit_Continue;
}
- data->visitor.visit(data->visitor.context, cursor,
- cxloc::translateSourceRange(Ctx, Loc));
+ if (data->visitor.visit(data->visitor.context, cursor,
+ cxloc::translateSourceRange(Ctx, Loc)) == CXVisit_Break)
+ return CXChildVisit_Break;
return CXChildVisit_Continue;
}
-static void findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
+static bool findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
const FileEntry *File,
CXCursorAndRangeVisitor Visitor) {
if (Cursor.kind != CXCursor_MacroDefinition &&
Cursor.kind != CXCursor_MacroExpansion)
- return;
+ return false;
- ASTUnit *Unit = static_cast<ASTUnit*>(TU->TUData);
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
SourceManager &SM = Unit->getSourceManager();
FileID FID = SM.translateFile(File);
@@ -318,9 +321,9 @@ static void findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
if (Cursor.kind == CXCursor_MacroDefinition)
Macro = getCursorMacroDefinition(Cursor)->getName();
else
- Macro = getCursorMacroExpansion(Cursor)->getName();
+ Macro = getCursorMacroExpansion(Cursor).getName();
if (!Macro)
- return;
+ return false;
FindFileMacroRefVisitData data(*Unit, File, Macro, Visitor);
@@ -330,7 +333,73 @@ static void findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
/*VisitPreprocessorLast=*/false,
/*VisitIncludedEntities=*/false,
Range);
- FindMacroRefsVisitor.visitPreprocessedEntitiesInRegion();
+ return FindMacroRefsVisitor.visitPreprocessedEntitiesInRegion();
+}
+
+namespace {
+
+struct FindFileIncludesVisitor {
+ ASTUnit &Unit;
+ const FileEntry *File;
+ CXCursorAndRangeVisitor visitor;
+
+ FindFileIncludesVisitor(ASTUnit &Unit, const FileEntry *File,
+ CXCursorAndRangeVisitor visitor)
+ : Unit(Unit), File(File), visitor(visitor) { }
+
+ ASTContext &getASTContext() const {
+ return Unit.getASTContext();
+ }
+
+ enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
+ if (cursor.kind != CXCursor_InclusionDirective)
+ return CXChildVisit_Continue;
+
+ SourceLocation
+ Loc = cxloc::translateSourceLocation(clang_getCursorLocation(cursor));
+
+ ASTContext &Ctx = getASTContext();
+ SourceManager &SM = Ctx.getSourceManager();
+
+ // We are looking for includes in a specific file.
+ std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+ if (SM.getFileEntryForID(LocInfo.first) != File)
+ return CXChildVisit_Continue;
+
+ if (visitor.visit(visitor.context, cursor,
+ cxloc::translateSourceRange(Ctx, Loc)) == CXVisit_Break)
+ return CXChildVisit_Break;
+ return CXChildVisit_Continue;
+ }
+
+ static enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent,
+ CXClientData client_data) {
+ return static_cast<FindFileIncludesVisitor*>(client_data)->
+ visit(cursor, parent);
+ }
+};
+
+} // anonymous namespace
+
+static bool findIncludesInFile(CXTranslationUnit TU, const FileEntry *File,
+ CXCursorAndRangeVisitor Visitor) {
+ assert(TU && File && Visitor.visit);
+
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
+ SourceManager &SM = Unit->getSourceManager();
+
+ FileID FID = SM.translateFile(File);
+
+ FindFileIncludesVisitor IncludesVisitor(*Unit, File, Visitor);
+
+ SourceRange Range(SM.getLocForStartOfFile(FID), SM.getLocForEndOfFile(FID));
+ CursorVisitor InclusionCursorsVisitor(TU,
+ FindFileIncludesVisitor::visit,
+ &IncludesVisitor,
+ /*VisitPreprocessorLast=*/false,
+ /*VisitIncludedEntities=*/false,
+ Range);
+ return InclusionCursorsVisitor.visitPreprocessedEntitiesInRegion();
}
@@ -340,44 +409,48 @@ static void findMacroRefsInFile(CXTranslationUnit TU, CXCursor Cursor,
extern "C" {
-void clang_findReferencesInFile(CXCursor cursor, CXFile file,
- CXCursorAndRangeVisitor visitor) {
- bool Logging = ::getenv("LIBCLANG_LOGGING");
+CXResult clang_findReferencesInFile(CXCursor cursor, CXFile file,
+ CXCursorAndRangeVisitor visitor) {
+ LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
if (clang_Cursor_isNull(cursor)) {
- if (Logging)
- llvm::errs() << "clang_findReferencesInFile: Null cursor\n";
- return;
+ if (Log)
+ *Log << "Null cursor";
+ return CXResult_Invalid;
}
if (cursor.kind == CXCursor_NoDeclFound) {
- if (Logging)
- llvm::errs() << "clang_findReferencesInFile: Got CXCursor_NoDeclFound\n";
- return;
+ if (Log)
+ *Log << "Got CXCursor_NoDeclFound";
+ return CXResult_Invalid;
}
if (!file) {
- if (Logging)
- llvm::errs() << "clang_findReferencesInFile: Null file\n";
- return;
+ if (Log)
+ *Log << "Null file";
+ return CXResult_Invalid;
}
if (!visitor.visit) {
- if (Logging)
- llvm::errs() << "clang_findReferencesInFile: Null visitor\n";
- return;
+ if (Log)
+ *Log << "Null visitor";
+ return CXResult_Invalid;
}
+ if (Log)
+ *Log << cursor << " @" << static_cast<const FileEntry *>(file);
+
ASTUnit *CXXUnit = cxcursor::getCursorASTUnit(cursor);
if (!CXXUnit)
- return;
+ return CXResult_Invalid;
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
if (cursor.kind == CXCursor_MacroDefinition ||
cursor.kind == CXCursor_MacroExpansion) {
- findMacroRefsInFile(cxcursor::getCursorTU(cursor),
- cursor,
- static_cast<const FileEntry *>(file),
- visitor);
- return;
+ if (findMacroRefsInFile(cxcursor::getCursorTU(cursor),
+ cursor,
+ static_cast<const FileEntry *>(file),
+ visitor))
+ return CXResult_VisitBreak;
+ return CXResult_Success;
}
// We are interested in semantics of identifiers so for C++ constructor exprs
@@ -392,16 +465,51 @@ void clang_findReferencesInFile(CXCursor cursor, CXFile file,
CXCursor refCursor = clang_getCursorReferenced(cursor);
if (!clang_isDeclaration(refCursor.kind)) {
- if (Logging)
- llvm::errs() << "clang_findReferencesInFile: cursor is not referencing a "
- "declaration\n";
- return;
+ if (Log)
+ *Log << "cursor is not referencing a declaration";
+ return CXResult_Invalid;
}
- findIdRefsInFile(cxcursor::getCursorTU(cursor),
- refCursor,
- static_cast<const FileEntry *>(file),
- visitor);
+ if (findIdRefsInFile(cxcursor::getCursorTU(cursor),
+ refCursor,
+ static_cast<const FileEntry *>(file),
+ visitor))
+ return CXResult_VisitBreak;
+ return CXResult_Success;
+}
+
+CXResult clang_findIncludesInFile(CXTranslationUnit TU, CXFile file,
+ CXCursorAndRangeVisitor visitor) {
+ LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
+
+ if (!TU) {
+ if (Log)
+ *Log << "Null CXTranslationUnit";
+ return CXResult_Invalid;
+ }
+ if (!file) {
+ if (Log)
+ *Log << "Null file";
+ return CXResult_Invalid;
+ }
+ if (!visitor.visit) {
+ if (Log)
+ *Log << "Null visitor";
+ return CXResult_Invalid;
+ }
+
+ if (Log)
+ *Log << TU << " @" << static_cast<const FileEntry *>(file);
+
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
+ if (!CXXUnit)
+ return CXResult_Invalid;
+
+ ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+ if (findIncludesInFile(TU, static_cast<const FileEntry *>(file), visitor))
+ return CXResult_VisitBreak;
+ return CXResult_Success;
}
static enum CXVisitorResult _visitCursorAndRange(void *context,
@@ -411,13 +519,21 @@ static enum CXVisitorResult _visitCursorAndRange(void *context,
return INVOKE_BLOCK2(block, cursor, range);
}
-void clang_findReferencesInFileWithBlock(CXCursor cursor,
- CXFile file,
- CXCursorAndRangeVisitorBlock block) {
+CXResult clang_findReferencesInFileWithBlock(CXCursor cursor,
+ CXFile file,
+ CXCursorAndRangeVisitorBlock block) {
CXCursorAndRangeVisitor visitor = { block,
block ? _visitCursorAndRange : 0 };
return clang_findReferencesInFile(cursor, file, visitor);
}
+CXResult clang_findIncludesInFileWithBlock(CXTranslationUnit TU,
+ CXFile file,
+ CXCursorAndRangeVisitorBlock block) {
+ CXCursorAndRangeVisitor visitor = { block,
+ block ? _visitCursorAndRange : 0 };
+ return clang_findIncludesInFile(TU, file, visitor);
+}
+
} // end: extern "C"
diff --git a/tools/libclang/CIndexInclusionStack.cpp b/tools/libclang/CIndexInclusionStack.cpp
index 848ca31..a6d3115 100644
--- a/tools/libclang/CIndexInclusionStack.cpp
+++ b/tools/libclang/CIndexInclusionStack.cpp
@@ -13,8 +13,8 @@
//===----------------------------------------------------------------------===//
#include "CIndexer.h"
-#include "CXTranslationUnit.h"
#include "CXSourceLocation.h"
+#include "CXTranslationUnit.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/Frontend/ASTUnit.h"
#include "llvm/ADT/SmallString.h"
@@ -25,7 +25,7 @@ extern "C" {
void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
CXClientData clientData) {
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
SourceManager &SM = CXXUnit->getSourceManager();
ASTContext &Ctx = CXXUnit->getASTContext();
@@ -64,7 +64,8 @@ void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
// Callback to the client.
// FIXME: We should have a function to construct CXFiles.
- CB((CXFile) FI.getContentCache()->OrigEntry,
+ CB(static_cast<CXFile>(
+ const_cast<FileEntry *>(FI.getContentCache()->OrigEntry)),
InclusionStack.data(), InclusionStack.size(), clientData);
}
}
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index 6140032..a911ce5 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -22,14 +22,13 @@
#include "llvm/Support/raw_ostream.h"
using namespace clang;
-using namespace clang::cxstring;
//===----------------------------------------------------------------------===//
// USR generation.
//===----------------------------------------------------------------------===//
namespace {
-class USRGenerator : public DeclVisitor<USRGenerator> {
+class USRGenerator : public ConstDeclVisitor<USRGenerator> {
OwningPtr<SmallString<128> > OwnedBuf;
SmallVectorImpl<char> &Buf;
llvm::raw_svector_ostream Out;
@@ -67,37 +66,37 @@ public:
bool ignoreResults() const { return IgnoreResults; }
// Visitation methods from generating USRs from AST elements.
- void VisitDeclContext(DeclContext *D);
- void VisitFieldDecl(FieldDecl *D);
- void VisitFunctionDecl(FunctionDecl *D);
- void VisitNamedDecl(NamedDecl *D);
- void VisitNamespaceDecl(NamespaceDecl *D);
- void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
- void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
- void VisitClassTemplateDecl(ClassTemplateDecl *D);
- void VisitObjCContainerDecl(ObjCContainerDecl *CD);
- void VisitObjCMethodDecl(ObjCMethodDecl *MD);
- void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
- void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
- void VisitTagDecl(TagDecl *D);
- void VisitTypedefDecl(TypedefDecl *D);
- void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
- void VisitVarDecl(VarDecl *D);
- void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
- void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
- void VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+ 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(UsingDirectiveDecl *D) {
+ void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
IgnoreResults = true;
}
- void VisitUsingDecl(UsingDecl *D) {
+ void VisitUsingDecl(const UsingDecl *D) {
IgnoreResults = true;
}
- void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
+ void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
IgnoreResults = true;
}
- void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
+ void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
IgnoreResults = true;
}
@@ -151,25 +150,19 @@ bool USRGenerator::EmitDeclName(const NamedDecl *D) {
return startSize == endSize;
}
-static bool InAnonymousNamespace(const Decl *D) {
- if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D->getDeclContext()))
- return ND->isAnonymousNamespace();
- return false;
-}
-
static inline bool ShouldGenerateLocation(const NamedDecl *D) {
- return D->getLinkage() != ExternalLinkage && !InAnonymousNamespace(D);
+ return D->getLinkage() != ExternalLinkage;
}
-void USRGenerator::VisitDeclContext(DeclContext *DC) {
- if (NamedDecl *D = dyn_cast<NamedDecl>(DC))
+void USRGenerator::VisitDeclContext(const DeclContext *DC) {
+ if (const NamedDecl *D = dyn_cast<NamedDecl>(DC))
Visit(D);
}
-void USRGenerator::VisitFieldDecl(FieldDecl *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 (ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
+ if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
Visit(ID);
else
VisitDeclContext(D->getDeclContext());
@@ -181,7 +174,7 @@ void USRGenerator::VisitFieldDecl(FieldDecl *D) {
}
}
-void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
+void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
if (ShouldGenerateLocation(D) && GenLoc(D))
return;
@@ -208,7 +201,8 @@ void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
}
// Mangle in type information for the arguments.
- for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end();
+ for (FunctionDecl::param_const_iterator I = D->param_begin(),
+ E = D->param_end();
I != E; ++I) {
Out << '#';
if (ParmVarDecl *PD = *I)
@@ -217,7 +211,7 @@ void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
if (D->isVariadic())
Out << '.';
Out << '#';
- if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
if (MD->isStatic())
Out << 'S';
if (unsigned quals = MD->getTypeQualifiers())
@@ -225,7 +219,7 @@ void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
}
}
-void USRGenerator::VisitNamedDecl(NamedDecl *D) {
+void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
VisitDeclContext(D->getDeclContext());
Out << "@";
@@ -238,7 +232,7 @@ void USRGenerator::VisitNamedDecl(NamedDecl *D) {
}
}
-void USRGenerator::VisitVarDecl(VarDecl *D) {
+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.
@@ -260,17 +254,19 @@ void USRGenerator::VisitVarDecl(VarDecl *D) {
Out << '@' << s;
}
-void USRGenerator::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+void USRGenerator::VisitNonTypeTemplateParmDecl(
+ const NonTypeTemplateParmDecl *D) {
GenLoc(D);
return;
}
-void USRGenerator::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+void USRGenerator::VisitTemplateTemplateParmDecl(
+ const TemplateTemplateParmDecl *D) {
GenLoc(D);
return;
}
-void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
+void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
if (D->isAnonymousNamespace()) {
Out << "@aN";
return;
@@ -281,29 +277,29 @@ void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) {
Out << "@N@" << D->getName();
}
-void USRGenerator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
VisitFunctionDecl(D->getTemplatedDecl());
}
-void USRGenerator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
VisitTagDecl(D->getTemplatedDecl());
}
-void USRGenerator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
VisitDeclContext(D->getDeclContext());
if (!IgnoreResults)
Out << "@NA@" << D->getName();
}
-void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
- DeclContext *container = D->getDeclContext();
- if (ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
+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.
- ObjCInterfaceDecl *ID = D->getClassInterface();
+ const ObjCInterfaceDecl *ID = D->getClassInterface();
if (!ID) {
IgnoreResults = true;
return;
@@ -318,7 +314,7 @@ void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) {
N.printName(Out);
}
-void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
+void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D) {
switch (D->getKind()) {
default:
llvm_unreachable("Invalid ObjC container.");
@@ -327,8 +323,8 @@ void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
GenObjCClass(D->getName());
break;
case Decl::ObjCCategory: {
- ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
- ObjCInterfaceDecl *ID = CD->getClassInterface();
+ const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
+ const ObjCInterfaceDecl *ID = CD->getClassInterface();
if (!ID) {
// Handle invalid code where the @interface might not
// have been specified.
@@ -349,8 +345,8 @@ void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
break;
}
case Decl::ObjCCategoryImpl: {
- ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
- ObjCInterfaceDecl *ID = CD->getClassInterface();
+ const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
+ const ObjCInterfaceDecl *ID = CD->getClassInterface();
if (!ID) {
// Handle invalid code where the @interface might not
// have been specified.
@@ -368,17 +364,17 @@ void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
}
}
-void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+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 (ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
+ if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
Visit(ID);
else
Visit(cast<Decl>(D->getDeclContext()));
GenObjCProperty(D->getName());
}
-void USRGenerator::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
VisitObjCPropertyDecl(PD);
return;
@@ -387,7 +383,7 @@ void USRGenerator::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
IgnoreResults = true;
}
-void USRGenerator::VisitTagDecl(TagDecl *D) {
+void USRGenerator::VisitTagDecl(const TagDecl *D) {
// Add the location of the tag decl to handle resolution across
// translation units.
if (ShouldGenerateLocation(D) && GenLoc(D))
@@ -397,7 +393,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
VisitDeclContext(D->getDeclContext());
bool AlreadyStarted = false;
- if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
+ if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
AlreadyStarted = true;
@@ -409,7 +405,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
case TTK_Enum: llvm_unreachable("enum template");
}
VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
- } else if (ClassTemplatePartialSpecializationDecl *PartialSpec
+ } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec
= dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
AlreadyStarted = true;
@@ -449,7 +445,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
}
// For a class template specialization, mangle the template arguments.
- if (ClassTemplateSpecializationDecl *Spec
+ if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(D)) {
const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
Out << '>';
@@ -460,17 +456,17 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
}
}
-void USRGenerator::VisitTypedefDecl(TypedefDecl *D) {
+void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
if (ShouldGenerateLocation(D) && GenLoc(D))
return;
- DeclContext *DC = D->getDeclContext();
- if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
+ const DeclContext *DC = D->getDeclContext();
+ if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
Visit(DCN);
Out << "@T@";
Out << D->getName();
}
-void USRGenerator::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
GenLoc(D);
return;
}
@@ -593,6 +589,14 @@ void USRGenerator::VisitType(QualType T) {
#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:
@@ -806,7 +810,7 @@ bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) {
return true;
USRGenerator UG(&D->getASTContext(), &Buf);
- UG->Visit(const_cast<Decl*>(D));
+ UG->Visit(D);
if (UG->ignoreResults())
return true;
@@ -820,22 +824,22 @@ CXString clang_getCursorUSR(CXCursor C) {
const CXCursorKind &K = clang_getCursorKind(C);
if (clang_isDeclaration(K)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (!D)
- return createCXString("");
+ return cxstring::createEmpty();
CXTranslationUnit TU = cxcursor::getCursorTU(C);
if (!TU)
- return createCXString("");
+ return cxstring::createEmpty();
- CXStringBuf *buf = cxstring::getCXStringBuf(TU);
+ cxstring::CXStringBuf *buf = cxstring::getCXStringBuf(TU);
if (!buf)
- return createCXString("");
+ return cxstring::createEmpty();
bool Ignore = cxcursor::getDeclCursorUSR(D, buf->Data);
if (Ignore) {
- disposeCXStringBuf(buf);
- return createCXString("");
+ buf->dispose();
+ return cxstring::createEmpty();
}
// Return the C-string, but don't make a copy since it is already in
@@ -847,11 +851,11 @@ CXString clang_getCursorUSR(CXCursor C) {
if (K == CXCursor_MacroDefinition) {
CXTranslationUnit TU = cxcursor::getCursorTU(C);
if (!TU)
- return createCXString("");
+ return cxstring::createEmpty();
- CXStringBuf *buf = cxstring::getCXStringBuf(TU);
+ cxstring::CXStringBuf *buf = cxstring::getCXStringBuf(TU);
if (!buf)
- return createCXString("");
+ return cxstring::createEmpty();
{
USRGenerator UG(&cxcursor::getCursorASTUnit(C)->getASTContext(),
@@ -863,14 +867,14 @@ CXString clang_getCursorUSR(CXCursor C) {
return createCXString(buf);
}
- return createCXString("");
+ return cxstring::createEmpty();
}
CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
USRGenerator UG;
UG << extractUSRSuffix(clang_getCString(classUSR));
UG->GenObjCIvar(name);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
CXString clang_constructUSR_ObjCMethod(const char *name,
@@ -879,26 +883,26 @@ CXString clang_constructUSR_ObjCMethod(const char *name,
USRGenerator UG;
UG << extractUSRSuffix(clang_getCString(classUSR));
UG->GenObjCMethod(name, isInstanceMethod);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
CXString clang_constructUSR_ObjCClass(const char *name) {
USRGenerator UG;
UG->GenObjCClass(name);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
CXString clang_constructUSR_ObjCProtocol(const char *name) {
USRGenerator UG;
UG->GenObjCProtocol(name);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
CXString clang_constructUSR_ObjCCategory(const char *class_name,
const char *category_name) {
USRGenerator UG;
UG->GenObjCCategory(class_name, category_name);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
CXString clang_constructUSR_ObjCProperty(const char *property,
@@ -906,7 +910,7 @@ CXString clang_constructUSR_ObjCProperty(const char *property,
USRGenerator UG;
UG << extractUSRSuffix(clang_getCString(classUSR));
UG->GenObjCProperty(property);
- return createCXString(UG.str(), true);
+ return cxstring::createDup(UG.str());
}
} // end extern "C"
diff --git a/tools/libclang/CIndexer.cpp b/tools/libclang/CIndexer.cpp
index d458789..d89e0a4 100644
--- a/tools/libclang/CIndexer.cpp
+++ b/tools/libclang/CIndexer.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "CIndexer.h"
-
#include "clang/AST/Decl.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/StmtVisitor.h"
@@ -24,12 +23,11 @@
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Program.h"
-
+#include "llvm/Support/raw_ostream.h"
#include <cstdio>
-#include <vector>
#include <sstream>
+#include <vector>
#ifdef __CYGWIN__
#include <cygwin/version.h>
diff --git a/tools/libclang/CIndexer.h b/tools/libclang/CIndexer.h
index 1e5fb82..08162c5 100644
--- a/tools/libclang/CIndexer.h
+++ b/tools/libclang/CIndexer.h
@@ -26,6 +26,11 @@ namespace llvm {
namespace clang {
class ASTUnit;
+ class MacroInfo;
+ class MacroDefinition;
+ class SourceLocation;
+ class Token;
+ class IdentifierInfo;
class CIndexer {
bool OnlyLocalDecls;
@@ -33,7 +38,6 @@ class CIndexer {
unsigned Options; // CXGlobalOptFlags.
llvm::sys::Path ResourcesPath;
- std::string WorkingDir;
public:
CIndexer() : OnlyLocalDecls(false), DisplayDiagnostics(false),
@@ -59,9 +63,6 @@ public:
/// \brief Get the path of the clang resource files.
std::string getClangResourcesPath();
-
- const std::string &getWorkingDirectory() const { return WorkingDir; }
- void setWorkingDirectory(const std::string &Dir) { WorkingDir = Dir; }
};
/**
@@ -98,6 +99,30 @@ public:
namespace cxindex {
void printDiagsToStderr(ASTUnit *Unit);
+
+ /// \brief If \c MacroDefLoc points at a macro definition with \c II as
+ /// its name, this retrieves its MacroInfo.
+ MacroInfo *getMacroInfo(const IdentifierInfo &II,
+ SourceLocation MacroDefLoc,
+ CXTranslationUnit TU);
+
+ /// \brief Retrieves the corresponding MacroInfo of a MacroDefinition.
+ const MacroInfo *getMacroInfo(const MacroDefinition *MacroDef,
+ CXTranslationUnit TU);
+
+ /// \brief If \c Loc resides inside the definition of \c MI and it points at
+ /// an identifier that has ever been a macro name, this returns the latest
+ /// MacroDefinition for that name, otherwise it returns NULL.
+ MacroDefinition *checkForMacroInMacroDefinition(const MacroInfo *MI,
+ SourceLocation Loc,
+ CXTranslationUnit TU);
+
+ /// \brief If \c Tok resides inside the definition of \c MI and it points at
+ /// an identifier that has ever been a macro name, this returns the latest
+ /// MacroDefinition for that name, otherwise it returns NULL.
+ MacroDefinition *checkForMacroInMacroDefinition(const MacroInfo *MI,
+ const Token &Tok,
+ CXTranslationUnit TU);
}
}
diff --git a/tools/libclang/CLog.h b/tools/libclang/CLog.h
new file mode 100644
index 0000000..57e01ae
--- /dev/null
+++ b/tools/libclang/CLog.h
@@ -0,0 +1,101 @@
+//===- CLog.h - Logging Interface -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBCLANG_CLOG_H
+#define LLVM_LIBCLANG_CLOG_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+
+namespace llvm {
+class format_object_base;
+}
+
+namespace clang {
+ class FileEntry;
+
+namespace cxindex {
+
+class Logger;
+typedef IntrusiveRefCntPtr<Logger> LogRef;
+
+/// \brief Collects logging output and writes it to stderr when it's destructed.
+/// Common use case:
+/// \code
+/// if (LogRef Log = Logger::make(__func__)) {
+/// *Log << "stuff";
+/// }
+/// \endcode
+class Logger : public RefCountedBase<Logger> {
+ std::string Name;
+ bool Trace;
+ SmallString<64> Msg;
+ llvm::raw_svector_ostream LogOS;
+public:
+ static const char *getEnvVar() {
+ static const char *sCachedVar = ::getenv("LIBCLANG_LOGGING");
+ return sCachedVar;
+ }
+ static bool isLoggingEnabled() { return getEnvVar() != 0; }
+ static bool isStackTracingEnabled() {
+ if (const char *EnvOpt = Logger::getEnvVar())
+ return llvm::StringRef(EnvOpt) == "2";
+ return false;
+ }
+ static LogRef make(llvm::StringRef name,
+ bool trace = isStackTracingEnabled()) {
+ if (isLoggingEnabled())
+ return new Logger(name, trace);
+ return 0;
+ }
+
+ explicit Logger(llvm::StringRef name, bool trace)
+ : Name(name), Trace(trace), LogOS(Msg) { }
+ ~Logger();
+
+ Logger &operator<<(CXTranslationUnit);
+ Logger &operator<<(const FileEntry *FE);
+ Logger &operator<<(CXCursor cursor);
+ Logger &operator<<(CXSourceLocation);
+ Logger &operator<<(CXSourceRange);
+ Logger &operator<<(CXString);
+ Logger &operator<<(llvm::StringRef Str) { LogOS << Str; return *this; }
+ Logger &operator<<(const char *Str) {
+ if (Str)
+ LogOS << Str;
+ return *this;
+ }
+ Logger &operator<<(unsigned long N) { LogOS << N; return *this; }
+ Logger &operator<<(long N) { LogOS << N ; return *this; }
+ Logger &operator<<(unsigned int N) { LogOS << N; return *this; }
+ Logger &operator<<(int N) { LogOS << N; return *this; }
+ Logger &operator<<(char C) { LogOS << C; return *this; }
+ Logger &operator<<(unsigned char C) { LogOS << C; return *this; }
+ Logger &operator<<(signed char C) { LogOS << C; return *this; }
+ Logger &operator<<(const llvm::format_object_base &Fmt);
+};
+
+}
+}
+
+/// \brief Macros to automate common uses of Logger. Like this:
+/// \code
+/// LOG_FUNC_SECTION {
+/// *Log << "blah";
+/// }
+/// \endcode
+#define LOG_SECTION(NAME) if (LogRef Log = clang::cxindex::Logger::make(NAME))
+#define LOG_FUNC_SECTION LOG_SECTION(LLVM_FUNCTION_NAME)
+
+#endif
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index 1426c42..c5a975b 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
asmparser
support
+ bitreader
mc
)
@@ -38,6 +39,7 @@ set(SOURCES
Indexing.cpp
IndexingContext.cpp
IndexingContext.h
+ SimpleFormatContext.h
../../include/clang-c/Index.h
)
@@ -54,6 +56,7 @@ set(LIBRARIES
clangLex
clangTooling
clangBasic
+ clangFormat
)
set(GENERATED_HEADERS
@@ -71,7 +74,7 @@ if( LLVM_ENABLE_PIC )
set(SHARED_LIBRARY TRUE)
add_clang_library(libclang ${SOURCES})
target_link_libraries(libclang ${LIBRARIES})
- add_dependencies(libclang ${GENERATED_HEADERS})
+ add_dependencies(libclang ${GENERATED_HEADERS} clang-headers)
if(WIN32)
set_target_properties(libclang
@@ -105,7 +108,7 @@ endif()
if( NOT BUILD_SHARED_LIBS 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})
+ add_dependencies(${LIBCLANG_STATIC_TARGET_NAME} ${GENERATED_HEADERS} clang-headers)
set_target_properties(${LIBCLANG_STATIC_TARGET_NAME}
PROPERTIES
diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp
index fa149a0..1c127e1 100644
--- a/tools/libclang/CXComment.cpp
+++ b/tools/libclang/CXComment.cpp
@@ -12,23 +12,23 @@
//===----------------------------------------------------------------------===//
#include "clang-c/Index.h"
-#include "CXString.h"
#include "CXComment.h"
#include "CXCursor.h"
-
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/CommentVisitor.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 "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;
-using namespace clang::cxstring;
using namespace clang::comments;
using namespace clang::cxcomment;
@@ -123,18 +123,18 @@ unsigned clang_InlineContentComment_hasTrailingNewline(CXComment CXC) {
CXString clang_TextComment_getText(CXComment CXC) {
const TextComment *TC = getASTNodeAs<TextComment>(CXC);
if (!TC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(TC->getText(), /*DupString=*/ false);
+ return cxstring::createRef(TC->getText());
}
CXString clang_InlineCommandComment_getCommandName(CXComment CXC) {
const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
if (!ICC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
const CommandTraits &Traits = getCommandTraits(CXC);
- return createCXString(ICC->getCommandName(Traits), /*DupString=*/ false);
+ return cxstring::createRef(ICC->getCommandName(Traits));
}
enum CXCommentInlineCommandRenderKind
@@ -171,17 +171,17 @@ CXString clang_InlineCommandComment_getArgText(CXComment CXC,
unsigned ArgIdx) {
const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
if (!ICC || ArgIdx >= ICC->getNumArgs())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(ICC->getArgText(ArgIdx), /*DupString=*/ false);
+ return cxstring::createRef(ICC->getArgText(ArgIdx));
}
CXString clang_HTMLTagComment_getTagName(CXComment CXC) {
const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
if (!HTC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(HTC->getTagName(), /*DupString=*/ false);
+ return cxstring::createRef(HTC->getTagName());
}
unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment CXC) {
@@ -203,26 +203,26 @@ unsigned clang_HTMLStartTag_getNumAttrs(CXComment CXC) {
CXString clang_HTMLStartTag_getAttrName(CXComment CXC, unsigned AttrIdx) {
const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
if (!HST || AttrIdx >= HST->getNumAttrs())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(HST->getAttr(AttrIdx).Name, /*DupString=*/ false);
+ return cxstring::createRef(HST->getAttr(AttrIdx).Name);
}
CXString clang_HTMLStartTag_getAttrValue(CXComment CXC, unsigned AttrIdx) {
const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
if (!HST || AttrIdx >= HST->getNumAttrs())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(HST->getAttr(AttrIdx).Value, /*DupString=*/ false);
+ return cxstring::createRef(HST->getAttr(AttrIdx).Value);
}
CXString clang_BlockCommandComment_getCommandName(CXComment CXC) {
const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
if (!BCC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
const CommandTraits &Traits = getCommandTraits(CXC);
- return createCXString(BCC->getCommandName(Traits), /*DupString=*/ false);
+ return cxstring::createRef(BCC->getCommandName(Traits));
}
unsigned clang_BlockCommandComment_getNumArgs(CXComment CXC) {
@@ -237,9 +237,9 @@ CXString clang_BlockCommandComment_getArgText(CXComment CXC,
unsigned ArgIdx) {
const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
if (!BCC || ArgIdx >= BCC->getNumArgs())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(BCC->getArgText(ArgIdx), /*DupString=*/ false);
+ return cxstring::createRef(BCC->getArgText(ArgIdx));
}
CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
@@ -253,9 +253,9 @@ CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
CXString clang_ParamCommandComment_getParamName(CXComment CXC) {
const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
if (!PCC || !PCC->hasParamName())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(PCC->getParamNameAsWritten(), /*DupString=*/ false);
+ return cxstring::createRef(PCC->getParamNameAsWritten());
}
unsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) {
@@ -304,9 +304,9 @@ enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
CXString clang_TParamCommandComment_getParamName(CXComment CXC) {
const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
if (!TPCC || !TPCC->hasParamName())
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(TPCC->getParamNameAsWritten(), /*DupString=*/ false);
+ return cxstring::createRef(TPCC->getParamNameAsWritten());
}
unsigned clang_TParamCommandComment_isParamPositionValid(CXComment CXC) {
@@ -337,17 +337,17 @@ CXString clang_VerbatimBlockLineComment_getText(CXComment CXC) {
const VerbatimBlockLineComment *VBL =
getASTNodeAs<VerbatimBlockLineComment>(CXC);
if (!VBL)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(VBL->getText(), /*DupString=*/ false);
+ return cxstring::createRef(VBL->getText());
}
CXString clang_VerbatimLineComment_getText(CXComment CXC) {
const VerbatimLineComment *VLC = getASTNodeAs<VerbatimLineComment>(CXC);
if (!VLC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
- return createCXString(VLC->getText(), /*DupString=*/ false);
+ return cxstring::createRef(VLC->getText());
}
} // end extern "C"
@@ -410,6 +410,7 @@ struct FullCommentParts {
const CommandTraits &Traits);
const BlockContentComment *Brief;
+ const BlockContentComment *Headerfile;
const ParagraphComment *FirstParagraph;
const BlockCommandComment *Returns;
SmallVector<const ParamCommandComment *, 8> Params;
@@ -419,7 +420,7 @@ struct FullCommentParts {
FullCommentParts::FullCommentParts(const FullComment *C,
const CommandTraits &Traits) :
- Brief(NULL), FirstParagraph(NULL), Returns(NULL) {
+ 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;
@@ -447,6 +448,10 @@ FullCommentParts::FullCommentParts(const FullComment *C,
Brief = BCC;
break;
}
+ if (!Headerfile && Info->IsHeaderfileCommand) {
+ Headerfile = BCC;
+ break;
+ }
if (!Returns && Info->IsReturnsCommand) {
Returns = BCC;
break;
@@ -749,6 +754,8 @@ 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) {
@@ -830,23 +837,23 @@ extern "C" {
CXString clang_HTMLTagComment_getAsString(CXComment CXC) {
const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
if (!HTC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
SmallString<128> HTML;
CommentASTToHTMLConverter Converter(0, HTML, getCommandTraits(CXC));
Converter.visit(HTC);
- return createCXString(HTML.str(), /* DupString = */ true);
+ return cxstring::createDup(HTML.str());
}
CXString clang_FullComment_getAsHTML(CXComment CXC) {
const FullComment *FC = getASTNodeAs<FullComment>(CXC);
if (!FC)
- return createCXString((const char *) 0);
+ return cxstring::createNull();
SmallString<1024> HTML;
CommentASTToHTMLConverter Converter(FC, HTML, getCommandTraits(CXC));
Converter.visit(FC);
- return createCXString(HTML.str(), /* DupString = */ true);
+ return cxstring::createDup(HTML.str());
}
} // end extern "C"
@@ -859,8 +866,12 @@ public:
CommentASTToXMLConverter(const FullComment *FC,
SmallVectorImpl<char> &Str,
const CommandTraits &Traits,
- const SourceManager &SM) :
- FC(FC), Result(Str), Traits(Traits), SM(SM) { }
+ 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);
@@ -870,6 +881,10 @@ public:
// 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);
@@ -882,6 +897,9 @@ public:
// Helpers.
void appendToResultWithXMLEscaping(StringRef S);
+ void formatTextOfDeclaration(const DeclInfo *DI,
+ SmallString<128> &Declaration);
+
private:
const FullComment *FC;
@@ -890,6 +908,8 @@ private:
const CommandTraits &Traits;
const SourceManager &SM;
+ SimpleFormatContext &FormatRewriterContext;
+ unsigned FormatInMemoryUniqueId;
};
void getSourceTextOfDeclaration(const DeclInfo *ThisDecl,
@@ -898,10 +918,40 @@ void getSourceTextOfDeclaration(const DeclInfo *ThisDecl,
const LangOptions &LangOpts = Context.getLangOpts();
llvm::raw_svector_ostream OS(Str);
PrintingPolicy PPolicy(LangOpts);
- PPolicy.SuppressAttributes = true;
+ PPolicy.PolishForDeclaration = true;
PPolicy.TerseOutput = true;
ThisDecl->CurrentDecl->print(OS, PPolicy,
- /*Indentation*/0, /*PrintInstantiation*/true);
+ /*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
@@ -959,10 +1009,20 @@ void CommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C
}
void CommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C) {
+ appendParagraphCommentWithKind(C, StringRef());
+}
+
+void CommentASTToXMLConverter::appendParagraphCommentWithKind(
+ const ParagraphComment *C,
+ StringRef ParagraphKind) {
if (C->isWhitespace())
return;
- Result << "<Para>";
+ 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);
@@ -971,7 +1031,33 @@ void CommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C)
}
void CommentASTToXMLConverter::visitBlockCommandComment(const BlockCommandComment *C) {
- visit(C->getParagraph());
+ 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) {
@@ -1022,9 +1108,14 @@ void CommentASTToXMLConverter::visitVerbatimBlockComment(
if (NumLines == 0)
return;
- Result << llvm::StringSwitch<const char *>(C->getCommandName(Traits))
- .Case("code", "<Verbatim xml:space=\"preserve\" kind=\"code\">")
- .Default("<Verbatim xml:space=\"preserve\" kind=\"verbatim\">");
+ 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)
@@ -1162,13 +1253,21 @@ void CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
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>";
}
@@ -1183,7 +1282,7 @@ void CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
Result << "</Abstract>";
FirstParagraphIsBrief = true;
}
-
+
if (Parts.TParams.size() != 0) {
Result << "<TemplateParameters>";
for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
@@ -1322,15 +1421,26 @@ extern "C" {
CXString clang_FullComment_getAsXML(CXComment CXC) {
const FullComment *FC = getASTNodeAs<FullComment>(CXC);
if (!FC)
- return createCXString((const char *) 0);
-
+ return cxstring::createNull();
+ ASTContext &Context = FC->getDeclInfo()->CurrentDecl->getASTContext();
CXTranslationUnit TU = CXC.TranslationUnit;
- SourceManager &SM = static_cast<ASTUnit *>(TU->TUData)->getSourceManager();
+ 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());
+ }
SmallString<1024> XML;
- CommentASTToXMLConverter Converter(FC, XML, getCommandTraits(CXC), SM);
+ CommentASTToXMLConverter Converter(FC, XML, getCommandTraits(CXC), SM,
+ *TU->FormatContext,
+ TU->FormatInMemoryUniqueId++);
Converter.visit(FC);
- return createCXString(XML.str(), /* DupString = */ true);
+ return cxstring::createDup(XML.str());
}
} // end extern "C"
diff --git a/tools/libclang/CXComment.h b/tools/libclang/CXComment.h
index 5134317..0780a65 100644
--- a/tools/libclang/CXComment.h
+++ b/tools/libclang/CXComment.h
@@ -14,11 +14,10 @@
#ifndef LLVM_CLANG_CXCOMMENT_H
#define LLVM_CLANG_CXCOMMENT_H
-#include "clang-c/Index.h"
#include "CXTranslationUnit.h"
-
-#include "clang/AST/Comment.h"
+#include "clang-c/Index.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Comment.h"
#include "clang/Frontend/ASTUnit.h"
namespace clang {
@@ -50,7 +49,7 @@ inline const T *getASTNodeAs(CXComment CXC) {
}
inline ASTContext &getASTContext(CXComment CXC) {
- return static_cast<ASTUnit *>(CXC.TranslationUnit->TUData)->getASTContext();
+ return cxtu::getASTUnit(CXC.TranslationUnit)->getASTContext();
}
inline comments::CommandTraits &getCommandTraits(CXComment CXC) {
diff --git a/tools/libclang/CXCompilationDatabase.cpp b/tools/libclang/CXCompilationDatabase.cpp
index 7bd319a..e35ac27 100644
--- a/tools/libclang/CXCompilationDatabase.cpp
+++ b/tools/libclang/CXCompilationDatabase.cpp
@@ -1,10 +1,9 @@
#include "clang-c/CXCompilationDatabase.h"
-#include "clang/Tooling/CompilationDatabase.h"
#include "CXString.h"
+#include "clang/Tooling/CompilationDatabase.h"
using namespace clang;
using namespace clang::tooling;
-using namespace clang::cxstring;
extern "C" {
@@ -59,6 +58,17 @@ clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb,
return 0;
}
+CXCompileCommands
+clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
+ if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
+ const std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
+ if (!CCmd.empty())
+ return new AllocatedCXCompileCommands( CCmd );
+ }
+
+ return 0;
+}
+
void
clang_CompileCommands_dispose(CXCompileCommands Cmds)
{
@@ -96,10 +106,10 @@ CXString
clang_CompileCommand_getDirectory(CXCompileCommand CCmd)
{
if (!CCmd)
- return createCXString((const char*)NULL);
+ return cxstring::createNull();
CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
- return createCXString(cmd->Directory);
+ return cxstring::createRef(cmd->Directory.c_str());
}
unsigned
@@ -115,14 +125,14 @@ CXString
clang_CompileCommand_getArg(CXCompileCommand CCmd, unsigned Arg)
{
if (!CCmd)
- return createCXString((const char*)NULL);
+ return cxstring::createNull();
CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
if (Arg >= Cmd->CommandLine.size())
- return createCXString((const char*)NULL);
+ return cxstring::createNull();
- return createCXString(Cmd->CommandLine[Arg]);
+ return cxstring::createRef(Cmd->CommandLine[Arg].c_str());
}
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index 8d3e169..7b01ec2 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -15,9 +15,9 @@
#include "CXTranslationUnit.h"
#include "CXCursor.h"
-#include "CXType.h"
#include "CXString.h"
-#include "clang/Frontend/ASTUnit.h"
+#include "CXType.h"
+#include "clang-c/Index.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
@@ -25,7 +25,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
-#include "clang-c/Index.h"
+#include "clang/Frontend/ASTUnit.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
@@ -53,14 +53,14 @@ static CXCursorKind GetCursorKind(const Attr *A) {
return CXCursor_UnexposedAttr;
}
-CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent,
+CXCursor cxcursor::MakeCXCursor(const Attr *A, const Decl *Parent,
CXTranslationUnit TU) {
assert(A && Parent && TU && "Invalid arguments!");
- CXCursor C = { GetCursorKind(A), 0, { Parent, (void*)A, TU } };
+ CXCursor C = { GetCursorKind(A), 0, { Parent, A, TU } };
return C;
}
-CXCursor cxcursor::MakeCXCursor(Decl *D, CXTranslationUnit TU,
+CXCursor cxcursor::MakeCXCursor(const Decl *D, CXTranslationUnit TU,
SourceRange RegionOfInterest,
bool FirstInDeclGroup) {
assert(D && TU && "Invalid arguments!");
@@ -89,7 +89,8 @@ CXCursor cxcursor::MakeCXCursor(Decl *D, CXTranslationUnit TU,
return C;
}
-CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, CXTranslationUnit TU,
+CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
+ CXTranslationUnit TU,
SourceRange RegionOfInterest) {
assert(S && TU && "Invalid arguments!");
CXCursorKind K = CXCursor_NotImplemented;
@@ -493,34 +494,32 @@ CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
SourceLocation Loc,
CXTranslationUnit TU) {
assert(Super && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+ void *RawLoc = Loc.getPtrEncoding();
CXCursor C = { CXCursor_ObjCSuperClassRef, 0, { Super, RawLoc, TU } };
return C;
}
-std::pair<ObjCInterfaceDecl *, SourceLocation>
+std::pair<const ObjCInterfaceDecl *, SourceLocation>
cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
assert(C.kind == CXCursor_ObjCSuperClassRef);
- return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const ObjCInterfaceDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
SourceLocation Loc,
CXTranslationUnit TU) {
assert(Proto && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_ObjCProtocolRef, 0, { (void*)Proto, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_ObjCProtocolRef, 0, { Proto, RawLoc, TU } };
return C;
}
-std::pair<ObjCProtocolDecl *, SourceLocation>
+std::pair<const ObjCProtocolDecl *, SourceLocation>
cxcursor::getCursorObjCProtocolRef(CXCursor C) {
assert(C.kind == CXCursor_ObjCProtocolRef);
- return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const ObjCProtocolDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
@@ -530,50 +529,47 @@ CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
if (!Class)
return MakeCXCursorInvalid(CXCursor_InvalidCode);
assert(TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_ObjCClassRef, 0, { (void*)Class, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_ObjCClassRef, 0, { Class, RawLoc, TU } };
return C;
}
-std::pair<ObjCInterfaceDecl *, SourceLocation>
+std::pair<const ObjCInterfaceDecl *, SourceLocation>
cxcursor::getCursorObjCClassRef(CXCursor C) {
assert(C.kind == CXCursor_ObjCClassRef);
- return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const ObjCInterfaceDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
CXTranslationUnit TU) {
assert(Type && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_TypeRef, 0, { (void*)Type, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_TypeRef, 0, { Type, RawLoc, TU } };
return C;
}
-std::pair<TypeDecl *, SourceLocation>
+std::pair<const TypeDecl *, SourceLocation>
cxcursor::getCursorTypeRef(CXCursor C) {
assert(C.kind == CXCursor_TypeRef);
- return std::make_pair(static_cast<TypeDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const TypeDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorTemplateRef(const TemplateDecl *Template,
SourceLocation Loc,
CXTranslationUnit TU) {
assert(Template && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_TemplateRef, 0, { (void*)Template, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_TemplateRef, 0, { Template, RawLoc, TU } };
return C;
}
-std::pair<TemplateDecl *, SourceLocation>
+std::pair<const TemplateDecl *, SourceLocation>
cxcursor::getCursorTemplateRef(CXCursor C) {
assert(C.kind == CXCursor_TemplateRef);
- return std::make_pair(static_cast<TemplateDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const TemplateDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorNamespaceRef(const NamedDecl *NS,
@@ -582,69 +578,66 @@ CXCursor cxcursor::MakeCursorNamespaceRef(const NamedDecl *NS,
assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
"Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_NamespaceRef, 0, { (void*)NS, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_NamespaceRef, 0, { NS, RawLoc, TU } };
return C;
}
-std::pair<NamedDecl *, SourceLocation>
+std::pair<const NamedDecl *, SourceLocation>
cxcursor::getCursorNamespaceRef(CXCursor C) {
assert(C.kind == CXCursor_NamespaceRef);
- return std::make_pair(static_cast<NamedDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const NamedDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
CXTranslationUnit TU) {
assert(Var && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_VariableRef, 0, { (void*)Var, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_VariableRef, 0, { Var, RawLoc, TU } };
return C;
}
-std::pair<VarDecl *, SourceLocation>
+std::pair<const VarDecl *, SourceLocation>
cxcursor::getCursorVariableRef(CXCursor C) {
assert(C.kind == CXCursor_VariableRef);
- return std::make_pair(static_cast<VarDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const VarDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
CXTranslationUnit TU) {
assert(Field && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_MemberRef, 0, { (void*)Field, RawLoc, TU } };
+ void *RawLoc = Loc.getPtrEncoding();
+ CXCursor C = { CXCursor_MemberRef, 0, { Field, RawLoc, TU } };
return C;
}
-std::pair<FieldDecl *, SourceLocation>
+std::pair<const FieldDecl *, SourceLocation>
cxcursor::getCursorMemberRef(CXCursor C) {
assert(C.kind == CXCursor_MemberRef);
- return std::make_pair(static_cast<FieldDecl *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const FieldDecl *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
CXCursor cxcursor::MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
CXTranslationUnit TU){
- CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { (void*)B, 0, TU } };
+ CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { B, 0, TU } };
return C;
}
-CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
+const CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
assert(C.kind == CXCursor_CXXBaseSpecifier);
- return static_cast<CXXBaseSpecifier*>(C.data[0]);
+ return static_cast<const CXXBaseSpecifier*>(C.data[0]);
}
CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
CXTranslationUnit TU) {
CXCursor C = { CXCursor_PreprocessingDirective, 0,
- { reinterpret_cast<void *>(Range.getBegin().getRawEncoding()),
- reinterpret_cast<void *>(Range.getEnd().getRawEncoding()),
+ { Range.getBegin().getPtrEncoding(),
+ Range.getEnd().getPtrEncoding(),
TU }
};
return C;
@@ -652,23 +645,21 @@ CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
assert(C.kind == CXCursor_PreprocessingDirective);
- SourceRange Range = SourceRange(SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t> (C.data[0])),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t> (C.data[1])));
+ SourceRange Range(SourceLocation::getFromPtrEncoding(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
ASTUnit *TU = getCursorASTUnit(C);
return TU->mapRangeFromPreamble(Range);
}
-CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI,
+CXCursor cxcursor::MakeMacroDefinitionCursor(const MacroDefinition *MI,
CXTranslationUnit TU) {
CXCursor C = { CXCursor_MacroDefinition, 0, { MI, 0, TU } };
return C;
}
-MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
+const MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
assert(C.kind == CXCursor_MacroDefinition);
- return static_cast<MacroDefinition *>(C.data[0]);
+ return static_cast<const MacroDefinition *>(C.data[0]);
}
CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
@@ -677,9 +668,28 @@ CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
return C;
}
-MacroExpansion *cxcursor::getCursorMacroExpansion(CXCursor C) {
- assert(C.kind == CXCursor_MacroExpansion);
- return static_cast<MacroExpansion *>(C.data[0]);
+CXCursor cxcursor::MakeMacroExpansionCursor(MacroDefinition *MI,
+ SourceLocation Loc,
+ CXTranslationUnit TU) {
+ assert(Loc.isValid());
+ CXCursor C = { CXCursor_MacroExpansion, 0, { MI, Loc.getPtrEncoding(), TU } };
+ return C;
+}
+
+const IdentifierInfo *cxcursor::MacroExpansionCursor::getName() const {
+ if (isPseudo())
+ return getAsMacroDefinition()->getName();
+ return getAsMacroExpansion()->getName();
+}
+const MacroDefinition *cxcursor::MacroExpansionCursor::getDefinition() const {
+ if (isPseudo())
+ return getAsMacroDefinition();
+ return getAsMacroExpansion()->getDefinition();
+}
+SourceRange cxcursor::MacroExpansionCursor::getSourceRange() const {
+ if (isPseudo())
+ return getPseudoLoc();
+ return getAsMacroExpansion()->getSourceRange();
}
CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
@@ -688,33 +698,32 @@ CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
return C;
}
-InclusionDirective *cxcursor::getCursorInclusionDirective(CXCursor C) {
+const InclusionDirective *cxcursor::getCursorInclusionDirective(CXCursor C) {
assert(C.kind == CXCursor_InclusionDirective);
- return static_cast<InclusionDirective *>(C.data[0]);
+ return static_cast<const InclusionDirective *>(C.data[0]);
}
CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
CXTranslationUnit TU) {
assert(Label && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+ void *RawLoc = Loc.getPtrEncoding();
CXCursor C = { CXCursor_LabelRef, 0, { Label, RawLoc, TU } };
return C;
}
-std::pair<LabelStmt*, SourceLocation>
+std::pair<const LabelStmt *, SourceLocation>
cxcursor::getCursorLabelRef(CXCursor C) {
assert(C.kind == CXCursor_LabelRef);
- return std::make_pair(static_cast<LabelStmt *>(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(static_cast<const LabelStmt *>(C.data[0]),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
-CXCursor cxcursor::MakeCursorOverloadedDeclRef(OverloadExpr *E,
+CXCursor cxcursor::MakeCursorOverloadedDeclRef(const OverloadExpr *E,
CXTranslationUnit TU) {
assert(E && TU && "Invalid arguments!");
OverloadedDeclRefStorage Storage(E);
- void *RawLoc = reinterpret_cast<void *>(E->getNameLoc().getRawEncoding());
+ void *RawLoc = E->getNameLoc().getPtrEncoding();
CXCursor C = {
CXCursor_OverloadedDeclRef, 0,
{ Storage.getOpaqueValue(), RawLoc, TU }
@@ -722,11 +731,11 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(OverloadExpr *E,
return C;
}
-CXCursor cxcursor::MakeCursorOverloadedDeclRef(Decl *D,
+CXCursor cxcursor::MakeCursorOverloadedDeclRef(const Decl *D,
SourceLocation Loc,
CXTranslationUnit TU) {
assert(D && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+ void *RawLoc = Loc.getPtrEncoding();
OverloadedDeclRefStorage Storage(D);
CXCursor C = {
CXCursor_OverloadedDeclRef, 0,
@@ -739,7 +748,7 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
SourceLocation Loc,
CXTranslationUnit TU) {
assert(Name.getAsOverloadedTemplate() && TU && "Invalid arguments!");
- void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+ void *RawLoc = Loc.getPtrEncoding();
OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
CXCursor C = {
CXCursor_OverloadedDeclRef, 0,
@@ -751,34 +760,34 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
std::pair<cxcursor::OverloadedDeclRefStorage, SourceLocation>
cxcursor::getCursorOverloadedDeclRef(CXCursor C) {
assert(C.kind == CXCursor_OverloadedDeclRef);
- return std::make_pair(OverloadedDeclRefStorage::getFromOpaqueValue(C.data[0]),
- SourceLocation::getFromRawEncoding(
- reinterpret_cast<uintptr_t>(C.data[1])));
+ return std::make_pair(OverloadedDeclRefStorage::getFromOpaqueValue(
+ const_cast<void *>(C.data[0])),
+ SourceLocation::getFromPtrEncoding(C.data[1]));
}
-Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
- return (Decl *)Cursor.data[0];
+const Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
+ return static_cast<const Decl *>(Cursor.data[0]);
}
-Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
+const Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
}
-Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
+const Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
Cursor.kind == CXCursor_ObjCProtocolRef ||
Cursor.kind == CXCursor_ObjCClassRef)
return 0;
- return (Stmt *)Cursor.data[1];
+ return static_cast<const Stmt *>(Cursor.data[1]);
}
-Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
- return (Attr *)Cursor.data[1];
+const Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
+ return static_cast<const Attr *>(Cursor.data[1]);
}
-Decl *cxcursor::getCursorParentDecl(CXCursor Cursor) {
- return (Decl *)Cursor.data[0];
+const Decl *cxcursor::getCursorParentDecl(CXCursor Cursor) {
+ return static_cast<const Decl *>(Cursor.data[0]);
}
ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
@@ -786,14 +795,14 @@ ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
}
ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
- CXTranslationUnit TU = static_cast<CXTranslationUnit>(Cursor.data[2]);
+ CXTranslationUnit TU = getCursorTU(Cursor);
if (!TU)
return 0;
- return static_cast<ASTUnit *>(TU->TUData);
+ return cxtu::getASTUnit(TU);
}
CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
- return static_cast<CXTranslationUnit>(Cursor.data[2]);
+ return static_cast<CXTranslationUnit>(const_cast<void*>(Cursor.data[2]));
}
void cxcursor::getOverriddenCursors(CXCursor cursor,
@@ -809,7 +818,7 @@ void cxcursor::getOverriddenCursors(CXCursor cursor,
for (SmallVector<const NamedDecl *, 8>::iterator
I = OverDecls.begin(), E = OverDecls.end(); I != E; ++I) {
- overridden.push_back(MakeCXCursor(const_cast<NamedDecl*>(*I), TU));
+ overridden.push_back(MakeCXCursor(*I, TU));
}
}
@@ -861,12 +870,13 @@ CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
if (cursor.xdata == 0)
return cursor;
- Expr *E = getCursorExpr(cursor);
+ const Expr *E = getCursorExpr(cursor);
TypeSourceInfo *Type = 0;
- if (CXXUnresolvedConstructExpr *
+ if (const CXXUnresolvedConstructExpr *
UnCtor = dyn_cast<CXXUnresolvedConstructExpr>(E)) {
Type = UnCtor->getTypeSourceInfo();
- } else if (CXXTemporaryObjectExpr *Tmp = dyn_cast<CXXTemporaryObjectExpr>(E)){
+ } else if (const CXXTemporaryObjectExpr *Tmp =
+ dyn_cast<CXXTemporaryObjectExpr>(E)){
Type = Tmp->getTypeSourceInfo();
}
@@ -880,7 +890,7 @@ CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
if (const ElaboratedType *ElabT = Ty->getAs<ElaboratedType>()) {
Ty = ElabT->getNamedType();
- ElaboratedTypeLoc ElabTL = cast<ElaboratedTypeLoc>(TL);
+ ElaboratedTypeLoc ElabTL = TL.castAs<ElaboratedTypeLoc>();
Loc = ElabTL.getNamedTypeLoc().getBeginLoc();
}
@@ -922,30 +932,48 @@ CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
int clang_Cursor_getNumArguments(CXCursor C) {
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
return MD->param_size();
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
return FD->param_size();
}
+ if (clang_isExpression(C.kind)) {
+ const Expr *E = cxcursor::getCursorExpr(C);
+ if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+ return CE->getNumArgs();
+ }
+ }
+
return -1;
}
CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) {
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
- if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
+ const Decl *D = cxcursor::getCursorDecl(C);
+ if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
if (i < MD->param_size())
return cxcursor::MakeCXCursor(MD->param_begin()[i],
cxcursor::getCursorTU(C));
- } else if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+ } else if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
if (i < FD->param_size())
return cxcursor::MakeCXCursor(FD->param_begin()[i],
cxcursor::getCursorTU(C));
}
}
+ if (clang_isExpression(C.kind)) {
+ const Expr *E = cxcursor::getCursorExpr(C);
+ if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+ if (i < CE->getNumArgs()) {
+ return cxcursor::MakeCXCursor(CE->getArg(i),
+ getCursorDecl(C),
+ cxcursor::getCursorTU(C));
+ }
+ }
+ }
+
return clang_getNullCursor();
}
@@ -973,7 +1001,7 @@ public:
return MakeCXCursorInvalid(CXCursor_NoDeclFound);
}
static inline unsigned getHashValue(const CXCursor &cursor) {
- return llvm::DenseMapInfo<std::pair<void*,void*> >
+ return llvm::DenseMapInfo<std::pair<const void *, const void *> >
::getHashValue(std::make_pair(cursor.data[0], cursor.data[1]));
}
static inline bool isEqual(const CXCursor &x, const CXCursor &y) {
@@ -1018,10 +1046,10 @@ unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) {
CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
enum CXCursorKind kind = clang_getCursorKind(cursor);
if (clang_isDeclaration(kind)) {
- Decl *decl = getCursorDecl(cursor);
- if (NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
+ const Decl *decl = getCursorDecl(cursor);
+ if (const NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
ASTUnit *unit = getCursorASTUnit(cursor);
- CodeCompletionResult Result(namedDecl);
+ CodeCompletionResult Result(namedDecl, CCP_Declaration);
CodeCompletionString *String
= Result.CreateCodeCompletionString(unit->getASTContext(),
unit->getPreprocessor(),
@@ -1032,10 +1060,10 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
}
}
else if (kind == CXCursor_MacroDefinition) {
- MacroDefinition *definition = getCursorMacroDefinition(cursor);
+ const MacroDefinition *definition = getCursorMacroDefinition(cursor);
const IdentifierInfo *MacroInfo = definition->getName();
ASTUnit *unit = getCursorASTUnit(cursor);
- CodeCompletionResult Result(const_cast<IdentifierInfo *>(MacroInfo));
+ CodeCompletionResult Result(MacroInfo);
CodeCompletionString *String
= Result.CreateCodeCompletionString(unit->getASTContext(),
unit->getPreprocessor(),
@@ -1050,7 +1078,7 @@ CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
namespace {
struct OverridenCursorsPool {
- typedef llvm::SmallVector<CXCursor, 2> CursorVec;
+ typedef SmallVector<CXCursor, 2> CursorVec;
std::vector<CursorVec*> AllCursors;
std::vector<CursorVec*> AvailableCursors;
@@ -1137,7 +1165,8 @@ void clang_disposeOverriddenCursors(CXCursor *overridden) {
// which has a back-reference to the TU and the vector.
--overridden;
OverridenCursorsPool::CursorVec *Vec =
- static_cast<OverridenCursorsPool::CursorVec*>(overridden->data[0]);
+ static_cast<OverridenCursorsPool::CursorVec *>(
+ const_cast<void *>(overridden->data[0]));
CXTranslationUnit TU = getCursorTU(*overridden);
assert(Vec && TU);
diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h
index 120b881..957d519 100644
--- a/tools/libclang/CXCursor.h
+++ b/tools/libclang/CXCursor.h
@@ -42,17 +42,18 @@ class TemplateDecl;
class TemplateName;
class TypeDecl;
class VarDecl;
+class IdentifierInfo;
namespace cxcursor {
CXCursor getCursor(CXTranslationUnit, SourceLocation);
-CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent,
+CXCursor MakeCXCursor(const clang::Attr *A, const clang::Decl *Parent,
CXTranslationUnit TU);
-CXCursor MakeCXCursor(clang::Decl *D, CXTranslationUnit TU,
+CXCursor MakeCXCursor(const clang::Decl *D, CXTranslationUnit TU,
SourceRange RegionOfInterest = SourceRange(),
bool FirstInDeclGroup = true);
-CXCursor MakeCXCursor(clang::Stmt *S, clang::Decl *Parent,
+CXCursor MakeCXCursor(const clang::Stmt *S, const clang::Decl *Parent,
CXTranslationUnit TU,
SourceRange RegionOfInterest = SourceRange());
CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = 0);
@@ -64,7 +65,7 @@ CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
/// \brief Unpack an ObjCSuperClassRef cursor into the interface it references
/// and optionally the location where the reference occurred.
-std::pair<ObjCInterfaceDecl *, SourceLocation>
+std::pair<const ObjCInterfaceDecl *, SourceLocation>
getCursorObjCSuperClassRef(CXCursor C);
/// \brief Create an Objective-C protocol reference at the given location.
@@ -74,7 +75,7 @@ CXCursor MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
/// \brief Unpack an ObjCProtocolRef cursor into the protocol it references
/// and optionally the location where the reference occurred.
-std::pair<ObjCProtocolDecl *, SourceLocation>
+std::pair<const ObjCProtocolDecl *, SourceLocation>
getCursorObjCProtocolRef(CXCursor C);
/// \brief Create an Objective-C class reference at the given location.
@@ -84,7 +85,7 @@ CXCursor MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
/// \brief Unpack an ObjCClassRef cursor into the class it references
/// and optionally the location where the reference occurred.
-std::pair<ObjCInterfaceDecl *, SourceLocation>
+std::pair<const ObjCInterfaceDecl *, SourceLocation>
getCursorObjCClassRef(CXCursor C);
/// \brief Create a type reference at the given location.
@@ -93,7 +94,7 @@ CXCursor MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
/// \brief Unpack a TypeRef cursor into the class it references
/// and optionally the location where the reference occurred.
-std::pair<TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);
+std::pair<const TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);
/// \brief Create a reference to a template at the given location.
CXCursor MakeCursorTemplateRef(const TemplateDecl *Template, SourceLocation Loc,
@@ -101,7 +102,8 @@ CXCursor MakeCursorTemplateRef(const TemplateDecl *Template, SourceLocation Loc,
/// \brief Unpack a TemplateRef cursor into the template it references and
/// the location where the reference occurred.
-std::pair<TemplateDecl *, SourceLocation> getCursorTemplateRef(CXCursor C);
+std::pair<const TemplateDecl *, SourceLocation>
+ getCursorTemplateRef(CXCursor C);
/// \brief Create a reference to a namespace or namespace alias at the given
/// location.
@@ -110,7 +112,7 @@ CXCursor MakeCursorNamespaceRef(const NamedDecl *NS, SourceLocation Loc,
/// \brief Unpack a NamespaceRef cursor into the namespace or namespace alias
/// it references and the location where the reference occurred.
-std::pair<NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C);
+std::pair<const NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C);
/// \brief Create a reference to a variable at the given location.
CXCursor MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
@@ -118,7 +120,7 @@ CXCursor MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
/// \brief Unpack a VariableRef cursor into the variable it references and the
/// location where the where the reference occurred.
-std::pair<VarDecl *, SourceLocation> getCursorVariableRef(CXCursor C);
+std::pair<const VarDecl *, SourceLocation> getCursorVariableRef(CXCursor C);
/// \brief Create a reference to a field at the given location.
CXCursor MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
@@ -126,14 +128,14 @@ CXCursor MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
/// \brief Unpack a MemberRef cursor into the field it references and the
/// location where the reference occurred.
-std::pair<FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C);
+std::pair<const FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C);
/// \brief Create a CXX base specifier cursor.
CXCursor MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
CXTranslationUnit TU);
/// \brief Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier.
-CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C);
+const CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C);
/// \brief Create a preprocessing directive cursor.
CXCursor MakePreprocessingDirectiveCursor(SourceRange Range,
@@ -143,19 +145,62 @@ CXCursor MakePreprocessingDirectiveCursor(SourceRange Range,
SourceRange getCursorPreprocessingDirective(CXCursor C);
/// \brief Create a macro definition cursor.
-CXCursor MakeMacroDefinitionCursor(MacroDefinition *, CXTranslationUnit TU);
+CXCursor MakeMacroDefinitionCursor(const MacroDefinition *,
+ CXTranslationUnit TU);
/// \brief Unpack a given macro definition cursor to retrieve its
/// source range.
-MacroDefinition *getCursorMacroDefinition(CXCursor C);
+const MacroDefinition *getCursorMacroDefinition(CXCursor C);
/// \brief Create a macro expansion cursor.
CXCursor MakeMacroExpansionCursor(MacroExpansion *,
CXTranslationUnit TU);
-/// \brief Unpack a given macro expansion cursor to retrieve its
-/// source range.
-MacroExpansion *getCursorMacroExpansion(CXCursor C);
+/// \brief Create a "pseudo" macro expansion cursor, using a macro definition
+/// and a source location.
+CXCursor MakeMacroExpansionCursor(MacroDefinition *, SourceLocation Loc,
+ CXTranslationUnit TU);
+
+/// \brief Wraps a macro expansion cursor and provides a common interface
+/// for a normal macro expansion cursor or a "pseudo" one.
+///
+/// "Pseudo" macro expansion cursors (essentially a macro definition along with
+/// a source location) are created in special cases, for example they can be
+/// created for identifiers inside macro definitions, if these identifiers are
+/// macro names.
+class MacroExpansionCursor {
+ CXCursor C;
+
+ bool isPseudo() const {
+ return C.data[1] != 0;
+ }
+ const MacroDefinition *getAsMacroDefinition() const {
+ assert(isPseudo());
+ return static_cast<const MacroDefinition *>(C.data[0]);
+ }
+ const MacroExpansion *getAsMacroExpansion() const {
+ assert(!isPseudo());
+ return static_cast<const MacroExpansion *>(C.data[0]);
+ }
+ SourceLocation getPseudoLoc() const {
+ assert(isPseudo());
+ return SourceLocation::getFromPtrEncoding(C.data[1]);
+ }
+
+public:
+ MacroExpansionCursor(CXCursor C) : C(C) {
+ assert(C.kind == CXCursor_MacroExpansion);
+ }
+
+ const IdentifierInfo *getName() const;
+ const MacroDefinition *getDefinition() const;
+ SourceRange getSourceRange() const;
+};
+
+/// \brief Unpack a given macro expansion cursor to retrieve its info.
+static inline MacroExpansionCursor getCursorMacroExpansion(CXCursor C) {
+ return C;
+}
/// \brief Create an inclusion directive cursor.
CXCursor MakeInclusionDirectiveCursor(InclusionDirective *,
@@ -163,7 +208,7 @@ CXCursor MakeInclusionDirectiveCursor(InclusionDirective *,
/// \brief Unpack a given inclusion directive cursor to retrieve its
/// source range.
-InclusionDirective *getCursorInclusionDirective(CXCursor C);
+const InclusionDirective *getCursorInclusionDirective(CXCursor C);
/// \brief Create a label reference at the given location.
CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
@@ -171,13 +216,14 @@ CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
/// \brief Unpack a label reference into the label statement it refers to and
/// the location of the reference.
-std::pair<LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C);
+std::pair<const LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C);
/// \brief Create a overloaded declaration reference cursor for an expression.
-CXCursor MakeCursorOverloadedDeclRef(OverloadExpr *E, CXTranslationUnit TU);
+CXCursor MakeCursorOverloadedDeclRef(const OverloadExpr *E,
+ CXTranslationUnit TU);
/// \brief Create a overloaded declaration reference cursor for a declaration.
-CXCursor MakeCursorOverloadedDeclRef(Decl *D, SourceLocation Location,
+CXCursor MakeCursorOverloadedDeclRef(const Decl *D, SourceLocation Location,
CXTranslationUnit TU);
/// \brief Create a overloaded declaration reference cursor for a template name.
@@ -186,7 +232,7 @@ CXCursor MakeCursorOverloadedDeclRef(TemplateName Template,
CXTranslationUnit TU);
/// \brief Internal storage for an overloaded declaration reference cursor;
-typedef llvm::PointerUnion3<OverloadExpr *, Decl *,
+typedef llvm::PointerUnion3<const OverloadExpr *, const Decl *,
OverloadedTemplateStorage *>
OverloadedDeclRefStorage;
@@ -195,11 +241,11 @@ typedef llvm::PointerUnion3<OverloadExpr *, Decl *,
std::pair<OverloadedDeclRefStorage, SourceLocation>
getCursorOverloadedDeclRef(CXCursor C);
-Decl *getCursorDecl(CXCursor Cursor);
-Expr *getCursorExpr(CXCursor Cursor);
-Stmt *getCursorStmt(CXCursor Cursor);
-Attr *getCursorAttr(CXCursor Cursor);
-Decl *getCursorParentDecl(CXCursor Cursor);
+const Decl *getCursorDecl(CXCursor Cursor);
+const Expr *getCursorExpr(CXCursor Cursor);
+const Stmt *getCursorStmt(CXCursor Cursor);
+const Attr *getCursorAttr(CXCursor Cursor);
+const Decl *getCursorParentDecl(CXCursor Cursor);
ASTContext &getCursorContext(CXCursor Cursor);
ASTUnit *getCursorASTUnit(CXCursor Cursor);
diff --git a/tools/libclang/CXLoadedDiagnostic.cpp b/tools/libclang/CXLoadedDiagnostic.cpp
index e5b6ccc..b02fdd6 100644
--- a/tools/libclang/CXLoadedDiagnostic.cpp
+++ b/tools/libclang/CXLoadedDiagnostic.cpp
@@ -1,15 +1,15 @@
-/*===-- CXLoadedDiagnostic.cpp - Handling of persisent diags -*- C++ -*-===*\
-|* *|
-|* The LLVM Compiler Infrastructure *|
-|* *|
-|* This file is distributed under the University of Illinois Open Source *|
-|* License. See LICENSE.TXT for details. *|
-|* *|
-|*===----------------------------------------------------------------------===*|
-|* *|
-|* Implements handling of persisent diagnostics. *|
-|* *|
-\*===----------------------------------------------------------------------===*/
+//===-- CXLoadedDiagnostic.cpp - Handling of persisent diags ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements handling of persisent diagnostics.
+//
+//===----------------------------------------------------------------------===//
#include "CXLoadedDiagnostic.h"
#include "CXString.h"
@@ -23,16 +23,13 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/MemoryBuffer.h"
-#include <assert.h>
-
using namespace clang;
-using namespace clang::cxstring;
//===----------------------------------------------------------------------===//
// Extend CXDiagnosticSetImpl which contains strings for diagnostics.
//===----------------------------------------------------------------------===//
-typedef llvm::DenseMap<unsigned, llvm::StringRef> Strings;
+typedef llvm::DenseMap<unsigned, const char *> Strings;
namespace {
class CXLoadedDiagnosticSetImpl : public CXDiagnosticSetImpl {
@@ -40,8 +37,6 @@ public:
CXLoadedDiagnosticSetImpl() : CXDiagnosticSetImpl(true), FakeFiles(FO) {}
virtual ~CXLoadedDiagnosticSetImpl() {}
- llvm::StringRef makeString(const char *blob, unsigned blobLen);
-
llvm::BumpPtrAllocator Alloc;
Strings Categories;
Strings WarningFlags;
@@ -50,17 +45,15 @@ public:
FileSystemOptions FO;
FileManager FakeFiles;
llvm::DenseMap<unsigned, const FileEntry *> Files;
-};
-}
-llvm::StringRef CXLoadedDiagnosticSetImpl::makeString(const char *blob,
- unsigned bloblen) {
- char *mem = Alloc.Allocate<char>(bloblen + 1);
- memcpy(mem, blob, bloblen);
- // Add a null terminator for those clients accessing the buffer
- // like a c-string.
- mem[bloblen] = '\0';
- return llvm::StringRef(mem, bloblen);
+ /// \brief Copy the string into our own allocator.
+ const char *copyString(StringRef Blob) {
+ char *mem = Alloc.Allocate<char>(Blob.size() + 1);
+ memcpy(mem, Blob.data(), Blob.size());
+ mem[Blob.size()] = '\0';
+ return mem;
+ }
+};
}
//===----------------------------------------------------------------------===//
@@ -102,17 +95,17 @@ CXSourceLocation CXLoadedDiagnostic::getLocation() const {
}
CXString CXLoadedDiagnostic::getSpelling() const {
- return cxstring::createCXString(Spelling, false);
+ return cxstring::createRef(Spelling);
}
CXString CXLoadedDiagnostic::getDiagnosticOption(CXString *Disable) const {
if (DiagOption.empty())
- return createCXString("");
+ return cxstring::createEmpty();
// FIXME: possibly refactor with logic in CXStoredDiagnostic.
if (Disable)
- *Disable = createCXString((Twine("-Wno-") + DiagOption).str());
- return createCXString((Twine("-W") + DiagOption).str());
+ *Disable = cxstring::createDup((Twine("-Wno-") + DiagOption).str());
+ return cxstring::createDup((Twine("-W") + DiagOption).str());
}
unsigned CXLoadedDiagnostic::getCategory() const {
@@ -120,7 +113,7 @@ unsigned CXLoadedDiagnostic::getCategory() const {
}
CXString CXLoadedDiagnostic::getCategoryText() const {
- return cxstring::createCXString(CategoryText);
+ return cxstring::createDup(CategoryText);
}
unsigned CXLoadedDiagnostic::getNumRanges() const {
@@ -141,7 +134,7 @@ CXString CXLoadedDiagnostic::getFixIt(unsigned FixIt,
assert(FixIt < FixIts.size());
if (ReplacementRange)
*ReplacementRange = FixIts[FixIt].first;
- return FixIts[FixIt].second;
+ return cxstring::createRef(FixIts[FixIt].second);
}
void CXLoadedDiagnostic::decodeLocation(CXSourceLocation location,
@@ -200,7 +193,7 @@ class DiagLoader {
if (error)
*error = code;
if (errorString)
- *errorString = createCXString(err);
+ *errorString = cxstring::createDup(err);
}
void reportInvalidFile(llvm::StringRef err) {
@@ -216,22 +209,20 @@ class DiagLoader {
StreamResult readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
llvm::StringRef errorContext,
unsigned &BlockOrRecordID,
- const bool atTopLevel = false);
+ bool atTopLevel = false);
LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
Strings &strings, llvm::StringRef errorContext,
RecordData &Record,
- const char *BlobStart,
- unsigned BlobLen,
+ StringRef Blob,
bool allowEmptyString = false);
LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
- llvm::StringRef &RetStr,
+ const char *&RetStr,
llvm::StringRef errorContext,
RecordData &Record,
- const char *BlobStart,
- unsigned BlobLen,
+ StringRef Blob,
bool allowEmptyString = false);
LoadResult readRange(CXLoadedDiagnosticSetImpl &TopDiags,
@@ -248,7 +239,7 @@ public:
if (error)
*error = CXLoadDiag_None;
if (errorString)
- *errorString = createCXString("");
+ *errorString = cxstring::createEmpty();
}
CXDiagnosticSet load(const char *file);
@@ -286,8 +277,7 @@ CXDiagnosticSet DiagLoader::load(const char *file) {
return 0;
}
- OwningPtr<CXLoadedDiagnosticSetImpl>
- Diags(new CXLoadedDiagnosticSetImpl());
+ OwningPtr<CXLoadedDiagnosticSetImpl> Diags(new CXLoadedDiagnosticSetImpl());
while (true) {
unsigned BlockID = 0;
@@ -328,7 +318,7 @@ CXDiagnosticSet DiagLoader::load(const char *file) {
StreamResult DiagLoader::readToNextRecordOrBlock(llvm::BitstreamCursor &Stream,
llvm::StringRef errorContext,
unsigned &blockOrRecordID,
- const bool atTopLevel) {
+ bool atTopLevel) {
blockOrRecordID = 0;
@@ -425,9 +415,7 @@ LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) {
}
RecordData Record;
- const char *Blob;
- unsigned BlobLen;
- unsigned recordID = Stream.ReadRecord(blockOrCode, Record, &Blob, &BlobLen);
+ unsigned recordID = Stream.readRecord(blockOrCode, Record);
if (recordID == serialized_diags::RECORD_VERSION) {
if (Record.size() < 1) {
@@ -435,7 +423,7 @@ LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) {
return Failure;
}
if (Record[0] > MaxSupportedVersion) {
- reportInvalidFile("diagnosics file is a newer version than the one "
+ reportInvalidFile("diagnostics file is a newer version than the one "
"supported");
return Failure;
}
@@ -445,32 +433,31 @@ LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) {
}
LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
- llvm::StringRef &RetStr,
+ const char *&RetStr,
llvm::StringRef errorContext,
RecordData &Record,
- const char *BlobStart,
- unsigned BlobLen,
+ StringRef Blob,
bool allowEmptyString) {
// Basic buffer overflow check.
- if (BlobLen > 65536) {
+ if (Blob.size() > 65536) {
reportInvalidFile(std::string("Out-of-bounds string in ") +
std::string(errorContext));
return Failure;
}
- if (allowEmptyString && Record.size() >= 1 && BlobLen == 0) {
+ if (allowEmptyString && Record.size() >= 1 && Blob.size() == 0) {
RetStr = "";
return Success;
}
- if (Record.size() < 1 || BlobLen == 0) {
+ if (Record.size() < 1 || Blob.size() == 0) {
reportInvalidFile(std::string("Corrupted ") + std::string(errorContext)
+ std::string(" entry"));
return Failure;
}
- RetStr = TopDiags.makeString(BlobStart, BlobLen);
+ RetStr = TopDiags.copyString(Blob);
return Success;
}
@@ -478,11 +465,10 @@ LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
Strings &strings,
llvm::StringRef errorContext,
RecordData &Record,
- const char *BlobStart,
- unsigned BlobLen,
+ StringRef Blob,
bool allowEmptyString) {
- llvm::StringRef RetStr;
- if (readString(TopDiags, RetStr, errorContext, Record, BlobStart, BlobLen,
+ const char *RetStr;
+ if (readString(TopDiags, RetStr, errorContext, Record, Blob,
allowEmptyString))
return Failure;
strings[Record[0]] = RetStr;
@@ -512,7 +498,7 @@ LoadResult DiagLoader::readLocation(CXLoadedDiagnosticSetImpl &TopDiags,
reportInvalidFile("Corrupted file entry in source location");
return Failure;
}
- Loc.file = (void*) FE;
+ Loc.file = const_cast<FileEntry *>(FE);
Loc.line = Record[offset++];
Loc.column = Record[offset++];
Loc.offset = Record[offset++];
@@ -582,10 +568,8 @@ LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
// Read the record.
Record.clear();
- const char *BlobStart = 0;
- unsigned BlobLen = 0;
- unsigned recID = Stream.ReadRecord(blockOrCode, Record,
- BlobStart, BlobLen);
+ StringRef Blob;
+ unsigned recID = Stream.readRecord(blockOrCode, Record, &Blob);
if (recID < serialized_diags::RECORD_FIRST ||
recID > serialized_diags::RECORD_LAST)
@@ -596,20 +580,19 @@ LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
continue;
case serialized_diags::RECORD_CATEGORY:
if (readString(TopDiags, TopDiags.Categories, "category", Record,
- BlobStart, BlobLen,
- /* allowEmptyString */ true))
+ Blob, /* allowEmptyString */ true))
return Failure;
continue;
case serialized_diags::RECORD_DIAG_FLAG:
if (readString(TopDiags, TopDiags.WarningFlags, "warning flag", Record,
- BlobStart, BlobLen))
+ Blob))
return Failure;
continue;
case serialized_diags::RECORD_FILENAME: {
if (readString(TopDiags, TopDiags.FileNames, "filename", Record,
- BlobStart, BlobLen))
+ Blob))
return Failure;
if (Record.size() < 3) {
@@ -638,11 +621,11 @@ LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
CXSourceRange SR;
if (readRange(TopDiags, Record, 0, SR))
return Failure;
- llvm::StringRef RetStr;
- if (readString(TopDiags, RetStr, "FIXIT", Record, BlobStart, BlobLen,
+ const char *RetStr;
+ if (readString(TopDiags, RetStr, "FIXIT", Record, Blob,
/* allowEmptyString */ true))
return Failure;
- D->FixIts.push_back(std::make_pair(SR, createCXString(RetStr, false)));
+ D->FixIts.push_back(std::make_pair(SR, RetStr));
continue;
}
@@ -655,7 +638,7 @@ LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
unsigned diagFlag = Record[offset++];
D->DiagOption = diagFlag ? TopDiags.WarningFlags[diagFlag] : "";
D->CategoryText = D->category ? TopDiags.Categories[D->category] : "";
- D->Spelling = TopDiags.makeString(BlobStart, BlobLen);
+ D->Spelling = TopDiags.copyString(Blob);
continue;
}
}
diff --git a/tools/libclang/CXLoadedDiagnostic.h b/tools/libclang/CXLoadedDiagnostic.h
index d4a321e..d4b11d5 100644
--- a/tools/libclang/CXLoadedDiagnostic.h
+++ b/tools/libclang/CXLoadedDiagnostic.h
@@ -82,8 +82,8 @@ public:
Location DiagLoc;
std::vector<CXSourceRange> Ranges;
- std::vector<std::pair<CXSourceRange, CXString> > FixIts;
- llvm::StringRef Spelling;
+ std::vector<std::pair<CXSourceRange, const char *> > FixIts;
+ const char *Spelling;
llvm::StringRef DiagOption;
llvm::StringRef CategoryText;
unsigned severity;
diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp
index a6bf8fc..bc8d575 100644
--- a/tools/libclang/CXSourceLocation.cpp
+++ b/tools/libclang/CXSourceLocation.cpp
@@ -12,15 +12,17 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/ASTUnit.h"
-
#include "CIndexer.h"
-#include "CXString.h"
+#include "CLog.h"
+#include "CXLoadedDiagnostic.h"
#include "CXSourceLocation.h"
+#include "CXString.h"
#include "CXTranslationUnit.h"
-#include "CXLoadedDiagnostic.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Format.h"
using namespace clang;
-using namespace clang::cxstring;
+using namespace clang::cxindex;
//===----------------------------------------------------------------------===//
// Internal predicates on CXSourceLocations.
@@ -116,40 +118,41 @@ CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
extern "C" {
-CXSourceLocation clang_getLocation(CXTranslationUnit tu,
+CXSourceLocation clang_getLocation(CXTranslationUnit TU,
CXFile file,
unsigned line,
unsigned column) {
- if (!tu || !file)
+ if (!TU || !file)
return clang_getNullLocation();
- bool Logging = ::getenv("LIBCLANG_LOGGING");
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+ LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
const FileEntry *File = static_cast<const FileEntry *>(file);
SourceLocation SLoc = CXXUnit->getLocation(File, line, column);
if (SLoc.isInvalid()) {
- if (Logging)
- llvm::errs() << "clang_getLocation(\"" << File->getName()
- << "\", " << line << ", " << column << ") = invalid\n";
+ if (Log)
+ *Log << llvm::format("(\"%s\", %d, %d) = invalid",
+ File->getName(), line, column);
return clang_getNullLocation();
}
- if (Logging)
- llvm::errs() << "clang_getLocation(\"" << File->getName()
- << "\", " << line << ", " << column << ") = "
- << SLoc.getRawEncoding() << "\n";
+ CXSourceLocation CXLoc =
+ cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
+ if (Log)
+ *Log << llvm::format("(\"%s\", %d, %d) = ", File->getName(), line, column)
+ << CXLoc;
- return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
+ return CXLoc;
}
-CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
+CXSourceLocation clang_getLocationForOffset(CXTranslationUnit TU,
CXFile file,
unsigned offset) {
- if (!tu || !file)
+ if (!TU || !file)
return clang_getNullLocation();
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+ ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
SourceLocation SLoc
= CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);
@@ -183,7 +186,7 @@ static void createNullLocation(CXFile *file, unsigned *line,
static void createNullLocation(CXString *filename, unsigned *line,
unsigned *column, unsigned *offset = 0) {
if (filename)
- *filename = createCXString("");
+ *filename = cxstring::createEmpty();
if (line)
*line = 0;
if (column)
@@ -228,7 +231,7 @@ void clang_getExpansionLocation(CXSourceLocation location,
}
if (file)
- *file = (void *)SM.getFileEntryForSLocEntry(sloc);
+ *file = const_cast<FileEntry *>(SM.getFileEntryForSLocEntry(sloc));
if (line)
*line = SM.getExpansionLineNumber(ExpansionLoc);
if (column)
@@ -259,7 +262,7 @@ void clang_getPresumedLocation(CXSourceLocation location,
PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
if (filename)
- *filename = createCXString(PreLoc.getFilename());
+ *filename = cxstring::createRef(PreLoc.getFilename());
if (line)
*line = PreLoc.getLine();
if (column)
@@ -295,16 +298,8 @@ void clang_getSpellingLocation(CXSourceLocation location,
const SourceManager &SM =
*static_cast<const SourceManager*>(location.ptr_data[0]);
- SourceLocation SpellLoc = Loc;
- if (SpellLoc.isMacroID()) {
- SourceLocation SimpleSpellingLoc = SM.getImmediateSpellingLoc(SpellLoc);
- if (SimpleSpellingLoc.isFileID() &&
- SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
- SpellLoc = SimpleSpellingLoc;
- else
- SpellLoc = SM.getExpansionLoc(SpellLoc);
- }
-
+ // FIXME: This should call SourceManager::getSpellingLoc().
+ SourceLocation SpellLoc = SM.getFileLoc(Loc);
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
FileID FID = LocInfo.first;
unsigned FileOffset = LocInfo.second;
@@ -313,7 +308,7 @@ void clang_getSpellingLocation(CXSourceLocation location,
return createNullLocation(file, line, column, offset);
if (file)
- *file = (void *)SM.getFileEntryForID(FID);
+ *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
if (line)
*line = SM.getLineNumber(FID, FileOffset);
if (column)
@@ -322,5 +317,41 @@ void clang_getSpellingLocation(CXSourceLocation location,
*offset = FileOffset;
}
-} // end extern "C"
+void clang_getFileLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset) {
+
+ if (!isASTUnitSourceLocation(location)) {
+ CXLoadedDiagnostic::decodeLocation(location, file, line,
+ column, offset);
+ return;
+ }
+
+ SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
+
+ if (!location.ptr_data[0] || Loc.isInvalid())
+ return createNullLocation(file, line, column, offset);
+
+ const SourceManager &SM =
+ *static_cast<const SourceManager*>(location.ptr_data[0]);
+ SourceLocation FileLoc = SM.getFileLoc(Loc);
+ std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(FileLoc);
+ FileID FID = LocInfo.first;
+ unsigned FileOffset = LocInfo.second;
+ if (FID.isInvalid())
+ return createNullLocation(file, line, column, offset);
+
+ if (file)
+ *file = const_cast<FileEntry *>(SM.getFileEntryForID(FID));
+ if (line)
+ *line = SM.getLineNumber(FID, FileOffset);
+ if (column)
+ *column = SM.getColumnNumber(FID, FileOffset);
+ if (offset)
+ *offset = FileOffset;
+}
+
+} // end extern "C"
diff --git a/tools/libclang/CXSourceLocation.h b/tools/libclang/CXSourceLocation.h
index 6c5e858..f97ac1f 100644
--- a/tools/libclang/CXSourceLocation.h
+++ b/tools/libclang/CXSourceLocation.h
@@ -15,9 +15,9 @@
#define LLVM_CLANG_CXSOURCELOCATION_H
#include "clang-c/Index.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/LangOptions.h"
#include "clang/AST/ASTContext.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
namespace clang {
@@ -32,7 +32,7 @@ translateSourceLocation(const SourceManager &SM, const LangOptions &LangOpts,
if (Loc.isInvalid())
clang_getNullLocation();
- CXSourceLocation Result = { { (void*) &SM, (void*) &LangOpts, },
+ CXSourceLocation Result = { { &SM, &LangOpts, },
Loc.getRawEncoding() };
return Result;
}
diff --git a/tools/libclang/CXStoredDiagnostic.cpp b/tools/libclang/CXStoredDiagnostic.cpp
index fa331de..9731616 100644
--- a/tools/libclang/CXStoredDiagnostic.cpp
+++ b/tools/libclang/CXStoredDiagnostic.cpp
@@ -26,7 +26,6 @@
using namespace clang;
using namespace clang::cxloc;
-using namespace clang::cxstring;
CXDiagnosticSeverity CXStoredDiagnostic::getSeverity() const {
switch (Diag.getLevel()) {
@@ -49,7 +48,7 @@ CXSourceLocation CXStoredDiagnostic::getLocation() const {
}
CXString CXStoredDiagnostic::getSpelling() const {
- return createCXString(Diag.getMessage(), false);
+ return cxstring::createRef(Diag.getMessage());
}
CXString CXStoredDiagnostic::getDiagnosticOption(CXString *Disable) const {
@@ -57,17 +56,17 @@ CXString CXStoredDiagnostic::getDiagnosticOption(CXString *Disable) const {
StringRef Option = DiagnosticIDs::getWarningOptionForDiag(ID);
if (!Option.empty()) {
if (Disable)
- *Disable = createCXString((Twine("-Wno-") + Option).str());
- return createCXString((Twine("-W") + Option).str());
+ *Disable = cxstring::createDup((Twine("-Wno-") + Option).str());
+ return cxstring::createDup((Twine("-W") + Option).str());
}
if (ID == diag::fatal_too_many_errors) {
if (Disable)
- *Disable = createCXString("-ferror-limit=0");
- return createCXString("-ferror-limit=");
+ *Disable = cxstring::createRef("-ferror-limit=0");
+ return cxstring::createRef("-ferror-limit=");
}
- return createCXString("");
+ return cxstring::createEmpty();
}
unsigned CXStoredDiagnostic::getCategory() const {
@@ -76,7 +75,7 @@ unsigned CXStoredDiagnostic::getCategory() const {
CXString CXStoredDiagnostic::getCategoryText() const {
unsigned catID = DiagnosticIDs::getCategoryNumberForDiag(Diag.getID());
- return createCXString(DiagnosticIDs::getCategoryNameFromID(catID));
+ return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(catID));
}
unsigned CXStoredDiagnostic::getNumRanges() const {
@@ -109,6 +108,6 @@ CXString CXStoredDiagnostic::getFixIt(unsigned FixIt,
*ReplacementRange = translateSourceRange(Diag.getLocation().getManager(),
LangOpts, Hint.RemoveRange);
}
- return createCXString(Hint.CodeToInsert);
+ return cxstring::createDup(Hint.CodeToInsert);
}
diff --git a/tools/libclang/CXString.cpp b/tools/libclang/CXString.cpp
index bb09cd5..1523034 100644
--- a/tools/libclang/CXString.cpp
+++ b/tools/libclang/CXString.cpp
@@ -15,48 +15,93 @@
#include "CXString.h"
#include "CXTranslationUnit.h"
-#include "clang/Frontend/ASTUnit.h"
#include "clang-c/Index.h"
+#include "clang/Frontend/ASTUnit.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
-using namespace clang::cxstring;
-enum CXStringFlag { CXS_Unmanaged, CXS_Malloc, CXS_StringBuf };
+/// Describes the kind of underlying data in CXString.
+enum CXStringFlag {
+ /// CXString contains a 'const char *' that it doesn't own.
+ CXS_Unmanaged,
+
+ /// CXString contains a 'const char *' that it allocated with malloc().
+ CXS_Malloc,
+
+ /// CXString contains a CXStringBuf that needs to be returned to the
+ /// CXStringPool.
+ CXS_StringBuf
+};
+
+namespace clang {
+namespace cxstring {
//===----------------------------------------------------------------------===//
// Basic generation of CXStrings.
//===----------------------------------------------------------------------===//
-CXString cxstring::createCXString(const char *String, bool DupString){
+CXString createEmpty() {
CXString Str;
- if (DupString) {
- Str.data = strdup(String);
- Str.private_flags = (unsigned) CXS_Malloc;
- } else {
- Str.data = (void*)String;
- Str.private_flags = (unsigned) CXS_Unmanaged;
- }
+ Str.data = "";
+ Str.private_flags = CXS_Unmanaged;
+ return Str;
+}
+
+CXString createNull() {
+ CXString Str;
+ Str.data = 0;
+ Str.private_flags = CXS_Unmanaged;
+ return Str;
+}
+
+CXString createRef(const char *String) {
+ if (String && String[0] == '\0')
+ return createEmpty();
+
+ CXString Str;
+ Str.data = String;
+ Str.private_flags = CXS_Unmanaged;
+ return Str;
+}
+
+CXString createDup(const char *String) {
+ if (!String)
+ return createNull();
+
+ if (String[0] == '\0')
+ return createEmpty();
+
+ CXString Str;
+ Str.data = strdup(String);
+ Str.private_flags = CXS_Malloc;
return Str;
}
-CXString cxstring::createCXString(StringRef String, bool DupString) {
+CXString createRef(StringRef String) {
+ // If the string is not nul-terminated, we have to make a copy.
+ // This is doing a one past end read, and should be removed!
+ if (!String.empty() && String.data()[String.size()] != 0)
+ return createDup(String);
+
CXString Result;
- if (DupString || (!String.empty() && String.data()[String.size()] != 0)) {
- char *Spelling = (char *)malloc(String.size() + 1);
- memmove(Spelling, String.data(), String.size());
- Spelling[String.size()] = 0;
- Result.data = Spelling;
- Result.private_flags = (unsigned) CXS_Malloc;
- } else {
- Result.data = (void*) String.data();
- Result.private_flags = (unsigned) CXS_Unmanaged;
- }
+ Result.data = String.data();
+ Result.private_flags = (unsigned) CXS_Unmanaged;
return Result;
}
-CXString cxstring::createCXString(CXStringBuf *buf) {
+CXString createDup(StringRef String) {
+ CXString Result;
+ char *Spelling = static_cast<char *>(malloc(String.size() + 1));
+ memmove(Spelling, String.data(), String.size());
+ Spelling[String.size()] = 0;
+ Result.data = Spelling;
+ Result.private_flags = (unsigned) CXS_Malloc;
+ return Result;
+}
+
+CXString createCXString(CXStringBuf *buf) {
CXString Str;
Str.data = buf;
Str.private_flags = (unsigned) CXS_StringBuf;
@@ -68,43 +113,38 @@ CXString cxstring::createCXString(CXStringBuf *buf) {
// String pools.
//===----------------------------------------------------------------------===//
-
-typedef std::vector<CXStringBuf *> CXStringPool;
-
-void *cxstring::createCXStringPool() {
- return new CXStringPool();
-}
-
-void cxstring::disposeCXStringPool(void *p) {
- CXStringPool *pool = static_cast<CXStringPool*>(p);
- if (pool) {
- for (CXStringPool::iterator I = pool->begin(), E = pool->end();
- I != E; ++I) {
- delete *I;
- }
- delete pool;
+CXStringPool::~CXStringPool() {
+ for (std::vector<CXStringBuf *>::iterator I = Pool.begin(), E = Pool.end();
+ I != E; ++I) {
+ delete *I;
}
}
-CXStringBuf *cxstring::getCXStringBuf(CXTranslationUnit TU) {
- CXStringPool *pool = static_cast<CXStringPool*>(TU->StringPool);
- if (pool->empty())
+CXStringBuf *CXStringPool::getCXStringBuf(CXTranslationUnit TU) {
+ if (Pool.empty())
return new CXStringBuf(TU);
- CXStringBuf *buf = pool->back();
- buf->Data.clear();
- pool->pop_back();
- return buf;
+
+ CXStringBuf *Buf = Pool.back();
+ Buf->Data.clear();
+ Pool.pop_back();
+ return Buf;
+}
+
+CXStringBuf *getCXStringBuf(CXTranslationUnit TU) {
+ return TU->StringPool->getCXStringBuf(TU);
}
-void cxstring::disposeCXStringBuf(CXStringBuf *buf) {
- if (buf)
- static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf);
+void CXStringBuf::dispose() {
+ TU->StringPool->Pool.push_back(this);
}
-bool cxstring::isManagedByPool(CXString str) {
+bool isManagedByPool(CXString str) {
return ((CXStringFlag) str.private_flags) == CXS_StringBuf;
}
+} // end namespace cxstring
+} // end namespace clang
+
//===----------------------------------------------------------------------===//
// libClang public APIs.
//===----------------------------------------------------------------------===//
@@ -112,9 +152,9 @@ bool cxstring::isManagedByPool(CXString str) {
extern "C" {
const char *clang_getCString(CXString string) {
if (string.private_flags == (unsigned) CXS_StringBuf) {
- return ((CXStringBuf*)string.data)->Data.data();
+ return static_cast<const cxstring::CXStringBuf *>(string.data)->Data.data();
}
- return (const char*) string.data;
+ return static_cast<const char *>(string.data);
}
void clang_disposeString(CXString string) {
@@ -123,10 +163,11 @@ void clang_disposeString(CXString string) {
break;
case CXS_Malloc:
if (string.data)
- free((void*)string.data);
+ free(const_cast<void *>(string.data));
break;
case CXS_StringBuf:
- disposeCXStringBuf((CXStringBuf *) string.data);
+ static_cast<cxstring::CXStringBuf *>(
+ const_cast<void *>(string.data))->dispose();
break;
}
}
diff --git a/tools/libclang/CXString.h b/tools/libclang/CXString.h
index c354bd2..7032033 100644
--- a/tools/libclang/CXString.h
+++ b/tools/libclang/CXString.h
@@ -16,36 +16,82 @@
#include "clang-c/Index.h"
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include <vector>
+#include <string>
namespace clang {
namespace cxstring {
-
-struct CXStringBuf {
- SmallString<128> Data;
- CXTranslationUnit TU;
- CXStringBuf(CXTranslationUnit tu) : TU(tu) {}
-};
-/// \brief Create a CXString object from a C string.
-CXString createCXString(const char *String, bool DupString = false);
+struct CXStringBuf;
+
+/// \brief Create a CXString object for an empty "" string.
+CXString createEmpty();
+
+/// \brief Create a CXString object for an NULL string.
+///
+/// A NULL string should be used as an "invalid" value in case of errors.
+CXString createNull();
+
+/// \brief Create a CXString object from a nul-terminated C string. New
+/// CXString may contain a pointer to \p String.
+///
+/// \p String should not be changed by the caller afterwards.
+CXString createRef(const char *String);
+
+/// \brief Create a CXString object from a nul-terminated C string. New
+/// CXString will contain a copy of \p String.
+///
+/// \p String can be changed or freed by the caller.
+CXString createDup(const char *String);
+
+/// \brief Create a CXString object from a StringRef. New CXString may
+/// contain a pointer to the undrelying data of \p String.
+///
+/// \p String should not be changed by the caller afterwards.
+CXString createRef(StringRef String);
+
+/// \brief Create a CXString object from a StringRef. New CXString will
+/// contain a copy of \p String.
+///
+/// \p String can be changed or freed by the caller.
+CXString createDup(StringRef String);
-/// \brief Create a CXString object from a StringRef.
-CXString createCXString(StringRef String, bool DupString = true);
+// Usually std::string is intended to be used as backing storage for CXString.
+// In this case, call \c createRef(String.c_str()).
+//
+// If you need to make a copy, call \c createDup(StringRef(String)).
+CXString createRef(std::string String) LLVM_DELETED_FUNCTION;
/// \brief Create a CXString object that is backed by a string buffer.
CXString createCXString(CXStringBuf *buf);
-/// \brief Create an opaque string pool used for fast geneneration of strings.
-void *createCXStringPool();
+/// \brief A string pool used for fast allocation/deallocation of strings.
+class CXStringPool {
+public:
+ ~CXStringPool();
+
+ CXStringBuf *getCXStringBuf(CXTranslationUnit TU);
+
+private:
+ std::vector<CXStringBuf *> Pool;
+
+ friend struct CXStringBuf;
+};
+
+struct CXStringBuf {
+ SmallString<128> Data;
+ CXTranslationUnit TU;
+
+ CXStringBuf(CXTranslationUnit TU) : TU(TU) {}
+
+ /// \brief Return this buffer to the pool.
+ void dispose();
+};
-/// \brief Dispose of a string pool.
-void disposeCXStringPool(void *pool);
-
CXStringBuf *getCXStringBuf(CXTranslationUnit TU);
-
-void disposeCXStringBuf(CXStringBuf *buf);
/// \brief Returns true if the CXString data is managed by a pool.
bool isManagedByPool(CXString str);
diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h
index 37789aa..699b74a 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -14,24 +14,34 @@
#ifndef LLVM_CLANG_CXTRANSLATIONUNIT_H
#define LLVM_CLANG_CXTRANSLATIONUNIT_H
-extern "C" {
+#include "clang-c/Index.h"
+#include "CXString.h"
+
+namespace clang {
+ class ASTUnit;
+ class CIndexer;
+ class SimpleFormatContext;
+} // namespace clang
+
struct CXTranslationUnitImpl {
- void *CIdx;
- void *TUData;
- void *StringPool;
+ clang::CIndexer *CIdx;
+ clang::ASTUnit *TheASTUnit;
+ clang::cxstring::CXStringPool *StringPool;
void *Diagnostics;
void *OverridenCursorsPool;
+ clang::SimpleFormatContext *FormatContext;
+ unsigned FormatInMemoryUniqueId;
};
-}
namespace clang {
- class ASTUnit;
- class CIndexer;
-
namespace cxtu {
-CXTranslationUnitImpl *MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *TU);
-
+CXTranslationUnitImpl *MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU);
+
+static inline ASTUnit *getASTUnit(CXTranslationUnit TU) {
+ return TU->TheASTUnit;
+}
+
class CXTUOwner {
CXTranslationUnitImpl *TU;
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 4e031d2..6f87fc5 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -12,15 +12,15 @@
//===--------------------------------------------------------------------===//
#include "CIndexer.h"
-#include "CXTranslationUnit.h"
#include "CXCursor.h"
#include "CXString.h"
+#include "CXTranslationUnit.h"
#include "CXType.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Type.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
#include "clang/Frontend/ASTUnit.h"
using namespace clang;
@@ -97,7 +97,7 @@ CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
CXTypeKind TK = CXType_Invalid;
if (TU && !T.isNull()) {
- ASTContext &Ctx = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
+ ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
if (Ctx.getLangOpts().ObjC1) {
QualType UnqualT = T.getUnqualifiedType();
if (Ctx.isObjCIdType(UnqualT))
@@ -131,27 +131,32 @@ CXType clang_getCursorType(CXCursor C) {
using namespace cxcursor;
CXTranslationUnit TU = cxcursor::getCursorTU(C);
- ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
+ if (!TU)
+ return MakeCXType(QualType(), TU);
+
+ ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
if (clang_isExpression(C.kind)) {
QualType T = cxcursor::getCursorExpr(C)->getType();
return MakeCXType(T, TU);
}
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (!D)
return MakeCXType(QualType(), TU);
- if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
+ if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
return MakeCXType(Context.getTypeDeclType(TD), TU);
- if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
+ if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return MakeCXType(Context.getObjCInterfaceType(ID), TU);
- if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+ if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
return MakeCXType(VD->getType(), TU);
- if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
+ if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
return MakeCXType(PD->getType(), TU);
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
return MakeCXType(FD->getType(), TU);
+ if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
+ return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
return MakeCXType(QualType(), TU);
}
@@ -197,14 +202,29 @@ CXType clang_getCursorType(CXCursor C) {
return MakeCXType(QualType(), TU);
}
+CXString clang_getTypeSpelling(CXType CT) {
+ QualType T = GetQualType(CT);
+ if (T.isNull())
+ return cxstring::createEmpty();
+
+ CXTranslationUnit TU = GetTU(CT);
+ SmallString<64> Str;
+ llvm::raw_svector_ostream OS(Str);
+ PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
+
+ T.print(OS, PP);
+
+ return cxstring::createDup(OS.str());
+}
+
CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
using namespace cxcursor;
CXTranslationUnit TU = cxcursor::getCursorTU(C);
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
- if (TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
+ if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
QualType T = TD->getUnderlyingType();
return MakeCXType(T, TU);
}
@@ -220,9 +240,9 @@ CXType clang_getEnumDeclIntegerType(CXCursor C) {
CXTranslationUnit TU = cxcursor::getCursorTU(C);
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
- if (EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
+ if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
QualType T = TD->getIntegerType();
return MakeCXType(T, TU);
}
@@ -237,9 +257,9 @@ long long clang_getEnumConstantDeclValue(CXCursor C) {
using namespace cxcursor;
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
- if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
+ if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
return TD->getInitVal().getSExtValue();
}
@@ -253,9 +273,9 @@ unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
using namespace cxcursor;
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
- if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
+ if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
return TD->getInitVal().getZExtValue();
}
@@ -265,6 +285,21 @@ unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
return ULLONG_MAX;
}
+int clang_getFieldDeclBitWidth(CXCursor C) {
+ using namespace cxcursor;
+
+ if (clang_isDeclaration(C.kind)) {
+ const Decl *D = getCursorDecl(C);
+
+ if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
+ if (FD->isBitField())
+ return FD->getBitWidthValue(getCursorContext(C));
+ }
+ }
+
+ return -1;
+}
+
CXType clang_getCanonicalType(CXType CT) {
if (CT.kind == CXType_Invalid)
return CT;
@@ -275,8 +310,9 @@ CXType clang_getCanonicalType(CXType CT) {
if (T.isNull())
return MakeCXType(QualType(), GetTU(CT));
- ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
- return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
+ return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
+ .getCanonicalType(T),
+ TU);
}
unsigned clang_isConstQualifiedType(CXType CT) {
@@ -427,7 +463,7 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
TKIND(Vector);
}
#undef TKIND
- return cxstring::createCXString(s);
+ return cxstring::createRef(s);
}
unsigned clang_equalTypes(CXType A, CXType B) {
@@ -465,6 +501,7 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
TCALLINGCONV(AAPCS);
TCALLINGCONV(AAPCS_VFP);
TCALLINGCONV(PnaclCall);
+ TCALLINGCONV(IntelOclBicc);
}
#undef TCALLINGCONV
}
@@ -517,7 +554,7 @@ CXType clang_getResultType(CXType X) {
CXType clang_getCursorResultType(CXCursor C) {
if (clang_isDeclaration(C.kind)) {
- Decl *D = cxcursor::getCursorDecl(C);
+ const Decl *D = cxcursor::getCursorDecl(C);
if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
@@ -533,9 +570,8 @@ unsigned clang_isPODType(CXType X) {
return 0;
CXTranslationUnit TU = GetTU(X);
- ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
- return T.isPODType(AU->getASTContext()) ? 1 : 0;
+ return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
}
CXType clang_getElementType(CXType CT) {
@@ -617,32 +653,30 @@ long long clang_getArraySize(CXType CT) {
CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
if (!clang_isDeclaration(C.kind))
- return cxstring::createCXString("");
+ return cxstring::createEmpty();
- Decl *D = static_cast<Decl*>(C.data[0]);
- CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
- ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
- ASTContext &Ctx = AU->getASTContext();
+ const Decl *D = cxcursor::getCursorDecl(C);
+ ASTContext &Ctx = cxcursor::getCursorContext(C);
std::string encoding;
- if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
+ if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
- return cxstring::createCXString("?");
- } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
+ return cxstring::createRef("?");
+ } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
- else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
else {
QualType Ty;
- if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
+ if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
Ty = Ctx.getTypeDeclType(TD);
- if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
+ if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
Ty = VD->getType();
- else return cxstring::createCXString("?");
+ else return cxstring::createRef("?");
Ctx.getObjCEncodingForType(Ty, encoding);
}
- return cxstring::createCXString(encoding);
+ return cxstring::createDup(encoding);
}
} // end: extern "C"
diff --git a/tools/libclang/CursorVisitor.h b/tools/libclang/CursorVisitor.h
index 7cf7508..53d864d 100644
--- a/tools/libclang/CursorVisitor.h
+++ b/tools/libclang/CursorVisitor.h
@@ -10,10 +10,9 @@
#ifndef LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
#define LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
-#include "Index_Internal.h"
#include "CXCursor.h"
#include "CXTranslationUnit.h"
-
+#include "Index_Internal.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/TypeLocVisitor.h"
@@ -34,10 +33,11 @@ public:
MemberRefVisitKind, SizeOfPackExprPartsKind,
LambdaExprPartsKind, PostChildrenVisitKind };
protected:
- void *data[3];
+ const void *data[3];
CXCursor parent;
Kind K;
- VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
+ VisitorJob(CXCursor C, Kind k, const void *d1, const void *d2 = 0,
+ const void *d3 = 0)
: parent(C), K(k) {
data[0] = d1;
data[1] = d2;
@@ -70,7 +70,7 @@ private:
/// \brief The declaration that serves at the parent of any statement or
/// expression nodes.
- Decl *StmtParent;
+ const Decl *StmtParent;
/// \brief The visitor function.
CXCursorVisitor Visitor;
@@ -116,15 +116,16 @@ private:
/// \param R a half-open source range retrieved from the abstract syntax tree.
RangeComparisonResult CompareRegionOfInterest(SourceRange R);
- void visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);
+ bool visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);
class SetParentRAII {
CXCursor &Parent;
- Decl *&StmtParent;
+ const Decl *&StmtParent;
CXCursor OldParent;
public:
- SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
+ SetParentRAII(CXCursor &Parent, const Decl *&StmtParent,
+ CXCursor NewParent)
: Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
{
Parent = NewParent;
@@ -147,7 +148,7 @@ public:
SourceRange RegionOfInterest = SourceRange(),
bool VisitDeclsOnly = false,
PostChildrenVisitorTy PostChildrenVisitor = 0)
- : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
+ : TU(TU), AU(cxtu::getASTUnit(TU)),
Visitor(Visitor), PostChildrenVisitor(PostChildrenVisitor),
ClientData(ClientData),
VisitPreprocessorLast(VisitPreprocessorLast),
@@ -171,14 +172,14 @@ public:
}
}
- ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
+ ASTUnit *getASTUnit() const { return AU; }
CXTranslationUnit getTU() const { return TU; }
bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
/// \brief Visit declarations and preprocessed entities for the file region
/// designated by \see RegionOfInterest.
- void visitFileRegion();
+ bool visitFileRegion();
bool visitPreprocessedEntitiesInRegion();
@@ -198,7 +199,7 @@ public:
bool VisitAttributes(Decl *D);
bool VisitBlockDecl(BlockDecl *B);
bool VisitCXXRecordDecl(CXXRecordDecl *D);
- llvm::Optional<bool> shouldVisitCursor(CXCursor C);
+ Optional<bool> shouldVisitCursor(CXCursor C);
bool VisitDeclContext(DeclContext *DC);
bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
bool VisitTypedefDecl(TypedefDecl *D);
@@ -258,8 +259,8 @@ public:
// Data-recursive visitor functions.
bool IsInRegionOfInterest(CXCursor C);
bool RunVisitorWorkList(VisitorWorkList &WL);
- void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
- LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
+ void EnqueueWorkList(VisitorWorkList &WL, const Stmt *S);
+ LLVM_ATTRIBUTE_NOINLINE bool Visit(const Stmt *S);
};
}
diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp
index 3614206..95d74ef 100644
--- a/tools/libclang/IndexBody.cpp
+++ b/tools/libclang/IndexBody.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
-
#include "RecursiveASTVisitor.h"
using namespace clang;
diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp
index 4b6706f..d7fb959 100644
--- a/tools/libclang/IndexDecl.cpp
+++ b/tools/libclang/IndexDecl.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
-
#include "clang/AST/DeclVisitor.h"
using namespace clang;
@@ -16,39 +15,41 @@ using namespace cxindex;
namespace {
-class IndexingDeclVisitor : public DeclVisitor<IndexingDeclVisitor, bool> {
+class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
IndexingContext &IndexCtx;
public:
explicit IndexingDeclVisitor(IndexingContext &indexCtx)
: IndexCtx(indexCtx) { }
- void handleDeclarator(DeclaratorDecl *D, const NamedDecl *Parent = 0) {
+ void handleDeclarator(const DeclaratorDecl *D, const NamedDecl *Parent = 0) {
if (!Parent) Parent = D;
if (!IndexCtx.shouldIndexFunctionLocalSymbols()) {
IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent);
IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
} else {
- if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
+ if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
IndexCtx.handleVar(Parm);
- } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- for (FunctionDecl::param_iterator
- PI = FD->param_begin(), PE = FD->param_end(); PI != PE; ++PI) {
+ } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ for (FunctionDecl::param_const_iterator PI = FD->param_begin(),
+ PE = FD->param_end();
+ PI != PE; ++PI) {
IndexCtx.handleVar(*PI);
}
}
}
}
- void handleObjCMethod(ObjCMethodDecl *D) {
+ void handleObjCMethod(const ObjCMethodDecl *D) {
IndexCtx.handleObjCMethod(D);
if (D->isImplicit())
return;
IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D);
- for (ObjCMethodDecl::param_iterator
- I = D->param_begin(), E = D->param_end(); I != E; ++I)
+ for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
+ E = D->param_end();
+ I != E; ++I)
handleDeclarator(*I, D);
if (D->isThisDeclarationADefinition()) {
@@ -59,14 +60,14 @@ public:
}
}
- bool VisitFunctionDecl(FunctionDecl *D) {
+ bool VisitFunctionDecl(const FunctionDecl *D) {
IndexCtx.handleFunction(D);
handleDeclarator(D);
- if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
+ if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
// Constructor initializers.
- for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(),
- E = Ctor->init_end();
+ for (CXXConstructorDecl::init_const_iterator I = Ctor->init_begin(),
+ E = Ctor->init_end();
I != E; ++I) {
CXXCtorInitializer *Init = *I;
if (Init->isWritten()) {
@@ -87,14 +88,14 @@ public:
return true;
}
- bool VisitVarDecl(VarDecl *D) {
+ bool VisitVarDecl(const VarDecl *D) {
IndexCtx.handleVar(D);
handleDeclarator(D);
IndexCtx.indexBody(D->getInit(), D);
return true;
}
- bool VisitFieldDecl(FieldDecl *D) {
+ bool VisitFieldDecl(const FieldDecl *D) {
IndexCtx.handleField(D);
handleDeclarator(D);
if (D->isBitField())
@@ -103,27 +104,27 @@ public:
IndexCtx.indexBody(D->getInClassInitializer(), D);
return true;
}
-
- bool VisitEnumConstantDecl(EnumConstantDecl *D) {
+
+ bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
IndexCtx.handleEnumerator(D);
IndexCtx.indexBody(D->getInitExpr(), D);
return true;
}
- bool VisitTypedefNameDecl(TypedefNameDecl *D) {
+ bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
IndexCtx.handleTypedefName(D);
IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
return true;
}
- bool VisitTagDecl(TagDecl *D) {
+ bool VisitTagDecl(const TagDecl *D) {
// Non-free standing tags are handled in indexTypeSourceInfo.
if (D->isFreeStanding())
IndexCtx.indexTagDecl(D);
return true;
}
- bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+ bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
IndexCtx.handleObjCInterface(D);
if (D->isThisDeclarationADefinition()) {
@@ -133,7 +134,7 @@ public:
return true;
}
- bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+ bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
IndexCtx.handleObjCProtocol(D);
if (D->isThisDeclarationADefinition()) {
@@ -143,7 +144,7 @@ public:
return true;
}
- bool VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+ bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
const ObjCInterfaceDecl *Class = D->getClassInterface();
if (!Class)
return true;
@@ -171,7 +172,7 @@ public:
return true;
}
- bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
+ bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
IndexCtx.handleObjCCategory(D);
IndexCtx.indexTUDeclsInObjCContainer();
@@ -179,7 +180,7 @@ public:
return true;
}
- bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+ bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
const ObjCCategoryDecl *Cat = D->getCategoryDecl();
if (!Cat)
return true;
@@ -191,7 +192,7 @@ public:
return true;
}
- bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
+ bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
// Methods associated with a property, even user-declared ones, are
// handled when we handle the property.
if (D->isPropertyAccessor())
@@ -201,7 +202,7 @@ public:
return true;
}
- bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+ bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
handleObjCMethod(MD);
@@ -213,7 +214,7 @@ public:
return true;
}
- bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+ bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
ObjCPropertyDecl *PD = D->getPropertyDecl();
IndexCtx.handleSynthesizedObjCProperty(D);
@@ -240,13 +241,13 @@ public:
return true;
}
- bool VisitNamespaceDecl(NamespaceDecl *D) {
+ bool VisitNamespaceDecl(const NamespaceDecl *D) {
IndexCtx.handleNamespace(D);
IndexCtx.indexDeclContext(D);
return true;
}
- bool VisitUsingDecl(UsingDecl *D) {
+ bool VisitUsingDecl(const UsingDecl *D) {
// FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
// we should do better.
@@ -259,7 +260,7 @@ public:
return true;
}
- bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+ bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
// FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
// we should do better.
@@ -269,14 +270,14 @@ public:
return true;
}
- bool VisitClassTemplateDecl(ClassTemplateDecl *D) {
+ bool VisitClassTemplateDecl(const ClassTemplateDecl *D) {
IndexCtx.handleClassTemplate(D);
if (D->isThisDeclarationADefinition())
IndexCtx.indexDeclContext(D->getTemplatedDecl());
return true;
}
- bool VisitClassTemplateSpecializationDecl(
+ bool VisitClassTemplateSpecializationDecl(const
ClassTemplateSpecializationDecl *D) {
// FIXME: Notify subsequent callbacks if info comes from implicit
// instantiation.
@@ -287,7 +288,7 @@ public:
return true;
}
- bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+ bool VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
IndexCtx.handleFunctionTemplate(D);
FunctionDecl *FD = D->getTemplatedDecl();
handleDeclarator(FD, D);
@@ -300,13 +301,13 @@ public:
return true;
}
- bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
+ bool VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
IndexCtx.handleTypeAliasTemplate(D);
IndexCtx.indexTypeSourceInfo(D->getTemplatedDecl()->getTypeSourceInfo(), D);
return true;
}
- bool VisitImportDecl(ImportDecl *D) {
+ bool VisitImportDecl(const ImportDecl *D) {
IndexCtx.importedModule(D);
return true;
}
@@ -318,7 +319,7 @@ void IndexingContext::indexDecl(const Decl *D) {
if (D->isImplicit() && shouldIgnoreIfImplicit(D))
return;
- bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D));
+ bool Handled = IndexingDeclVisitor(*this).Visit(D);
if (!Handled && isa<DeclContext>(D))
indexDeclContext(cast<DeclContext>(D));
}
diff --git a/tools/libclang/IndexTypeSourceInfo.cpp b/tools/libclang/IndexTypeSourceInfo.cpp
index 67a06f2..2c771c8 100644
--- a/tools/libclang/IndexTypeSourceInfo.cpp
+++ b/tools/libclang/IndexTypeSourceInfo.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
-
#include "RecursiveASTVisitor.h"
using namespace clang;
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 714a36e..2a504db 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -8,28 +8,31 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
+#include "CIndexDiagnostic.h"
+#include "CIndexer.h"
+#include "CLog.h"
#include "CXCursor.h"
#include "CXSourceLocation.h"
-#include "CXTranslationUnit.h"
#include "CXString.h"
-#include "CIndexDiagnostic.h"
-#include "CIndexer.h"
-
+#include "CXTranslationUnit.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/DeclVisitor.h"
#include "clang/Frontend/ASTUnit.h"
-#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/Utils.h"
-#include "clang/Sema/SemaConsumer.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/PPCallbacks.h"
-#include "llvm/Support/MemoryBuffer.h"
+#include "clang/Lex/PPConditionalDirectiveRecord.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Sema/SemaConsumer.h"
#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/MutexGuard.h"
using namespace clang;
-using namespace cxstring;
using namespace cxtu;
using namespace cxindex;
@@ -38,6 +41,204 @@ static void indexDiagnostics(CXTranslationUnit TU, IndexingContext &IdxCtx);
namespace {
//===----------------------------------------------------------------------===//
+// Skip Parsed Bodies
+//===----------------------------------------------------------------------===//
+
+#ifdef LLVM_ON_WIN32
+
+// FIXME: On windows it is disabled since current implementation depends on
+// file inodes.
+
+class SessionSkipBodyData { };
+
+class TUSkipBodyControl {
+public:
+ TUSkipBodyControl(SessionSkipBodyData &sessionData,
+ PPConditionalDirectiveRecord &ppRec,
+ Preprocessor &pp) { }
+ bool isParsed(SourceLocation Loc, FileID FID, const FileEntry *FE) {
+ return false;
+ }
+ void finished() { }
+};
+
+#else
+
+/// \brief A "region" in source code identified by the file/offset of the
+/// preprocessor conditional directive that it belongs to.
+/// Multiple, non-consecutive ranges can be parts of the same region.
+///
+/// As an example of different regions separated by preprocessor directives:
+///
+/// \code
+/// #1
+/// #ifdef BLAH
+/// #2
+/// #ifdef CAKE
+/// #3
+/// #endif
+/// #2
+/// #endif
+/// #1
+/// \endcode
+///
+/// There are 3 regions, with non-consecutive parts:
+/// #1 is identified as the beginning of the file
+/// #2 is identified as the location of "#ifdef BLAH"
+/// #3 is identified as the location of "#ifdef CAKE"
+///
+class PPRegion {
+ ino_t ino;
+ 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) {}
+
+ ino_t getIno() const { return ino; }
+ dev_t getDev() const { return dev; }
+ 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;
+ }
+};
+
+typedef llvm::DenseSet<PPRegion> PPRegionSetTy;
+
+} // end anonymous namespace
+
+namespace llvm {
+ template <> struct isPodLike<PPRegion> {
+ static const bool value = true;
+ };
+
+ template <>
+ struct DenseMapInfo<PPRegion> {
+ static inline PPRegion getEmptyKey() {
+ return PPRegion(0, 0, unsigned(-1), 0);
+ }
+ static inline PPRegion getTombstoneKey() {
+ return PPRegion(0, 0, unsigned(-2), 0);
+ }
+
+ static unsigned getHashValue(const PPRegion &S) {
+ llvm::FoldingSetNodeID ID;
+ ID.AddInteger(S.getIno());
+ ID.AddInteger(S.getDev());
+ ID.AddInteger(S.getOffset());
+ ID.AddInteger(S.getModTime());
+ return ID.ComputeHash();
+ }
+
+ static bool isEqual(const PPRegion &LHS, const PPRegion &RHS) {
+ return LHS == RHS;
+ }
+ };
+}
+
+namespace {
+
+class SessionSkipBodyData {
+ llvm::sys::Mutex Mux;
+ PPRegionSetTy ParsedRegions;
+
+public:
+ SessionSkipBodyData() : Mux(/*recursive=*/false) {}
+ ~SessionSkipBodyData() {
+ //llvm::errs() << "RegionData: " << Skipped.size() << " - " << Skipped.getMemorySize() << "\n";
+ }
+
+ void copyTo(PPRegionSetTy &Set) {
+ llvm::MutexGuard MG(Mux);
+ Set = ParsedRegions;
+ }
+
+ void update(ArrayRef<PPRegion> Regions) {
+ llvm::MutexGuard MG(Mux);
+ ParsedRegions.insert(Regions.begin(), Regions.end());
+ }
+};
+
+class TUSkipBodyControl {
+ SessionSkipBodyData &SessionData;
+ PPConditionalDirectiveRecord &PPRec;
+ Preprocessor &PP;
+
+ PPRegionSetTy ParsedRegions;
+ SmallVector<PPRegion, 32> NewParsedRegions;
+ PPRegion LastRegion;
+ bool LastIsParsed;
+
+public:
+ TUSkipBodyControl(SessionSkipBodyData &sessionData,
+ PPConditionalDirectiveRecord &ppRec,
+ Preprocessor &pp)
+ : SessionData(sessionData), PPRec(ppRec), PP(pp) {
+ SessionData.copyTo(ParsedRegions);
+ }
+
+ bool isParsed(SourceLocation Loc, FileID FID, const FileEntry *FE) {
+ PPRegion region = getRegion(Loc, FID, FE);
+ if (region.isInvalid())
+ return false;
+
+ // Check common case, consecutive functions in the same region.
+ if (LastRegion == region)
+ return LastIsParsed;
+
+ LastRegion = region;
+ LastIsParsed = ParsedRegions.count(region);
+ if (!LastIsParsed)
+ NewParsedRegions.push_back(region);
+ return LastIsParsed;
+ }
+
+ void finished() {
+ SessionData.update(NewParsedRegions);
+ }
+
+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());
+ return PPRegion();
+ }
+
+ const SourceManager &SM = PPRec.getSourceManager();
+ assert(RegionLoc.isFileID());
+ FileID RegionFID;
+ unsigned RegionOffset;
+ llvm::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc);
+
+ if (RegionFID != FID) {
+ if (isParsedOnceInclude(FE))
+ return PPRegion(FE->getDevice(), FE->getInode(), 0,
+ FE->getModificationTime());
+ return PPRegion();
+ }
+
+ return PPRegion(FE->getDevice(), FE->getInode(), RegionOffset,
+ FE->getModificationTime());
+ }
+
+ bool isParsedOnceInclude(const FileEntry *FE) {
+ return PP.getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE);
+ }
+};
+
+#endif
+
+//===----------------------------------------------------------------------===//
// IndexPPCallbacks
//===----------------------------------------------------------------------===//
@@ -80,19 +281,20 @@ public:
}
/// MacroDefined - This hook is called whenever a macro definition is seen.
- virtual void MacroDefined(const Token &Id, const MacroInfo *MI) {
+ virtual void MacroDefined(const Token &Id, const MacroDirective *MD) {
}
/// MacroUndefined - This hook is called whenever a macro #undef is seen.
/// MI is released immediately following this callback.
- virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
+ virtual void MacroUndefined(const Token &MacroNameTok,
+ const MacroDirective *MD) {
}
/// MacroExpands - This is called by when a macro invocation is found.
- virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI,
+ virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
SourceRange Range) {
}
-
+
/// SourceRangeSkipped - This hook is called when a source range is skipped.
/// \param Range The SourceRange that was skipped. The range begins at the
/// #if/#else directive and ends after the #endif/#else directive.
@@ -106,10 +308,11 @@ public:
class IndexingConsumer : public ASTConsumer {
IndexingContext &IndexCtx;
+ TUSkipBodyControl *SKCtrl;
public:
- explicit IndexingConsumer(IndexingContext &indexCtx)
- : IndexCtx(indexCtx) { }
+ IndexingConsumer(IndexingContext &indexCtx, TUSkipBodyControl *skCtrl)
+ : IndexCtx(indexCtx), SKCtrl(skCtrl) { }
// ASTConsumer Implementation
@@ -119,6 +322,8 @@ public:
}
virtual void HandleTranslationUnit(ASTContext &Ctx) {
+ if (SKCtrl)
+ SKCtrl->finished();
}
virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
@@ -152,6 +357,32 @@ public:
IndexCtx.indexDecl(D);
}
+
+ virtual bool shouldSkipFunctionBody(Decl *D) {
+ if (!SKCtrl) {
+ // Always skip bodies.
+ return true;
+ }
+
+ const SourceManager &SM = IndexCtx.getASTContext().getSourceManager();
+ SourceLocation Loc = D->getLocation();
+ if (Loc.isMacroID())
+ return false;
+ if (SM.isInSystemHeader(Loc))
+ return true; // always skip bodies from system headers.
+
+ FileID FID;
+ unsigned Offset;
+ llvm::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
+ // Don't skip bodies from main files; this may be revisited.
+ if (SM.getMainFileID() == FID)
+ return false;
+ const FileEntry *FE = SM.getFileEntryForID(FID);
+ if (!FE)
+ return false;
+
+ return SKCtrl->isParsed(Loc, FID, FE);
+ }
};
//===----------------------------------------------------------------------===//
@@ -181,13 +412,17 @@ class IndexingFrontendAction : public ASTFrontendAction {
IndexingContext IndexCtx;
CXTranslationUnit CXTU;
+ SessionSkipBodyData *SKData;
+ OwningPtr<TUSkipBodyControl> SKCtrl;
+
public:
IndexingFrontendAction(CXClientData clientData,
IndexerCallbacks &indexCallbacks,
unsigned indexOptions,
- CXTranslationUnit cxTU)
+ CXTranslationUnit cxTU,
+ SessionSkipBodyData *skData)
: IndexCtx(clientData, indexCallbacks, indexOptions, cxTU),
- CXTU(cxTU) { }
+ CXTU(cxTU), SKData(skData) { }
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
@@ -202,7 +437,15 @@ public:
Preprocessor &PP = CI.getPreprocessor();
PP.addPPCallbacks(new IndexPPCallbacks(PP, IndexCtx));
IndexCtx.setPreprocessor(PP);
- return new IndexingConsumer(IndexCtx);
+
+ if (SKData) {
+ PPConditionalDirectiveRecord *
+ PPRec = new PPConditionalDirectiveRecord(PP.getSourceManager());
+ PP.addPPCallbacks(PPRec);
+ SKCtrl.reset(new TUSkipBodyControl(*SKData, *PPRec, PP));
+ }
+
+ return new IndexingConsumer(IndexCtx, SKCtrl.get());
}
virtual void EndSourceFileAction() {
@@ -222,6 +465,14 @@ public:
// clang_indexSourceFileUnit Implementation
//===----------------------------------------------------------------------===//
+struct IndexSessionData {
+ CXIndex CIdx;
+ OwningPtr<SessionSkipBodyData> SkipBodyData;
+
+ explicit IndexSessionData(CXIndex cIdx)
+ : CIdx(cIdx), SkipBodyData(new SessionSkipBodyData) {}
+};
+
struct IndexSourceFileInfo {
CXIndexAction idxAction;
CXClientData client_data;
@@ -253,7 +504,7 @@ struct MemBufferOwner {
static void clang_indexSourceFile_Impl(void *UserData) {
IndexSourceFileInfo *ITUI =
static_cast<IndexSourceFileInfo*>(UserData);
- CXIndex CIdx = (CXIndex)ITUI->idxAction;
+ CXIndexAction cxIdxAction = ITUI->idxAction;
CXClientData client_data = ITUI->client_data;
IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
unsigned index_callbacks_size = ITUI->index_callbacks_size;
@@ -271,7 +522,7 @@ static void clang_indexSourceFile_Impl(void *UserData) {
*out_TU = 0;
bool requestedToGetTU = (out_TU != 0);
- if (!CIdx)
+ if (!cxIdxAction)
return;
if (!client_index_callbacks || index_callbacks_size == 0)
return;
@@ -282,18 +533,21 @@ static void clang_indexSourceFile_Impl(void *UserData) {
? index_callbacks_size : sizeof(CB);
memcpy(&CB, client_index_callbacks, ClientCBSize);
- CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+ IndexSessionData *IdxSession = static_cast<IndexSessionData *>(cxIdxAction);
+ CIndexer *CXXIdx = static_cast<CIndexer *>(IdxSession->CIdx);
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
setThreadBackgroundPriority();
- CaptureDiagnosticConsumer *CaptureDiag = new CaptureDiagnosticConsumer();
+ bool CaptureDiagnostics = !Logger::isLoggingEnabled();
+
+ CaptureDiagnosticConsumer *CaptureDiag = 0;
+ if (CaptureDiagnostics)
+ CaptureDiag = new CaptureDiagnosticConsumer();
// Configure the diagnostics.
IntrusiveRefCntPtr<DiagnosticsEngine>
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
- num_command_line_args,
- command_line_args,
CaptureDiag,
/*ShouldOwnClient=*/true,
/*ShouldCloneClient=*/false));
@@ -359,7 +613,7 @@ static void clang_indexSourceFile_Impl(void *UserData) {
CInvok->getDiagnosticOpts().IgnoreWarnings = true;
ASTUnit *Unit = ASTUnit::create(CInvok.getPtr(), Diags,
- /*CaptureDiagnostics=*/true,
+ CaptureDiagnostics,
/*UserFilesAreVolatile=*/true);
OwningPtr<CXTUOwner> CXTU(new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit)));
@@ -367,9 +621,17 @@ static void clang_indexSourceFile_Impl(void *UserData) {
llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner>
CXTUCleanup(CXTU.get());
+ // Enable the skip-parsed-bodies optimization only for C++; this may be
+ // revisited.
+ bool SkipBodies = (index_options & CXIndexOpt_SkipParsedBodiesInSession) &&
+ CInvok->getLangOpts()->CPlusPlus;
+ if (SkipBodies)
+ CInvok->getFrontendOpts().SkipFunctionBodies = true;
+
OwningPtr<IndexingFrontendAction> IndexAction;
IndexAction.reset(new IndexingFrontendAction(client_data, CB,
- index_options, CXTU->getTU()));
+ index_options, CXTU->getTU(),
+ SkipBodies ? IdxSession->SkipBodyData.get() : 0));
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction>
@@ -404,7 +666,7 @@ static void clang_indexSourceFile_Impl(void *UserData) {
Persistent,
CXXIdx->getClangResourcesPath(),
OnlyLocalDecls,
- /*CaptureDiagnostics=*/true,
+ CaptureDiagnostics,
PrecompilePreamble,
CacheCodeCompletionResults,
/*IncludeBriefCommentsInCodeCompletion=*/false,
@@ -502,7 +764,7 @@ static void clang_indexTranslationUnit_Impl(void *UserData) {
if (!client_index_callbacks || index_callbacks_size == 0)
return;
- CIndexer *CXXIdx = (CIndexer*)TU->CIdx;
+ CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
setThreadBackgroundPriority();
@@ -520,13 +782,13 @@ static void clang_indexTranslationUnit_Impl(void *UserData) {
IndexCtxCleanup(IndexCtx.get());
OwningPtr<IndexingConsumer> IndexConsumer;
- IndexConsumer.reset(new IndexingConsumer(*IndexCtx));
+ IndexConsumer.reset(new IndexingConsumer(*IndexCtx, 0));
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<IndexingConsumer>
IndexConsumerCleanup(IndexConsumer.get());
- ASTUnit *Unit = static_cast<ASTUnit *>(TU->TUData);
+ ASTUnit *Unit = cxtu::getASTUnit(TU);
if (!Unit)
return;
@@ -690,12 +952,12 @@ void clang_index_setClientEntity(const CXIdxEntityInfo *info,
}
CXIndexAction clang_IndexAction_create(CXIndex CIdx) {
- // For now, CXIndexAction is featureless.
- return CIdx;
+ return new IndexSessionData(CIdx);
}
void clang_IndexAction_dispose(CXIndexAction idxAction) {
- // For now, CXIndexAction is featureless.
+ if (idxAction)
+ delete static_cast<IndexSessionData *>(idxAction);
}
int clang_indexSourceFile(CXIndexAction idxAction,
@@ -710,6 +972,11 @@ int clang_indexSourceFile(CXIndexAction idxAction,
unsigned num_unsaved_files,
CXTranslationUnit *out_TU,
unsigned TU_options) {
+ LOG_FUNC_SECTION {
+ *Log << source_filename << ": ";
+ for (int i = 0; i != num_command_line_args; ++i)
+ *Log << command_line_args[i] << " ";
+ }
IndexSourceFileInfo ITUI = { idxAction, client_data, index_callbacks,
index_callbacks_size, index_options,
@@ -760,6 +1027,9 @@ int clang_indexTranslationUnit(CXIndexAction idxAction,
unsigned index_callbacks_size,
unsigned index_options,
CXTranslationUnit TU) {
+ LOG_FUNC_SECTION {
+ *Log << TU;
+ }
IndexTranslationUnitInfo ITUI = { idxAction, client_data, index_callbacks,
index_callbacks_size, index_options, TU,
diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp
index d4daa49..3368922 100644
--- a/tools/libclang/IndexingContext.cpp
+++ b/tools/libclang/IndexingContext.cpp
@@ -8,12 +8,11 @@
//===----------------------------------------------------------------------===//
#include "IndexingContext.h"
-#include "CXTranslationUnit.h"
#include "CIndexDiagnostic.h"
-
-#include "clang/Frontend/ASTUnit.h"
+#include "CXTranslationUnit.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/Frontend/ASTUnit.h"
using namespace clang;
using namespace cxindex;
@@ -70,7 +69,7 @@ AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx)
for (AttrVec::const_iterator AttrI = D->attr_begin(), AttrE = D->attr_end();
AttrI != AttrE; ++AttrI) {
const Attr *A = *AttrI;
- CXCursor C = MakeCXCursor(A, const_cast<Decl *>(D), IdxCtx.CXTU);
+ CXCursor C = MakeCXCursor(A, D, IdxCtx.CXTU);
CXIdxLoc Loc = IdxCtx.getIndexLoc(A->getLocation());
switch (C.kind) {
default:
@@ -166,16 +165,16 @@ SourceLocation IndexingContext::CXXBasesListInfo::getBaseLoc(
if (TL.isNull())
return Loc;
- if (const QualifiedTypeLoc *QL = dyn_cast<QualifiedTypeLoc>(&TL))
- TL = QL->getUnqualifiedLoc();
+ if (QualifiedTypeLoc QL = TL.getAs<QualifiedTypeLoc>())
+ TL = QL.getUnqualifiedLoc();
- if (const ElaboratedTypeLoc *EL = dyn_cast<ElaboratedTypeLoc>(&TL))
- return EL->getNamedTypeLoc().getBeginLoc();
- if (const DependentNameTypeLoc *DL = dyn_cast<DependentNameTypeLoc>(&TL))
- return DL->getNameLoc();
- if (const DependentTemplateSpecializationTypeLoc *
- DTL = dyn_cast<DependentTemplateSpecializationTypeLoc>(&TL))
- return DTL->getTemplateNameLoc();
+ if (ElaboratedTypeLoc EL = TL.getAs<ElaboratedTypeLoc>())
+ return EL.getNamedTypeLoc().getBeginLoc();
+ if (DependentNameTypeLoc DL = TL.getAs<DependentNameTypeLoc>())
+ return DL.getNameLoc();
+ if (DependentTemplateSpecializationTypeLoc DTL =
+ TL.getAs<DependentTemplateSpecializationTypeLoc>())
+ return DTL.getTemplateNameLoc();
return Loc;
}
@@ -197,11 +196,11 @@ const char *ScratchAlloc::copyCStr(StringRef Str) {
void IndexingContext::setASTContext(ASTContext &ctx) {
Ctx = &ctx;
- static_cast<ASTUnit*>(CXTU->TUData)->setASTContext(&ctx);
+ cxtu::getASTUnit(CXTU)->setASTContext(&ctx);
}
void IndexingContext::setPreprocessor(Preprocessor &PP) {
- static_cast<ASTUnit*>(CXTU->TUData)->setPreprocessor(&PP);
+ cxtu::getASTUnit(CXTU)->setPreprocessor(&PP);
}
bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
@@ -232,7 +231,9 @@ bool IndexingContext::shouldAbort() {
void IndexingContext::enteredMainFile(const FileEntry *File) {
if (File && CB.enteredMainFile) {
- CXIdxClientFile idxFile = CB.enteredMainFile(ClientData, (CXFile)File, 0);
+ CXIdxClientFile idxFile =
+ CB.enteredMainFile(ClientData,
+ static_cast<CXFile>(const_cast<FileEntry *>(File)), 0);
FileMap[File] = idxFile;
}
}
@@ -248,7 +249,8 @@ void IndexingContext::ppIncludedFile(SourceLocation hashLoc,
ScratchAlloc SA(*this);
CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),
SA.toCStr(filename),
- (CXFile)File,
+ static_cast<CXFile>(
+ const_cast<FileEntry *>(File)),
isImport, isAngled, isModuleImport };
CXIdxClientFile idxFile = CB.ppIncludedFile(ClientData, &Info);
FileMap[File] = idxFile;
@@ -264,7 +266,8 @@ void IndexingContext::importedModule(const ImportDecl *ImportD) {
std::string ModuleName = Mod->getFullModuleName();
CXIdxImportedASTFileInfo Info = {
- (CXFile)Mod->getASTFile(),
+ static_cast<CXFile>(
+ const_cast<FileEntry *>(Mod->getASTFile())),
Mod,
getIndexLoc(ImportD->getLocation()),
ImportD->isImplicit()
@@ -278,7 +281,8 @@ void IndexingContext::importedPCH(const FileEntry *File) {
return;
CXIdxImportedASTFileInfo Info = {
- (CXFile)File,
+ static_cast<CXFile>(
+ const_cast<FileEntry *>(File)),
/*module=*/NULL,
getIndexLoc(SourceLocation()),
/*isImplicit=*/false
@@ -365,8 +369,18 @@ bool IndexingContext::handleObjCContainer(const ObjCContainerDecl *D,
}
bool IndexingContext::handleFunction(const FunctionDecl *D) {
- DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
- D->isThisDeclarationADefinition());
+ bool isDef = D->isThisDeclarationADefinition();
+ bool isContainer = isDef;
+ bool isSkipped = false;
+ if (D->hasSkippedBody()) {
+ isSkipped = true;
+ isDef = true;
+ isContainer = false;
+ }
+
+ DeclInfo DInfo(!D->isFirstDeclaration(), isDef, isContainer);
+ if (isSkipped)
+ DInfo.flags |= CXIdxDeclFlag_Skipped;
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
}
@@ -549,8 +563,18 @@ bool IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
}
bool IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
- DeclInfo DInfo(!D->isCanonicalDecl(), D->isThisDeclarationADefinition(),
- D->isThisDeclarationADefinition());
+ bool isDef = D->isThisDeclarationADefinition();
+ bool isContainer = isDef;
+ bool isSkipped = false;
+ if (D->hasSkippedBody()) {
+ isSkipped = true;
+ isDef = true;
+ isContainer = false;
+ }
+
+ DeclInfo DInfo(!D->isCanonicalDecl(), isDef, isContainer);
+ if (isSkipped)
+ DInfo.flags |= CXIdxDeclFlag_Skipped;
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
}
@@ -625,8 +649,7 @@ bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
if (!D)
return false;
- CXCursor Cursor = E ? MakeCXCursor(const_cast<Expr*>(E),
- const_cast<Decl*>(cast<Decl>(DC)), CXTU)
+ CXCursor Cursor = E ? MakeCXCursor(E, cast<Decl>(DC), CXTU)
: getRefCursor(D, Loc);
return handleReference(D, Loc, Cursor, Parent, DC, E, Kind);
}
@@ -808,7 +831,7 @@ IndexingContext::getEntityContainer(const Decl *D) const {
if (const ClassTemplateDecl *ClassTempl = dyn_cast<ClassTemplateDecl>(D)) {
DC = ClassTempl->getTemplatedDecl();
- } if (const FunctionTemplateDecl *
+ } else if (const FunctionTemplateDecl *
FuncTempl = dyn_cast<FunctionTemplateDecl>(D)) {
DC = FuncTempl->getTemplatedDecl();
}
@@ -844,7 +867,7 @@ CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
if (Loc.isInvalid())
return idxLoc;
- idxLoc.ptr_data[0] = (void*)this;
+ idxLoc.ptr_data[0] = const_cast<IndexingContext *>(this);
idxLoc.int_data = Loc.getRawEncoding();
return idxLoc;
}
@@ -870,7 +893,7 @@ void IndexingContext::translateLoc(SourceLocation Loc,
if (indexFile)
*indexFile = getIndexFile(FE);
if (file)
- *file = (void *)FE;
+ *file = const_cast<FileEntry *>(FE);
if (line)
*line = SM.getLineNumber(FID, FileOffset);
if (column)
diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h
index 0fc7238..c9097c5 100644
--- a/tools/libclang/IndexingContext.h
+++ b/tools/libclang/IndexingContext.h
@@ -7,11 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#include "Index_Internal.h"
#include "CXCursor.h"
-
-#include "clang/AST/DeclObjC.h"
+#include "Index_Internal.h"
#include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclObjC.h"
#include "llvm/ADT/DenseSet.h"
#include <deque>
@@ -89,6 +88,7 @@ struct DeclInfo : public CXIdxDeclInfo {
attributes = 0;
numAttributes = 0;
declAsContainer = semanticContainer = lexicalContainer = 0;
+ flags = 0;
}
DeclInfo(DInfoKind K,
bool isRedeclaration, bool isDefinition, bool isContainer)
@@ -99,6 +99,7 @@ struct DeclInfo : public CXIdxDeclInfo {
attributes = 0;
numAttributes = 0;
declAsContainer = semanticContainer = lexicalContainer = 0;
+ flags = 0;
}
};
@@ -493,7 +494,7 @@ private:
void getContainerInfo(const DeclContext *DC, ContainerInfo &ContInfo);
CXCursor getCursor(const Decl *D) {
- return cxcursor::MakeCXCursor(const_cast<Decl*>(D), CXTU);
+ return cxcursor::MakeCXCursor(D, CXTU);
}
CXCursor getRefCursor(const NamedDecl *D, SourceLocation Loc);
diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile
index 93f63cf..f33f345 100644
--- a/tools/libclang/Makefile
+++ b/tools/libclang/Makefile
@@ -16,12 +16,15 @@ LINK_LIBS_IN_SHARED = 1
SHARED_LIBRARY = 1
include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
-USEDLIBS = clangARCMigrate.a clangRewriteCore.a clangRewriteFrontend.a \
- clangFrontend.a clangDriver.a \
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc
+USEDLIBS = clangFrontend.a clangDriver.a \
+ clangTooling.a \
clangSerialization.a \
- clangParse.a clangSema.a clangEdit.a clangAnalysis.a \
- clangAST.a clangLex.a clangTooling.a clangBasic.a
+ clangParse.a clangSema.a \
+ clangARCMigrate.a clangRewriteFrontend.a clangRewriteCore.a \
+ clangAnalysis.a clangEdit.a \
+ clangAST.a clangLex.a clangBasic.a \
+ clangFormat.a
include $(CLANG_LEVEL)/Makefile
@@ -54,7 +57,7 @@ ifeq ($(HOST_OS),Darwin)
endif
# If we're doing an Apple-style build, add the LTO object path.
- ifeq ($(RC_BUILDIT),YES)
+ ifeq ($(RC_XBS),YES)
TempFile := $(shell mkdir -p ${OBJROOT}/dSYMs ; mktemp ${OBJROOT}/dSYMs/clang-lto.XXXXXX)
LLVMLibsOptions += -Wl,-object_path_lto -Wl,$(TempFile)
endif
diff --git a/tools/libclang/RecursiveASTVisitor.h b/tools/libclang/RecursiveASTVisitor.h
index 4844204..5862e12 100644
--- a/tools/libclang/RecursiveASTVisitor.h
+++ b/tools/libclang/RecursiveASTVisitor.h
@@ -18,6 +18,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
@@ -535,7 +536,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
#define ABSTRACT_TYPELOC(CLASS, BASE)
#define TYPELOC(CLASS, BASE) \
case TypeLoc::CLASS: \
- return getDerived().Traverse##CLASS##TypeLoc(*cast<CLASS##TypeLoc>(&TL));
+ return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
#include "clang/AST/TypeLocNodes.def"
}
@@ -1199,6 +1200,8 @@ DEF_TRAVERSE_DECL(BlockDecl, {
return true;
})
+DEF_TRAVERSE_DECL(EmptyDecl, { })
+
DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
TRY_TO(TraverseStmt(D->getAsmString()));
})
@@ -1323,6 +1326,14 @@ DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
DEF_TRAVERSE_DECL(UsingShadowDecl, { })
+DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
+ for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
+ E = D->varlist_end();
+ I != E; ++I) {
+ TRY_TO(TraverseStmt(*I));
+ }
+ })
+
// A helper method for TemplateDecl's children.
template<typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
@@ -2027,8 +2038,7 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
// Visit the whole type.
TRY_TO(TraverseTypeLoc(TL));
- } else if (isa<FunctionProtoTypeLoc>(TL)) {
- FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL);
+ } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
if (S->hasExplicitParameters()) {
// Visit parameters.
for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) {
diff --git a/tools/libclang/SimpleFormatContext.h b/tools/libclang/SimpleFormatContext.h
new file mode 100644
index 0000000..016d0b6
--- /dev/null
+++ b/tools/libclang/SimpleFormatContext.h
@@ -0,0 +1,75 @@
+//===--- 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 4495b66..d99f24e 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -98,6 +98,8 @@ clang_equalLocations
clang_equalRanges
clang_equalTypes
clang_executeOnThread
+clang_findIncludesInFile
+clang_findIncludesInFileWithBlock
clang_findReferencesInFile
clang_findReferencesInFileWithBlock
clang_formatDiagnostic
@@ -160,10 +162,13 @@ clang_getElementType
clang_getEnumConstantDeclUnsignedValue
clang_getEnumConstantDeclValue
clang_getEnumDeclIntegerType
+clang_getFieldDeclBitWidth
clang_getExpansionLocation
clang_getFile
+clang_getFileLocation
clang_getFileName
clang_getFileTime
+clang_getFileUniqueID
clang_getFunctionTypeCallingConv
clang_getIBOutletCollectionType
clang_getIncludedFile
@@ -202,6 +207,7 @@ clang_getTranslationUnitCursor
clang_getTranslationUnitSpelling
clang_getTypeDeclaration
clang_getTypeKindSpelling
+clang_getTypeSpelling
clang_getTypedefDeclUnderlyingType
clang_hashCursor
clang_indexLoc_getCXSourceLocation
@@ -250,6 +256,7 @@ clang_tokenize
clang_CompilationDatabase_fromDirectory
clang_CompilationDatabase_dispose
clang_CompilationDatabase_getCompileCommands
+clang_CompilationDatabase_getAllCompileCommands
clang_CompileCommands_dispose
clang_CompileCommands_getSize
clang_CompileCommands_getCommand
OpenPOWER on IntegriCloud