aboutsummaryrefslogtreecommitdiff
path: root/tools/libclang/CIndex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libclang/CIndex.cpp')
-rw-r--r--tools/libclang/CIndex.cpp1000
1 files changed, 682 insertions, 318 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index f53e5c1c4951..fc8703aface1 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -15,7 +15,6 @@
#include "CIndexer.h"
#include "CIndexDiagnostic.h"
#include "CLog.h"
-#include "CXComment.h"
#include "CXCursor.h"
#include "CXSourceLocation.h"
#include "CXString.h"
@@ -25,6 +24,8 @@
#include "clang/AST/Attr.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticCategories.h"
+#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/Version.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
@@ -34,13 +35,15 @@
#include "clang/Lex/Lexer.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
+#include "clang/Serialization/SerializationDiagnostic.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Program.h"
@@ -50,7 +53,11 @@
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
-#if HAVE_PTHREAD_H
+#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
+#define USE_DARWIN_THREADS
+#endif
+
+#ifdef USE_DARWIN_THREADS
#include <pthread.h>
#endif
@@ -61,17 +68,30 @@ using namespace clang::cxindex;
CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
if (!AU)
- return 0;
+ return nullptr;
+ assert(CIdx);
CXTranslationUnit D = new CXTranslationUnitImpl();
D->CIdx = CIdx;
D->TheASTUnit = AU;
D->StringPool = new cxstring::CXStringPool();
- D->Diagnostics = 0;
+ D->Diagnostics = nullptr;
D->OverridenCursorsPool = createOverridenCXCursorsPool();
- D->CommentToXML = 0;
+ D->CommentToXML = nullptr;
return D;
}
+bool cxtu::isASTReadError(ASTUnit *AU) {
+ for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
+ DEnd = AU->stored_diag_end();
+ D != DEnd; ++D) {
+ if (D->getLevel() >= DiagnosticsEngine::Error &&
+ DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
+ diag::DiagCat_AST_Deserialization_Issue)
+ return true;
+ }
+ return false;
+}
+
cxtu::CXTUOwner::~CXTUOwner() {
if (TU)
clang_disposeTranslationUnit(TU);
@@ -298,7 +318,7 @@ bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
if (Outer.isInvalid())
return false;
- llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
+ std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Length = 0;
Unit->findFileRegionDecls(File, Offset, Length, Decls);
}
@@ -306,7 +326,7 @@ bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
assert(!Decls.empty());
bool VisitedAtLeastOnce = false;
- DeclContext *CurDC = 0;
+ DeclContext *CurDC = nullptr;
SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Decl *D = *DIt;
@@ -335,7 +355,7 @@ bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
FileDI_current = &DIt;
FileDE_current = DE;
} else {
- FileDI_current = 0;
+ FileDI_current = nullptr;
}
if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
@@ -769,7 +789,7 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
// 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.getReturnLoc())) ||
(!FTL && Visit(TL)))
return true;
@@ -779,8 +799,9 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
return true;
// Visit the declaration name.
- if (VisitDeclarationNameInfo(ND->getNameInfo()))
- return true;
+ if (!isa<CXXDestructorDecl>(ND))
+ if (VisitDeclarationNameInfo(ND->getNameInfo()))
+ return true;
// FIXME: Visit explicitly-specified template arguments!
@@ -795,13 +816,11 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
// Find the initializers that were written in the source.
SmallVector<CXXCtorInitializer *, 4> WrittenInits;
- for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
- IEnd = Constructor->init_end();
- I != IEnd; ++I) {
- if (!(*I)->isWritten())
+ for (auto *I : Constructor->inits()) {
+ if (!I->isWritten())
continue;
- WrittenInits.push_back(*I);
+ WrittenInits.push_back(I);
}
// Sort the initializers in source order
@@ -895,14 +914,12 @@ bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
}
bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
- if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
+ if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
if (Visit(TSInfo->getTypeLoc()))
return true;
- for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
- PEnd = ND->param_end();
- P != PEnd; ++P) {
- if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
+ for (const auto *P : ND->params()) {
+ if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
return true;
}
@@ -934,19 +951,6 @@ static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
}
}
-namespace {
- struct ContainerDeclsSort {
- SourceManager &SM;
- ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
- bool operator()(Decl *A, Decl *B) {
- SourceLocation L_A = A->getLocStart();
- SourceLocation L_B = B->getLocStart();
- assert(L_A.isValid() && L_B.isValid());
- return SM.isBeforeInTranslationUnit(L_A, L_B);
- }
- };
-}
-
bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
// FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
// an @implementation can lexically contain Decls that are not properly
@@ -978,18 +982,21 @@ bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
// Get all the Decls in the DeclContext, and sort them with the
// additional ones we've collected. Then visit them.
- for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
- I!=E; ++I) {
- Decl *subDecl = *I;
- if (!subDecl || subDecl->getLexicalDeclContext() != D ||
- subDecl->getLocStart().isInvalid())
+ for (auto *SubDecl : D->decls()) {
+ if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
+ SubDecl->getLocStart().isInvalid())
continue;
- DeclsInContainer.push_back(subDecl);
+ DeclsInContainer.push_back(SubDecl);
}
// Now sort the Decls so that they appear in lexical order.
std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
- ContainerDeclsSort(SM));
+ [&SM](Decl *A, Decl *B) {
+ SourceLocation L_A = A->getLocStart();
+ SourceLocation L_B = B->getLocStart();
+ assert(L_A.isValid() && L_B.isValid());
+ return SM.isBeforeInTranslationUnit(L_A, L_B);
+ });
// Now visit the decls.
for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
@@ -1517,11 +1524,11 @@ bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
bool SkipResultType) {
- if (!SkipResultType && Visit(TL.getResultLoc()))
+ if (!SkipResultType && Visit(TL.getReturnLoc()))
return true;
- for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
- if (Decl *D = TL.getArg(I))
+ for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
+ if (Decl *D = TL.getParam(I))
if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
return true;
@@ -1542,6 +1549,10 @@ bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
return Visit(TL.getOriginalLoc());
}
+bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
+ return Visit(TL.getOriginalLoc());
+}
+
bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
// Visit the template name.
@@ -1651,9 +1662,8 @@ bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
return true;
if (D->isCompleteDefinition()) {
- for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
- E = D->bases_end(); I != E; ++I) {
- if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
+ for (const auto &I : D->bases()) {
+ if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
return true;
}
}
@@ -1662,9 +1672,8 @@ bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
}
bool CursorVisitor::VisitAttributes(Decl *D) {
- for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
- i != e; ++i)
- if (Visit(MakeCXCursor(*i, D, TU)))
+ for (const auto *I : D->attrs())
+ if (Visit(MakeCXCursor(I, D, TU)))
return true;
return false;
@@ -1699,7 +1708,7 @@ class DeclVisit : public VisitorJob {
public:
DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
VisitorJob(parent, VisitorJob::DeclVisitKind,
- D, isFirst ? (void*) 1 : (void*) 0) {}
+ D, isFirst ? (void*) 1 : (void*) nullptr) {}
static bool classof(const VisitorJob *VJ) {
return VJ->getKind() == DeclVisitKind;
}
@@ -1775,6 +1784,8 @@ public:
return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
case Stmt::DependentScopeDeclRefExprClass:
return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
+ case Stmt::OMPCriticalDirectiveClass:
+ return cast<OMPCriticalDirective>(S)->getDirectiveName();
}
}
};
@@ -1835,8 +1846,6 @@ public:
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);
@@ -1848,6 +1857,20 @@ public:
void VisitLambdaExpr(const LambdaExpr *E);
void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
void VisitOMPParallelDirective(const OMPParallelDirective *D);
+ void VisitOMPSimdDirective(const OMPSimdDirective *D);
+ void VisitOMPForDirective(const OMPForDirective *D);
+ void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
+ void VisitOMPSectionDirective(const OMPSectionDirective *D);
+ void VisitOMPSingleDirective(const OMPSingleDirective *D);
+ void VisitOMPMasterDirective(const OMPMasterDirective *D);
+ void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
+ void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
+ void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
+ void VisitOMPTaskDirective(const OMPTaskDirective *D);
+ void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
+ void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
+ void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
+ void VisitOMPFlushDirective(const OMPFlushDirective *D);
private:
void AddDeclarationNameInfo(const Stmt *S);
@@ -1920,14 +1943,46 @@ public:
#include "clang/Basic/OpenMPKinds.def"
};
+void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
+ Visitor->AddStmt(C->getCondition());
+}
+
+void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
+ Visitor->AddStmt(C->getCondition());
+}
+
+void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
+ Visitor->AddStmt(C->getNumThreads());
+}
+
+void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
+ Visitor->AddStmt(C->getSafelen());
+}
+
+void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
+ Visitor->AddStmt(C->getNumForLoops());
+}
+
void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
+void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
+
+void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
+ Visitor->AddStmt(C->getChunkSize());
+}
+
+void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
+
+void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
+
+void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
+
+void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
+
template<typename T>
void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
- for (typename T::varlist_const_iterator I = Node->varlist_begin(),
- E = Node->varlist_end();
- I != E; ++I)
- Visitor->AddStmt(*I);
+ for (const auto *I : Node->varlists())
+ Visitor->AddStmt(I);
}
void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
@@ -1937,9 +1992,34 @@ void OMPClauseEnqueue::VisitOMPFirstprivateClause(
const OMPFirstprivateClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseEnqueue::VisitOMPLastprivateClause(
+ const OMPLastprivateClause *C) {
+ VisitOMPClauseList(C);
+}
void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
+ VisitOMPClauseList(C);
+}
+void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
+ VisitOMPClauseList(C);
+ Visitor->AddStmt(C->getStep());
+}
+void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
+ VisitOMPClauseList(C);
+ Visitor->AddStmt(C->getAlignment());
+}
+void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
+ VisitOMPClauseList(C);
+}
+void
+OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
+ VisitOMPClauseList(C);
+}
+void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
+ VisitOMPClauseList(C);
+}
}
void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
@@ -2062,9 +2142,8 @@ void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
unsigned size = WL.size();
bool isFirst = true;
- for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
- D != DEnd; ++D) {
- AddDecl(*D, isFirst);
+ for (const auto *D : S->decls()) {
+ AddDecl(D, isFirst);
isFirst = false;
}
if (size == WL.size())
@@ -2181,15 +2260,6 @@ void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
AddDecl(W->getConditionVariable());
}
-void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
- AddTypeLoc(E->getQueriedTypeSourceInfo());
-}
-
-void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
- AddTypeLoc(E->getRhsTypeSourceInfo());
- AddTypeLoc(E->getLhsTypeSourceInfo());
-}
-
void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
for (unsigned I = E->getNumArgs(); I > 0; --I)
AddTypeLoc(E->getArg(I-1));
@@ -2243,6 +2313,66 @@ void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
VisitOMPExecutableDirective(D);
}
+void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
+ VisitOMPExecutableDirective(D);
+ AddDeclarationNameInfo(D);
+}
+
+void
+EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPParallelSectionsDirective(
+ const OMPParallelSectionsDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void
+EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
+ VisitOMPExecutableDirective(D);
+}
+
void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
}
@@ -2338,7 +2468,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
case CXChildVisit_Continue: break;
case CXChildVisit_Recurse:
if (PostChildrenVisitor)
- WL.push_back(PostChildrenVisit(0, Cursor));
+ WL.push_back(PostChildrenVisit(nullptr, Cursor));
EnqueueWorkList(WL, S);
break;
}
@@ -2444,12 +2574,12 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
TL.getAs<FunctionProtoTypeLoc>()) {
if (E->hasExplicitParameters()) {
// Visit parameters.
- for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
- if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
+ if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
return true;
} else {
// Visit result type.
- if (Visit(Proto.getResultLoc()))
+ if (Visit(Proto.getReturnLoc()))
return true;
}
}
@@ -2467,7 +2597,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
}
bool CursorVisitor::Visit(const Stmt *S) {
- VisitorWorkList *WL = 0;
+ VisitorWorkList *WL = nullptr;
if (!WorkListFreeList.empty()) {
WL = WorkListFreeList.back();
WL->clear();
@@ -2485,10 +2615,10 @@ bool CursorVisitor::Visit(const Stmt *S) {
namespace {
typedef SmallVector<SourceRange, 4> RefNamePieces;
-RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
- const DeclarationNameInfo &NI,
- const SourceRange &QLoc,
- const ASTTemplateArgumentListInfo *TemplateArgs = 0){
+RefNamePieces
+buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
+ const DeclarationNameInfo &NI, const SourceRange &QLoc,
+ const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
@@ -2528,9 +2658,6 @@ RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
// Misc. API hooks.
//===----------------------------------------------------------------------===//
-static llvm::sys::Mutex EnableMultithreadingMutex;
-static bool EnabledMultithreading;
-
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
@@ -2539,22 +2666,28 @@ static void fatal_error_handler(void *user_data, const std::string& reason,
::abort();
}
+namespace {
+struct RegisterFatalErrorHandler {
+ RegisterFatalErrorHandler() {
+ llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
+ }
+};
+}
+
+static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
+
extern "C" {
CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
int displayDiagnostics) {
// We use crash recovery to make some of our APIs more reliable, implicitly
// enable it.
- llvm::CrashRecoveryContext::Enable();
+ if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
+ llvm::CrashRecoveryContext::Enable();
- // Enable support for multithreading in LLVM.
- {
- llvm::sys::ScopedLock L(EnableMultithreadingMutex);
- if (!EnabledMultithreading) {
- llvm::install_fatal_error_handler(fatal_error_handler, 0);
- llvm::llvm_start_multithreaded();
- EnabledMultithreading = true;
- }
- }
+ // Look through the managed static to trigger construction of the managed
+ // static which registers our fatal error handler. This ensures it is only
+ // registered once.
+ (void)*RegisterFatalErrorHandlerOnce;
CIndexer *CIdxr = new CIndexer();
if (excludeDeclarationsFromPCH)
@@ -2594,11 +2727,26 @@ void clang_toggleCrashRecovery(unsigned isEnabled) {
else
llvm::CrashRecoveryContext::Disable();
}
-
+
CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
const char *ast_filename) {
- if (!CIdx || !ast_filename)
- return 0;
+ CXTranslationUnit TU;
+ enum CXErrorCode Result =
+ clang_createTranslationUnit2(CIdx, ast_filename, &TU);
+ (void)Result;
+ assert((TU && Result == CXError_Success) ||
+ (!TU && Result != CXError_Success));
+ return TU;
+}
+
+enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
+ const char *ast_filename,
+ CXTranslationUnit *out_TU) {
+ if (out_TU)
+ *out_TU = nullptr;
+
+ if (!CIdx || !ast_filename || !out_TU)
+ return CXError_InvalidArguments;
LOG_FUNC_SECTION {
*Log << ast_filename;
@@ -2608,20 +2756,20 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
FileSystemOptions FileSystemOpts;
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
- ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
- CXXIdx->getOnlyLocalDecls(),
- 0, 0,
- /*CaptureDiagnostics=*/true,
- /*AllowPCHWithCompilerErrors=*/true,
- /*UserFilesAreVolatile=*/true);
- return MakeCXTranslationUnit(CXXIdx, TU);
+ ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
+ CXXIdx->getOnlyLocalDecls(), None,
+ /*CaptureDiagnostics=*/true,
+ /*AllowPCHWithCompilerErrors=*/true,
+ /*UserFilesAreVolatile=*/true);
+ *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
+ return *out_TU ? CXError_Success : CXError_Failure;
}
unsigned clang_defaultEditingTranslationUnitOptions() {
return CXTranslationUnit_PrecompiledPreamble |
CXTranslationUnit_CacheCompletionResults;
}
-
+
CXTranslationUnit
clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
const char *source_filename,
@@ -2641,25 +2789,30 @@ struct ParseTranslationUnitInfo {
const char *source_filename;
const char *const *command_line_args;
int num_command_line_args;
- struct CXUnsavedFile *unsaved_files;
- unsigned num_unsaved_files;
+ ArrayRef<CXUnsavedFile> unsaved_files;
unsigned options;
- CXTranslationUnit result;
+ CXTranslationUnit *out_TU;
+ CXErrorCode &result;
};
static void clang_parseTranslationUnit_Impl(void *UserData) {
- ParseTranslationUnitInfo *PTUI =
- static_cast<ParseTranslationUnitInfo*>(UserData);
+ const ParseTranslationUnitInfo *PTUI =
+ static_cast<ParseTranslationUnitInfo *>(UserData);
CXIndex CIdx = PTUI->CIdx;
const char *source_filename = PTUI->source_filename;
const char * const *command_line_args = PTUI->command_line_args;
int num_command_line_args = PTUI->num_command_line_args;
- struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
- unsigned num_unsaved_files = PTUI->num_unsaved_files;
unsigned options = PTUI->options;
- PTUI->result = 0;
+ CXTranslationUnit *out_TU = PTUI->out_TU;
+
+ // Set up the initial return values.
+ if (out_TU)
+ *out_TU = nullptr;
- if (!CIdx)
+ // Check arguments.
+ if (!CIdx || !out_TU) {
+ PTUI->result = CXError_InvalidArguments;
return;
+ }
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
@@ -2670,7 +2823,7 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
// FIXME: Add a flag for modules.
TranslationUnitKind TUKind
= (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
- bool CacheCodeCompetionResults
+ bool CacheCodeCompletionResults
= options & CXTranslationUnit_CacheCompletionResults;
bool IncludeBriefCommentsInCodeCompletion
= options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
@@ -2684,25 +2837,23 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
// Recover resources if we crash before exiting this function.
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
- DiagCleanup(Diags.getPtr());
+ DiagCleanup(Diags.get());
- OwningPtr<std::vector<ASTUnit::RemappedFile> >
- RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
+ std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
+ new std::vector<ASTUnit::RemappedFile>());
// Recover resources if we crash before exiting this function.
llvm::CrashRecoveryContextCleanupRegistrar<
std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
- for (unsigned I = 0; I != num_unsaved_files; ++I) {
- StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
- const llvm::MemoryBuffer *Buffer
- = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
- RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
- Buffer));
+ for (auto &UF : PTUI->unsaved_files) {
+ llvm::MemoryBuffer *MB =
+ llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
+ RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
}
- OwningPtr<std::vector<const char *> >
- Args(new std::vector<const char*>());
+ std::unique_ptr<std::vector<const char *>> Args(
+ new std::vector<const char *>());
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
@@ -2742,27 +2893,15 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
}
unsigned NumErrors = Diags->getClient()->getNumErrors();
- OwningPtr<ASTUnit> ErrUnit;
- OwningPtr<ASTUnit> Unit(
- ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
- /* vector::data() not portable */,
- Args->size() ? (&(*Args)[0] + Args->size()) :0,
- Diags,
- CXXIdx->getClangResourcesPath(),
- CXXIdx->getOnlyLocalDecls(),
- /*CaptureDiagnostics=*/true,
- RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
- RemappedFiles->size(),
- /*RemappedFilesKeepOriginalName=*/true,
- PrecompilePreamble,
- TUKind,
- CacheCodeCompetionResults,
- IncludeBriefCommentsInCodeCompletion,
- /*AllowPCHWithCompilerErrors=*/true,
- SkipFunctionBodies,
- /*UserFilesAreVolatile=*/true,
- ForSerialization,
- &ErrUnit));
+ std::unique_ptr<ASTUnit> ErrUnit;
+ std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
+ Args->data(), Args->data() + Args->size(), Diags,
+ CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
+ /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
+ /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
+ CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
+ /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
+ /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
if (NumErrors != Diags->getClient()->getNumErrors()) {
// Make sure to check that 'Unit' is non-NULL.
@@ -2770,24 +2909,60 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
}
- PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
+ if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
+ PTUI->result = CXError_ASTReadError;
+ } else {
+ *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
+ PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
+ }
}
-CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
- const char *source_filename,
- const char * const *command_line_args,
- int num_command_line_args,
- struct CXUnsavedFile *unsaved_files,
- unsigned num_unsaved_files,
- unsigned options) {
+
+CXTranslationUnit
+clang_parseTranslationUnit(CXIndex CIdx,
+ const char *source_filename,
+ const char *const *command_line_args,
+ int num_command_line_args,
+ struct CXUnsavedFile *unsaved_files,
+ unsigned num_unsaved_files,
+ unsigned options) {
+ CXTranslationUnit TU;
+ enum CXErrorCode Result = clang_parseTranslationUnit2(
+ CIdx, source_filename, command_line_args, num_command_line_args,
+ unsaved_files, num_unsaved_files, options, &TU);
+ (void)Result;
+ assert((TU && Result == CXError_Success) ||
+ (!TU && Result != CXError_Success));
+ return TU;
+}
+
+enum CXErrorCode clang_parseTranslationUnit2(
+ CXIndex CIdx,
+ const char *source_filename,
+ const char *const *command_line_args,
+ int num_command_line_args,
+ struct CXUnsavedFile *unsaved_files,
+ unsigned num_unsaved_files,
+ unsigned options,
+ CXTranslationUnit *out_TU) {
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 };
+ if (num_unsaved_files && !unsaved_files)
+ return CXError_InvalidArguments;
+
+ CXErrorCode result = CXError_Failure;
+ ParseTranslationUnitInfo PTUI = {
+ CIdx,
+ source_filename,
+ command_line_args,
+ num_command_line_args,
+ llvm::makeArrayRef(unsaved_files, num_unsaved_files),
+ options,
+ out_TU,
+ result};
llvm::CrashRecoveryContext CRC;
if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
@@ -2810,13 +2985,14 @@ CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
fprintf(stderr, "],\n");
fprintf(stderr, " 'options' : %d,\n", options);
fprintf(stderr, "}\n");
-
- return 0;
+
+ return CXError_Crashed;
} else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
- PrintLibclangResourceUsage(PTUI.result);
+ if (CXTranslationUnit *TU = PTUI.out_TU)
+ PrintLibclangResourceUsage(*TU);
}
-
- return PTUI.result;
+
+ return result;
}
unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
@@ -2852,8 +3028,10 @@ int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
*Log << TU << ' ' << FileName;
}
- if (!TU)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
return CXSaveError_InvalidTU;
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
@@ -2896,7 +3074,8 @@ void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
if (CTUnit) {
// If the translation unit has been marked as unsafe to free, just discard
// it.
- if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
+ ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
+ if (Unit && Unit->isUnsafeToFree())
return;
delete cxtu::getASTUnit(CTUnit);
@@ -2914,28 +3093,28 @@ unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
struct ReparseTranslationUnitInfo {
CXTranslationUnit TU;
- unsigned num_unsaved_files;
- struct CXUnsavedFile *unsaved_files;
+ ArrayRef<CXUnsavedFile> unsaved_files;
unsigned options;
- int result;
+ CXErrorCode &result;
};
static void clang_reparseTranslationUnit_Impl(void *UserData) {
- ReparseTranslationUnitInfo *RTUI =
- static_cast<ReparseTranslationUnitInfo*>(UserData);
+ const ReparseTranslationUnitInfo *RTUI =
+ static_cast<ReparseTranslationUnitInfo *>(UserData);
CXTranslationUnit TU = RTUI->TU;
- if (!TU)
+ unsigned options = RTUI->options;
+ (void) options;
+
+ // Check arguments.
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ RTUI->result = CXError_InvalidArguments;
return;
+ }
// Reset the associated diagnostics.
delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
- TU->Diagnostics = 0;
-
- unsigned num_unsaved_files = RTUI->num_unsaved_files;
- struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
- unsigned options = RTUI->options;
- (void) options;
- RTUI->result = 1;
+ TU->Diagnostics = nullptr;
CIndexer *CXXIdx = TU->CIdx;
if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
@@ -2943,25 +3122,24 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) {
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
-
- OwningPtr<std::vector<ASTUnit::RemappedFile> >
- RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
-
+
+ std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
+ new std::vector<ASTUnit::RemappedFile>());
+
// Recover resources if we crash before exiting this function.
llvm::CrashRecoveryContextCleanupRegistrar<
std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
-
- for (unsigned I = 0; I != num_unsaved_files; ++I) {
- StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
- const llvm::MemoryBuffer *Buffer
- = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
- RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
- Buffer));
+
+ for (auto &UF : RTUI->unsaved_files) {
+ llvm::MemoryBuffer *MB =
+ llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
+ RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
}
-
- if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
- RemappedFiles->size()))
- RTUI->result = 0;
+
+ if (!CXXUnit->Reparse(*RemappedFiles.get()))
+ RTUI->result = CXError_Success;
+ else if (isASTReadError(CXXUnit))
+ RTUI->result = CXError_ASTReadError;
}
int clang_reparseTranslationUnit(CXTranslationUnit TU,
@@ -2972,12 +3150,17 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU,
*Log << TU;
}
- ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
- options, 0 };
+ if (num_unsaved_files && !unsaved_files)
+ return CXError_InvalidArguments;
+
+ CXErrorCode result = CXError_Failure;
+ ReparseTranslationUnitInfo RTUI = {
+ TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
+ result};
if (getenv("LIBCLANG_NOTHREADS")) {
clang_reparseTranslationUnit_Impl(&RTUI);
- return RTUI.result;
+ return result;
}
llvm::CrashRecoveryContext CRC;
@@ -2985,25 +3168,29 @@ int clang_reparseTranslationUnit(CXTranslationUnit TU,
if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
fprintf(stderr, "libclang: crash detected during reparsing\n");
cxtu::getASTUnit(TU)->setUnsafeToFree(true);
- return 1;
+ return CXError_Crashed;
} else if (getenv("LIBCLANG_RESOURCE_USAGE"))
PrintLibclangResourceUsage(TU);
- return RTUI.result;
+ return result;
}
CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
- if (!CTUnit)
+ if (isNotUsableTU(CTUnit)) {
+ LOG_BAD_TU(CTUnit);
return cxstring::createEmpty();
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
}
CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
- if (!TU)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
return clang_getNullCursor();
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
@@ -3033,8 +3220,10 @@ time_t clang_getFileTime(CXFile SFile) {
}
CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
- if (!TU)
- return 0;
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return nullptr;
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
@@ -3042,8 +3231,14 @@ CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
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 (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return 0;
+ }
+
+ if (!file)
return 0;
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
@@ -3114,8 +3309,8 @@ static const Decl *getDeclFromExpr(const Stmt *E) {
if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
isa<ParmVarDecl>(SizeOfPack->getPack()))
return SizeOfPack->getPack();
-
- return 0;
+
+ return nullptr;
}
static SourceLocation getLocationFromExpr(const Expr *E) {
@@ -3309,6 +3504,22 @@ CXString clang_getCursorSpelling(CXCursor C) {
}
if (clang_isExpression(C.kind)) {
+ const Expr *E = getCursorExpr(C);
+
+ if (C.kind == CXCursor_ObjCStringLiteral ||
+ C.kind == CXCursor_StringLiteral) {
+ const StringLiteral *SLit;
+ if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
+ SLit = OSL->getString();
+ } else {
+ SLit = cast<StringLiteral>(E);
+ }
+ SmallString<256> Buf;
+ llvm::raw_svector_ostream OS(Buf);
+ SLit->outputString(OS);
+ return cxstring::createDup(OS.str());
+ }
+
const Decl *D = getDeclFromExpr(getCursorExpr(C));
if (D)
return getDeclSpelling(D);
@@ -3740,6 +3951,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("SEHExceptStmt");
case CXCursor_SEHFinallyStmt:
return cxstring::createRef("SEHFinallyStmt");
+ case CXCursor_SEHLeaveStmt:
+ return cxstring::createRef("SEHLeaveStmt");
case CXCursor_NullStmt:
return cxstring::createRef("NullStmt");
case CXCursor_InvalidFile:
@@ -3770,6 +3983,20 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("asm label");
case CXCursor_PackedAttr:
return cxstring::createRef("attribute(packed)");
+ case CXCursor_PureAttr:
+ return cxstring::createRef("attribute(pure)");
+ case CXCursor_ConstAttr:
+ return cxstring::createRef("attribute(const)");
+ case CXCursor_NoDuplicateAttr:
+ return cxstring::createRef("attribute(noduplicate)");
+ case CXCursor_CUDAConstantAttr:
+ return cxstring::createRef("attribute(constant)");
+ case CXCursor_CUDADeviceAttr:
+ return cxstring::createRef("attribute(device)");
+ case CXCursor_CUDAGlobalAttr:
+ return cxstring::createRef("attribute(global)");
+ case CXCursor_CUDAHostAttr:
+ return cxstring::createRef("attribute(host)");
case CXCursor_PreprocessingDirective:
return cxstring::createRef("preprocessing directive");
case CXCursor_MacroDefinition:
@@ -3819,7 +4046,35 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
case CXCursor_ModuleImportDecl:
return cxstring::createRef("ModuleImport");
case CXCursor_OMPParallelDirective:
- return cxstring::createRef("OMPParallelDirective");
+ return cxstring::createRef("OMPParallelDirective");
+ case CXCursor_OMPSimdDirective:
+ return cxstring::createRef("OMPSimdDirective");
+ case CXCursor_OMPForDirective:
+ return cxstring::createRef("OMPForDirective");
+ case CXCursor_OMPSectionsDirective:
+ return cxstring::createRef("OMPSectionsDirective");
+ case CXCursor_OMPSectionDirective:
+ return cxstring::createRef("OMPSectionDirective");
+ case CXCursor_OMPSingleDirective:
+ return cxstring::createRef("OMPSingleDirective");
+ case CXCursor_OMPMasterDirective:
+ return cxstring::createRef("OMPMasterDirective");
+ case CXCursor_OMPCriticalDirective:
+ return cxstring::createRef("OMPCriticalDirective");
+ case CXCursor_OMPParallelForDirective:
+ return cxstring::createRef("OMPParallelForDirective");
+ case CXCursor_OMPParallelSectionsDirective:
+ return cxstring::createRef("OMPParallelSectionsDirective");
+ case CXCursor_OMPTaskDirective:
+ return cxstring::createRef("OMPTaskDirective");
+ case CXCursor_OMPTaskyieldDirective:
+ return cxstring::createRef("OMPTaskyieldDirective");
+ case CXCursor_OMPBarrierDirective:
+ return cxstring::createRef("OMPBarrierDirective");
+ case CXCursor_OMPTaskwaitDirective:
+ return cxstring::createRef("OMPTaskwaitDirective");
+ case CXCursor_OMPFlushDirective:
+ return cxstring::createRef("OMPFlushDirective");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -3936,8 +4191,10 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
}
CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
- if (!TU)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
return clang_getNullCursor();
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
@@ -3953,10 +4210,11 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
CXString SearchFileName, ResultFileName, KindSpelling, USR;
const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
-
- clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
+
+ clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
+ nullptr);
clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
- &ResultColumn, 0);
+ &ResultColumn, nullptr);
SearchFileName = clang_getFileName(SearchFile);
ResultFileName = clang_getFileName(ResultFile);
KindSpelling = clang_getCursorKindSpelling(Result.kind);
@@ -3980,7 +4238,7 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
CXFile DefinitionFile;
unsigned DefinitionLine, DefinitionColumn;
clang_getFileLocation(DefinitionLoc, &DefinitionFile,
- &DefinitionLine, &DefinitionColumn, 0);
+ &DefinitionLine, &DefinitionColumn, nullptr);
CXString DefinitionFileName = clang_getFileName(DefinitionFile);
*Log << llvm::format(" -> %s(%s:%d:%d)",
clang_getCString(DefinitionKindSpelling),
@@ -4007,9 +4265,9 @@ unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
// 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;
+ X.data[1] = nullptr;
if (clang_isDeclaration(Y.kind))
- Y.data[1] = 0;
+ Y.data[1] = nullptr;
return X == Y;
}
@@ -4587,7 +4845,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
case Decl::CXXConstructor:
case Decl::CXXDestructor:
case Decl::CXXConversion: {
- const FunctionDecl *Def = 0;
+ const FunctionDecl *Def = nullptr;
if (cast<FunctionDecl>(D)->getBody(Def))
return MakeCXCursor(Def, TU);
return clang_getNullCursor();
@@ -4603,7 +4861,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
}
case Decl::FunctionTemplate: {
- const FunctionDecl *Def = 0;
+ const FunctionDecl *Def = nullptr;
if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
return clang_getNullCursor();
@@ -4897,6 +5155,11 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
break;
}
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return cxstring::createEmpty();
+ }
+
// We have to find the starting buffer pointer the hard way, by
// deconstructing the source location.
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
@@ -4916,6 +5179,11 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
}
CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return clang_getNullLocation();
+ }
+
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
return clang_getNullLocation();
@@ -4925,6 +5193,11 @@ CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
}
CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return clang_getNullRange();
+ }
+
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit)
return clang_getNullRange();
@@ -4995,10 +5268,10 @@ static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
CXTok.ptr_data = II;
} else if (Tok.is(tok::comment)) {
CXTok.int_data[0] = CXToken_Comment;
- CXTok.ptr_data = 0;
+ CXTok.ptr_data = nullptr;
} else {
CXTok.int_data[0] = CXToken_Punctuation;
- CXTok.ptr_data = 0;
+ CXTok.ptr_data = nullptr;
}
CXTokens.push_back(CXTok);
previousWasAt = Tok.is(tok::at);
@@ -5012,12 +5285,14 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
}
if (Tokens)
- *Tokens = 0;
+ *Tokens = nullptr;
if (NumTokens)
*NumTokens = 0;
- if (!TU)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
return;
+ }
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
if (!CXXUnit || !Tokens || !NumTokens)
@@ -5075,18 +5350,26 @@ class AnnotateTokensWorker {
unsigned BeforeChildrenTokenIdx;
};
SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
-
+
+ CXToken &getTok(unsigned Idx) {
+ assert(Idx < NumTokens);
+ return Tokens[Idx];
+ }
+ const CXToken &getTok(unsigned Idx) const {
+ assert(Idx < NumTokens);
+ return Tokens[Idx];
+ }
bool MoreTokens() const { return TokIdx < NumTokens; }
unsigned NextToken() const { return TokIdx; }
void AdvanceToken() { ++TokIdx; }
SourceLocation GetTokenLoc(unsigned tokI) {
- return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
+ return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
}
bool isFunctionMacroToken(unsigned tokI) const {
- return Tokens[tokI].int_data[3] != 0;
+ return getTok(tokI).int_data[3] != 0;
}
SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
- return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
+ return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
}
void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
@@ -5223,10 +5506,8 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
if (Method->getObjCDeclQualifier())
HasContextSensitiveKeywords = true;
else {
- for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
- PEnd = Method->param_end();
- P != PEnd; ++P) {
- if ((*P)->getObjCDeclQualifier()) {
+ for (const auto *P : Method->params()) {
+ if (P->getObjCDeclQualifier()) {
HasContextSensitiveKeywords = true;
break;
}
@@ -5333,7 +5614,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
// This can happen for C++ constructor expressions whose range generally
// include the variable declaration, e.g.:
// MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
- if (clang_isExpression(cursorK)) {
+ if (clang_isExpression(cursorK) && MoreTokens()) {
const Expr *E = getCursorExpr(cursor);
if (const Decl *D = getCursorParentDecl(cursor)) {
const unsigned I = NextToken();
@@ -5455,14 +5736,23 @@ public:
}
private:
+ CXToken &getTok(unsigned Idx) {
+ assert(Idx < NumTokens);
+ return Tokens[Idx];
+ }
+ const CXToken &getTok(unsigned Idx) const {
+ assert(Idx < NumTokens);
+ return Tokens[Idx];
+ }
+
SourceLocation getTokenLoc(unsigned tokI) {
- return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
+ return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
}
void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
// The third field is reserved and currently not used. Use it here
// to mark macro arg expanded tokens with their expanded locations.
- Tokens[tokI].int_data[3] = loc.getRawEncoding();
+ getTok(tokI).int_data[3] = loc.getRawEncoding();
}
};
@@ -5552,15 +5842,14 @@ static void annotatePreprocessorTokens(CXTranslationUnit TU,
if (lexNext(Lex, Tok, NextIdx, NumTokens))
break;
- MacroInfo *MI = 0;
- if (Tok.is(tok::raw_identifier) &&
- StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
+ MacroInfo *MI = nullptr;
+ if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "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);
+ IdentifierInfo &II =
+ PP.getIdentifierTable().get(Tok.getRawIdentifier());
SourceLocation MappedTokLoc =
CXXUnit->mapLocationToPreamble(Tok.getLocation());
MI = getMacroInfo(II, MappedTokLoc, TU);
@@ -5720,7 +6009,11 @@ extern "C" {
void clang_annotateTokens(CXTranslationUnit TU,
CXToken *Tokens, unsigned NumTokens,
CXCursor *Cursors) {
- if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return;
+ }
+ if (NumTokens == 0 || !Tokens || !Cursors) {
LOG_FUNC_SECTION { *Log << "<null input>"; }
return;
}
@@ -5890,28 +6183,30 @@ static int getCursorPlatformAvailabilityForDecl(const Decl *D,
int availability_size) {
bool HadAvailAttr = false;
int N = 0;
- for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
- ++A) {
- if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
+ for (auto A : D->attrs()) {
+ if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
HadAvailAttr = true;
if (always_deprecated)
*always_deprecated = 1;
- if (deprecated_message)
+ if (deprecated_message) {
+ clang_disposeString(*deprecated_message);
*deprecated_message = cxstring::createDup(Deprecated->getMessage());
+ }
continue;
}
- if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
+ if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
HadAvailAttr = true;
if (always_unavailable)
*always_unavailable = 1;
if (unavailable_message) {
+ clang_disposeString(*unavailable_message);
*unavailable_message = cxstring::createDup(Unavailable->getMessage());
}
continue;
}
- if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
+ if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
HadAvailAttr = true;
if (N < availability_size) {
availability[N].Platform
@@ -5988,7 +6283,7 @@ CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
/// function template.
static const Decl *maybeGetTemplateCursor(const Decl *D) {
if (!D)
- return 0;
+ return nullptr;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
@@ -6040,8 +6335,8 @@ CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
CXFile clang_getIncludedFile(CXCursor cursor) {
if (cursor.kind != CXCursor_InclusionDirective)
- return 0;
-
+ return nullptr;
+
const InclusionDirective *ID = getCursorInclusionDirective(cursor);
return const_cast<FileEntry *>(ID->getFile());
}
@@ -6172,17 +6467,6 @@ CXString clang_Cursor_getBriefCommentText(CXCursor C) {
return cxstring::createNull();
}
-CXComment clang_Cursor_getParsedComment(CXCursor C) {
- if (!clang_isDeclaration(C.kind))
- return cxcomment::createCXComment(NULL, NULL);
-
- const Decl *D = getCursorDecl(C);
- const ASTContext &Context = getCursorContext(C);
- const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
-
- return cxcomment::createCXComment(FC, getCursorTU(C));
-}
-
CXModule clang_Cursor_getModule(CXCursor C) {
if (C.kind == CXCursor_ModuleImportDecl) {
if (const ImportDecl *ImportD =
@@ -6190,19 +6474,39 @@ CXModule clang_Cursor_getModule(CXCursor C) {
return ImportD->getImportedModule();
}
- return 0;
+ return nullptr;
+}
+
+CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return nullptr;
+ }
+ if (!File)
+ return nullptr;
+ FileEntry *FE = static_cast<FileEntry *>(File);
+
+ ASTUnit &Unit = *cxtu::getASTUnit(TU);
+ HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
+ ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
+
+ if (Module *Mod = Header.getModule()) {
+ if (Header.getRole() != ModuleMap::ExcludedHeader)
+ return Mod;
+ }
+ return nullptr;
}
CXFile clang_Module_getASTFile(CXModule CXMod) {
if (!CXMod)
- return 0;
+ return nullptr;
Module *Mod = static_cast<Module*>(CXMod);
return const_cast<FileEntry *>(Mod->getASTFile());
}
CXModule clang_Module_getParent(CXModule CXMod) {
if (!CXMod)
- return 0;
+ return nullptr;
Module *Mod = static_cast<Module*>(CXMod);
return Mod->Parent;
}
@@ -6221,9 +6525,20 @@ CXString clang_Module_getFullName(CXModule CXMod) {
return cxstring::createDup(Mod->getFullModuleName());
}
+int clang_Module_isSystem(CXModule CXMod) {
+ if (!CXMod)
+ return 0;
+ Module *Mod = static_cast<Module*>(CXMod);
+ return Mod->IsSystem;
+}
+
unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
CXModule CXMod) {
- if (!TU || !CXMod)
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return 0;
+ }
+ if (!CXMod)
return 0;
Module *Mod = static_cast<Module*>(CXMod);
FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
@@ -6233,8 +6548,12 @@ unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
CXModule CXMod, unsigned Index) {
- if (!TU || !CXMod)
- return 0;
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return nullptr;
+ }
+ if (!CXMod)
+ return nullptr;
Module *Mod = static_cast<Module*>(CXMod);
FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
@@ -6242,7 +6561,7 @@ CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
if (Index < TopHeaders.size())
return const_cast<FileEntry *>(TopHeaders[Index]);
- return 0;
+ return nullptr;
}
} // end: extern "C"
@@ -6256,27 +6575,29 @@ unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
- const CXXMethodDecl *Method = 0;
const Decl *D = cxcursor::getCursorDecl(C);
- if (const FunctionTemplateDecl *FunTmpl =
- dyn_cast_or_null<FunctionTemplateDecl>(D))
- Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
- else
- Method = dyn_cast_or_null<CXXMethodDecl>(D);
+ const CXXMethodDecl *Method =
+ D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
}
+unsigned clang_CXXMethod_isConst(CXCursor C) {
+ if (!clang_isDeclaration(C.kind))
+ return 0;
+
+ const Decl *D = cxcursor::getCursorDecl(C);
+ const CXXMethodDecl *Method =
+ D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
+ return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
+}
+
unsigned clang_CXXMethod_isStatic(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
- const CXXMethodDecl *Method = 0;
const Decl *D = cxcursor::getCursorDecl(C);
- if (const FunctionTemplateDecl *FunTmpl =
- dyn_cast_or_null<FunctionTemplateDecl>(D))
- Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
- else
- Method = dyn_cast_or_null<CXXMethodDecl>(D);
+ const CXXMethodDecl *Method =
+ D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
return (Method && Method->isStatic()) ? 1 : 0;
}
@@ -6284,13 +6605,9 @@ unsigned clang_CXXMethod_isVirtual(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
- const CXXMethodDecl *Method = 0;
const Decl *D = cxcursor::getCursorDecl(C);
- if (const FunctionTemplateDecl *FunTmpl =
- dyn_cast_or_null<FunctionTemplateDecl>(D))
- Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
- else
- Method = dyn_cast_or_null<CXXMethodDecl>(D);
+ const CXXMethodDecl *Method =
+ D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
return (Method && Method->isVirtual()) ? 1 : 0;
}
} // end: extern "C"
@@ -6376,13 +6693,14 @@ const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
}
CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
- if (!TU) {
- CXTUResourceUsage usage = { (void*) 0, 0, 0 };
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
return usage;
}
ASTUnit *astUnit = cxtu::getASTUnit(TU);
- OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
+ std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
ASTContext &astContext = astUnit->getASTContext();
// How much memory is used by AST nodes and types?
@@ -6404,7 +6722,7 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
// How much memory is used for caching global code completion results?
unsigned long completionBytes = 0;
if (GlobalCodeCompletionAllocator *completionAllocator =
- astUnit->getCachedCompletionAllocator().getPtr()) {
+ astUnit->getCachedCompletionAllocator().get()) {
completionBytes = completionAllocator->getTotalMemory();
}
createCXTUResourceUsageEntry(*entries,
@@ -6459,11 +6777,11 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
createCXTUResourceUsageEntry(*entries,
CXTUResourceUsage_Preprocessor_HeaderSearch,
pp.getHeaderSearchInfo().getTotalMemory());
-
+
CXTUResourceUsage usage = { (void*) entries.get(),
(unsigned) entries->size(),
- entries->size() ? &(*entries)[0] : 0 };
- entries.take();
+ entries->size() ? &(*entries)[0] : nullptr };
+ entries.release();
return usage;
}
@@ -6472,6 +6790,52 @@ void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
delete (MemUsageEntries*) usage.data;
}
+CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
+ CXSourceRangeList *skipped = new CXSourceRangeList;
+ skipped->count = 0;
+ skipped->ranges = nullptr;
+
+ if (isNotUsableTU(TU)) {
+ LOG_BAD_TU(TU);
+ return skipped;
+ }
+
+ if (!file)
+ return skipped;
+
+ ASTUnit *astUnit = cxtu::getASTUnit(TU);
+ PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
+ if (!ppRec)
+ return skipped;
+
+ ASTContext &Ctx = astUnit->getASTContext();
+ SourceManager &sm = Ctx.getSourceManager();
+ FileEntry *fileEntry = static_cast<FileEntry *>(file);
+ FileID wantedFileID = sm.translateFile(fileEntry);
+
+ const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
+ std::vector<SourceRange> wantedRanges;
+ for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
+ i != ei; ++i) {
+ if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
+ wantedRanges.push_back(*i);
+ }
+
+ skipped->count = wantedRanges.size();
+ skipped->ranges = new CXSourceRange[skipped->count];
+ for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
+ skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
+
+ return skipped;
+}
+
+void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
+ if (ranges) {
+ delete[] ranges->ranges;
+ delete ranges;
+ }
+}
+
} // end extern "C"
void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
@@ -6517,8 +6881,7 @@ void clang::setThreadBackgroundPriority() {
if (getenv("LIBCLANG_BGPRIO_DISABLE"))
return;
- // FIXME: Move to llvm/Support and make it cross-platform.
-#ifdef __APPLE__
+#ifdef USE_DARWIN_THREADS
setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
#endif
}
@@ -6530,7 +6893,7 @@ void cxindex::printDiagsToStderr(ASTUnit *Unit) {
for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
DEnd = Unit->stored_diag_end();
D != DEnd; ++D) {
- CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
+ CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
CXString Msg = clang_formatDiagnostic(&Diag,
clang_defaultDiagnosticDisplayOptions());
fprintf(stderr, "%s\n", clang_getCString(Msg));
@@ -6548,9 +6911,9 @@ MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
SourceLocation MacroDefLoc,
CXTranslationUnit TU){
if (MacroDefLoc.isInvalid() || !TU)
- return 0;
+ return nullptr;
if (!II.hadMacroDefinition())
- return 0;
+ return nullptr;
ASTUnit *Unit = cxtu::getASTUnit(TU);
Preprocessor &PP = Unit->getPreprocessor();
@@ -6563,16 +6926,16 @@ MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
}
}
- return 0;
+ return nullptr;
}
const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
CXTranslationUnit TU) {
if (!MacroDef || !TU)
- return 0;
+ return nullptr;
const IdentifierInfo *II = MacroDef->getName();
if (!II)
- return 0;
+ return nullptr;
return getMacroInfo(*II, MacroDef->getLocation(), TU);
}
@@ -6581,12 +6944,12 @@ MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
const Token &Tok,
CXTranslationUnit TU) {
if (!MI || !TU)
- return 0;
+ return nullptr;
if (Tok.isNot(tok::raw_identifier))
- return 0;
+ return nullptr;
if (MI->getNumTokens() == 0)
- return 0;
+ return nullptr;
SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
MI->getDefinitionEndLoc());
ASTUnit *Unit = cxtu::getASTUnit(TU);
@@ -6594,27 +6957,26 @@ MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
// 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;
+ return nullptr;
if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
- return 0;
+ return nullptr;
Preprocessor &PP = Unit->getPreprocessor();
PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
if (!PPRec)
- return 0;
+ return nullptr;
- StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
- IdentifierInfo &II = PP.getIdentifierTable().get(Name);
+ IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
if (!II.hadMacroDefinition())
- return 0;
+ return nullptr;
// 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;
+ return nullptr;
MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
if (!InnerMD)
- return 0;
+ return nullptr;
return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
}
@@ -6623,18 +6985,18 @@ MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
SourceLocation Loc,
CXTranslationUnit TU) {
if (Loc.isInvalid() || !MI || !TU)
- return 0;
+ return nullptr;
if (MI->getNumTokens() == 0)
- return 0;
+ return nullptr;
ASTUnit *Unit = cxtu::getASTUnit(TU);
Preprocessor &PP = Unit->getPreprocessor();
if (!PP.getPreprocessingRecord())
- return 0;
+ return nullptr;
Loc = Unit->getSourceManager().getSpellingLoc(Loc);
Token Tok;
if (PP.getRawToken(Loc, Tok))
- return 0;
+ return nullptr;
return checkForMacroInMacroDefinition(MI, Tok, TU);
}
@@ -6655,9 +7017,9 @@ Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
LogOS << " (" << Unit->getASTFileName() << ')';
return *this;
}
+ } else {
+ LogOS << "<NULL TU>";
}
-
- LogOS << "<NULL TU>";
return *this;
}
@@ -6676,7 +7038,7 @@ Logger &cxindex::Logger::operator<<(CXCursor cursor) {
Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
CXFile File;
unsigned Line, Column;
- clang_getFileLocation(Loc, &File, &Line, &Column, 0);
+ clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
CXString FileName = clang_getFileName(File);
*this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
clang_disposeString(FileName);
@@ -6689,11 +7051,11 @@ Logger &cxindex::Logger::operator<<(CXSourceRange range) {
CXFile BFile;
unsigned BLine, BColumn;
- clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
+ clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
CXFile EFile;
unsigned ELine, EColumn;
- clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
+ clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
CXString BFileName = clang_getFileName(BFile);
if (BFile == EFile) {
@@ -6721,18 +7083,20 @@ Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
return *this;
}
+static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
+
cxindex::Logger::~Logger() {
LogOS.flush();
- llvm::sys::ScopedLock L(EnableMultithreadingMutex);
+ llvm::sys::ScopedLock L(*LoggingMutex);
static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
raw_ostream &OS = llvm::errs();
OS << "[libclang:" << Name << ':';
- // FIXME: Portability.
-#if HAVE_PTHREAD_H && __APPLE__
+#ifdef USE_DARWIN_THREADS
+ // TODO: Portability.
mach_port_t tid = pthread_mach_thread_np(pthread_self());
OS << tid << ':';
#endif