summaryrefslogtreecommitdiff
path: root/tools/libclang
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2011-10-20 21:14:49 +0000
committerDimitry Andric <dim@FreeBSD.org>2011-10-20 21:14:49 +0000
commit36981b17ed939300f6f8fc2355a255f711fcef71 (patch)
treeee2483e98b09cac943dc93a6969d83ca737ff139 /tools/libclang
parent180abc3db9ae3b4fc63cd65b15697e6ffcc8a657 (diff)
Notes
Diffstat (limited to 'tools/libclang')
-rw-r--r--tools/libclang/CIndex.cpp1403
-rw-r--r--tools/libclang/CIndexCXX.cpp11
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp185
-rw-r--r--tools/libclang/CIndexDiagnostic.cpp18
-rw-r--r--tools/libclang/CIndexHigh.cpp315
-rw-r--r--tools/libclang/CIndexInclusionStack.cpp19
-rw-r--r--tools/libclang/CIndexUSRs.cpp106
-rw-r--r--tools/libclang/CIndexer.cpp2
-rw-r--r--tools/libclang/CMakeLists.txt1
-rw-r--r--tools/libclang/CXCursor.cpp697
-rw-r--r--tools/libclang/CXCursor.h37
-rw-r--r--tools/libclang/CXString.cpp6
-rw-r--r--tools/libclang/CXString.h6
-rw-r--r--tools/libclang/CXTranslationUnit.h9
-rw-r--r--tools/libclang/CXType.cpp36
-rw-r--r--tools/libclang/Index_Internal.h43
-rw-r--r--tools/libclang/libclang.darwin.exports143
-rw-r--r--tools/libclang/libclang.exports26
18 files changed, 2133 insertions, 930 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 50d56fccb9c59..46ba3d55340d3 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -51,8 +51,9 @@
using namespace clang;
using namespace clang::cxcursor;
using namespace clang::cxstring;
+using namespace clang::cxtu;
-static CXTranslationUnit MakeCXTranslationUnit(ASTUnit *TU) {
+CXTranslationUnit cxtu::MakeCXTranslationUnit(ASTUnit *TU) {
if (!TU)
return 0;
CXTranslationUnit D = new CXTranslationUnitImpl();
@@ -117,10 +118,10 @@ CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
// location accordingly.
SourceLocation EndLoc = R.getEnd();
if (EndLoc.isValid() && EndLoc.isMacroID())
- EndLoc = SM.getInstantiationRange(EndLoc).second;
+ EndLoc = SM.getExpansionRange(EndLoc).second;
if (R.isTokenRange() && !EndLoc.isInvalid() && EndLoc.isFileID()) {
unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts);
- EndLoc = EndLoc.getFileLocWithOffset(Length);
+ EndLoc = EndLoc.getLocWithOffset(Length);
}
CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts },
@@ -141,7 +142,6 @@ public:
TypeLocVisitKind, OverloadExprPartsKind,
DeclRefExprPartsKind, LabelRefVisitKind,
ExplicitTemplateArgsVisitKind,
- NestedNameSpecifierVisitKind,
NestedNameSpecifierLocVisitKind,
DeclarationNameInfoVisitKind,
MemberRefVisitKind, SizeOfPackExprPartsKind };
@@ -161,7 +161,7 @@ public:
static bool classof(VisitorJob *VJ) { return true; }
};
-typedef llvm::SmallVector<VisitorJob, 10> VisitorWorkList;
+typedef SmallVector<VisitorJob, 10> VisitorWorkList;
// Cursor visitor.
class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
@@ -184,11 +184,6 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
/// \brief The opaque client data, to be passed along to the visitor.
CXClientData ClientData;
- // MaxPCHLevel - the maximum PCH level of declarations that we will pass on
- // to the visitor. Declarations with a PCH level greater than this value will
- // be suppressed.
- unsigned MaxPCHLevel;
-
/// \brief Whether we should visit the preprocessing record entries last,
/// after visiting other declarations.
bool VisitPreprocessorLast;
@@ -203,8 +198,8 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
DeclContext::decl_iterator DE_current;
// Cache of pre-allocated worklists for data-recursion walk of Stmts.
- llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
- llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
+ SmallVector<VisitorWorkList*, 5> WorkListFreeList;
+ SmallVector<VisitorWorkList*, 5> WorkListCache;
using DeclVisitor<CursorVisitor, bool>::Visit;
using TypeLocVisitor<CursorVisitor, bool>::Visit;
@@ -239,12 +234,11 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
public:
CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
CXClientData ClientData,
- unsigned MaxPCHLevel,
bool VisitPreprocessorLast,
SourceRange RegionOfInterest = SourceRange())
: TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
Visitor(Visitor), ClientData(ClientData),
- MaxPCHLevel(MaxPCHLevel), VisitPreprocessorLast(VisitPreprocessorLast),
+ VisitPreprocessorLast(VisitPreprocessorLast),
RegionOfInterest(RegionOfInterest), DI_current(0)
{
Parent.kind = CXCursor_NoDeclFound;
@@ -256,7 +250,7 @@ public:
~CursorVisitor() {
// Free the pre-allocated worklists for data-recursion.
- for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
+ for (SmallVectorImpl<VisitorWorkList*>::iterator
I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
delete *I;
}
@@ -267,8 +261,10 @@ public:
bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
- std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
- getPreprocessedEntities();
+ bool visitPreprocessedEntitiesInRegion();
+
+ template<typename InputIterator>
+ bool visitPreprocessedEntities(InputIterator First, InputIterator Last);
bool VisitChildren(CXCursor Parent);
@@ -327,35 +323,15 @@ public:
bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
// Type visitors
- bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL);
- bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL);
- bool VisitTypedefTypeLoc(TypedefTypeLoc TL);
- bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL);
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
+#include "clang/AST/TypeLocNodes.def"
+
bool VisitTagTypeLoc(TagTypeLoc TL);
- bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL);
- bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
- bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL);
- bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL);
- bool VisitParenTypeLoc(ParenTypeLoc TL);
- bool VisitPointerTypeLoc(PointerTypeLoc TL);
- bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL);
- bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL);
- bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL);
- bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL);
- bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
bool VisitArrayTypeLoc(ArrayTypeLoc TL);
- bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL);
- // FIXME: Implement visitors here when the unimplemented TypeLocs get
- // implemented
- bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL);
- bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL);
- bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL);
- bool VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL);
- bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL);
- bool VisitDependentTemplateSpecializationTypeLoc(
- DependentTemplateSpecializationTypeLoc TL);
- bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL);
-
+ bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
+
// Data-recursive visitor functions.
bool IsInRegionOfInterest(CXCursor C);
bool RunVisitorWorkList(VisitorWorkList &WL);
@@ -390,10 +366,9 @@ bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
if (clang_isDeclaration(Cursor.kind)) {
Decl *D = getCursorDecl(Cursor);
assert(D && "Invalid declaration cursor");
- if (D->getPCHLevel() > MaxPCHLevel)
- return false;
-
- if (D->isImplicit())
+ // Ignore implicit declarations, unless it's an objc method because
+ // currently we should report implicit methods for properties when indexing.
+ if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
return false;
}
@@ -419,65 +394,53 @@ bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
return false;
}
-std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
-CursorVisitor::getPreprocessedEntities() {
+bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
PreprocessingRecord &PPRec
= *AU->getPreprocessor().getPreprocessingRecord();
+ if (RegionOfInterest.isValid()) {
+ SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
+ std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+ Entities = PPRec.getPreprocessedEntitiesInRange(MappedRange);
+ return visitPreprocessedEntities(Entities.first, Entities.second);
+ }
+
bool OnlyLocalDecls
= !AU->isMainFileAST() && AU->getOnlyLocalDecls();
- if (OnlyLocalDecls && RegionOfInterest.isValid()) {
- // If we would only look at local declarations but we have a region of
- // interest, check whether that region of interest is in the main file.
- // If not, we should traverse all declarations.
- // FIXME: My kingdom for a proper binary search approach to finding
- // cursors!
- std::pair<FileID, unsigned> Location
- = AU->getSourceManager().getDecomposedInstantiationLoc(
- RegionOfInterest.getBegin());
- if (Location.first != AU->getSourceManager().getMainFileID())
- OnlyLocalDecls = false;
- }
-
- PreprocessingRecord::iterator StartEntity, EndEntity;
- if (OnlyLocalDecls) {
- StartEntity = AU->pp_entity_begin();
- EndEntity = AU->pp_entity_end();
- } else {
- StartEntity = PPRec.begin();
- EndEntity = PPRec.end();
- }
-
- // There is no region of interest; we have to walk everything.
- if (RegionOfInterest.isInvalid())
- return std::make_pair(StartEntity, EndEntity);
-
- // Find the file in which the region of interest lands.
- SourceManager &SM = AU->getSourceManager();
- std::pair<FileID, unsigned> Begin
- = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin());
- std::pair<FileID, unsigned> End
- = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd());
-
- // The region of interest spans files; we have to walk everything.
- if (Begin.first != End.first)
- return std::make_pair(StartEntity, EndEntity);
+ if (OnlyLocalDecls)
+ return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end());
+
+ return visitPreprocessedEntities(PPRec.begin(), PPRec.end());
+}
+
+template<typename InputIterator>
+bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
+ InputIterator Last) {
+ for (; First != Last; ++First) {
+ if (MacroExpansion *ME = dyn_cast<MacroExpansion>(*First)) {
+ if (Visit(MakeMacroExpansionCursor(ME, TU)))
+ return true;
+
+ continue;
+ }
+
+ if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*First)) {
+ if (Visit(MakeMacroDefinitionCursor(MD, TU)))
+ return true;
+
+ continue;
+ }
- ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap
- = AU->getPreprocessedEntitiesByFile();
- if (ByFileMap.empty()) {
- // Build the mapping from files to sets of preprocessed entities.
- for (PreprocessingRecord::iterator E = StartEntity; E != EndEntity; ++E) {
- std::pair<FileID, unsigned> P
- = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin());
+ if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*First)) {
+ if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
+ return true;
- ByFileMap[P.first].push_back(*E);
+ continue;
}
}
- return std::make_pair(ByFileMap[Begin.first].begin(),
- ByFileMap[Begin.first].end());
+ return false;
}
/// \brief Visit the children of the given cursor.
@@ -529,7 +492,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), true))
+ if (Visit(MakeCXCursor(*TL, tu, RegionOfInterest), true))
return true;
}
} else if (VisitDeclContext(
@@ -539,33 +502,8 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
}
// Walk the preprocessing record.
- if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
- // FIXME: Once we have the ability to deserialize a preprocessing record,
- // do so.
- PreprocessingRecord::iterator E, EEnd;
- for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
- if (MacroExpansion *ME = dyn_cast<MacroExpansion>(*E)) {
- if (Visit(MakeMacroExpansionCursor(ME, tu)))
- return true;
-
- continue;
- }
-
- if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
- if (Visit(MakeMacroDefinitionCursor(MD, tu)))
- return true;
-
- continue;
- }
-
- if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
- if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
- return true;
-
- continue;
- }
- }
- }
+ if (CXXUnit->getPreprocessor().getPreprocessingRecord())
+ visitPreprocessedEntitiesInRegion();
}
return false;
@@ -578,7 +516,15 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
}
}
}
-
+
+ if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
+ IBOutletCollectionAttr *A =
+ cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
+ if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
+ return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
+ A->getInterfaceLoc(), TU));
+ }
+
// Nothing to visit at the moment.
return false;
}
@@ -589,7 +535,7 @@ bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
return true;
if (Stmt *Body = B->getBody())
- return Visit(MakeCXCursor(Body, StmtParent, TU));
+ return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -629,7 +575,7 @@ bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
Decl *D = *I;
if (D->getLexicalDeclContext() != DC)
continue;
- CXCursor Cursor = MakeCXCursor(D, TU);
+ CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
if (!V.hasValue())
continue;
@@ -727,7 +673,7 @@ bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
if (Expr *Init = D->getInitExpr())
- return Visit(MakeCXCursor(Init, StmtParent, TU));
+ return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -794,7 +740,7 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
// Find the initializers that were written in the source.
- llvm::SmallVector<CXXCtorInitializer *, 4> WrittenInits;
+ SmallVector<CXXCtorInitializer *, 4> WrittenInits;
for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
IEnd = Constructor->init_end();
I != IEnd; ++I) {
@@ -822,12 +768,12 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
// Visit the initializer value.
if (Expr *Initializer = Init->getInit())
- if (Visit(MakeCXCursor(Initializer, ND, TU)))
+ if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
return true;
}
}
- if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
+ if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
return true;
}
@@ -839,7 +785,7 @@ bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
return true;
if (Expr *BitWidth = D->getBitWidth())
- return Visit(MakeCXCursor(BitWidth, StmtParent, TU));
+ return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -849,7 +795,7 @@ bool CursorVisitor::VisitVarDecl(VarDecl *D) {
return true;
if (Expr *Init = D->getInit())
- return Visit(MakeCXCursor(Init, StmtParent, TU));
+ return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -860,7 +806,7 @@ bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
if (Expr *DefArg = D->getDefaultArgument())
- return Visit(MakeCXCursor(DefArg, StmtParent, TU));
+ return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -902,12 +848,12 @@ bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
PEnd = ND->param_end();
P != PEnd; ++P) {
- if (Visit(MakeCXCursor(*P, TU)))
+ if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
return true;
}
if (ND->isThisDeclarationADefinition() &&
- Visit(MakeCXCursor(ND->getBody(), StmtParent, TU)))
+ Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
return true;
return false;
@@ -938,7 +884,7 @@ bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
// in the current DeclContext. If any fall within the
// container's lexical region, stash them into a vector
// for later processing.
- llvm::SmallVector<Decl *, 24> DeclsInContainer;
+ SmallVector<Decl *, 24> DeclsInContainer;
SourceLocation EndLoc = D->getSourceRange().getEnd();
SourceManager &SM = AU->getSourceManager();
if (EndLoc.isValid()) {
@@ -979,9 +925,9 @@ bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
ContainerDeclsSort(SM));
// Now visit the decls.
- for (llvm::SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
+ for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
E = DeclsInContainer.end(); I != E; ++I) {
- CXCursor Cursor = MakeCXCursor(*I, TU);
+ CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
const llvm::Optional<bool> &V = shouldVisitCursor(Cursor);
if (!V.hasValue())
continue;
@@ -1043,12 +989,12 @@ bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
// the @interface.
if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
- if (Visit(MakeCXCursor(MD, TU)))
+ if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
return true;
if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
if (MD->isSynthesized() && MD->getLexicalDeclContext() == CDecl)
- if (Visit(MakeCXCursor(MD, TU)))
+ if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
return true;
return false;
@@ -1110,10 +1056,9 @@ bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
}
bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) {
- for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C)
- if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU)))
+ if (Visit(MakeCursorObjCClassRef(D->getForwardInterfaceDecl(),
+ D->getForwardDecl()->getLocation(), TU)))
return true;
-
return false;
}
@@ -1254,7 +1199,7 @@ bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
bool
CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
- llvm::SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
+ SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
for (; Qualifier; Qualifier = Qualifier.getPrefix())
Qualifiers.push_back(Qualifier);
@@ -1302,7 +1247,7 @@ bool CursorVisitor::VisitTemplateParameters(
for (TemplateParameterList::const_iterator P = Params->begin(),
PEnd = Params->end();
P != PEnd; ++P) {
- if (Visit(MakeCXCursor(*P, TU)))
+ if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
return true;
}
@@ -1359,12 +1304,12 @@ bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
case TemplateArgument::Declaration:
if (Expr *E = TAL.getSourceDeclExpression())
- return Visit(MakeCXCursor(E, StmtParent, TU));
+ return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
return false;
case TemplateArgument::Expression:
if (Expr *E = TAL.getSourceExpression())
- return Visit(MakeCXCursor(E, StmtParent, TU));
+ return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
return false;
case TemplateArgument::Template:
@@ -1414,6 +1359,7 @@ bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
case BuiltinType::Long:
case BuiltinType::LongLong:
case BuiltinType::Int128:
+ case BuiltinType::Half:
case BuiltinType::Float:
case BuiltinType::Double:
case BuiltinType::LongDouble:
@@ -1455,6 +1401,9 @@ bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
}
bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
+ if (TL.isDefinition())
+ return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
+
return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
}
@@ -1510,6 +1459,10 @@ bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
return Visit(TL.getPointeeLoc());
}
+bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
+ return Visit(TL.getModifiedLoc());
+}
+
bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
bool SkipResultType) {
if (!SkipResultType && Visit(TL.getResultLoc()))
@@ -1517,7 +1470,7 @@ bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
if (Decl *D = TL.getArg(I))
- if (Visit(MakeCXCursor(D, TU)))
+ if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
return true;
return false;
@@ -1528,7 +1481,7 @@ bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
return true;
if (Expr *Size = TL.getSizeExpr())
- return Visit(MakeCXCursor(Size, StmtParent, TU));
+ return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
return false;
}
@@ -1599,13 +1552,49 @@ bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
return Visit(TL.getPatternLoc());
}
+bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
+ if (Expr *E = TL.getUnderlyingExpr())
+ return Visit(MakeCXCursor(E, StmtParent, TU));
+
+ return false;
+}
+
+bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+ return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+}
+
+bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
+ return Visit(TL.getValueLoc());
+}
+
+#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
+bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
+ return Visit##PARENT##Loc(TL); \
+}
+
+DEFAULT_TYPELOC_IMPL(Complex, Type)
+DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
+DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
+DEFAULT_TYPELOC_IMPL(Vector, Type)
+DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
+DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
+DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
+DEFAULT_TYPELOC_IMPL(Record, TagType)
+DEFAULT_TYPELOC_IMPL(Enum, TagType)
+DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
+DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
+DEFAULT_TYPELOC_IMPL(Auto, Type)
+
bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
// Visit the nested-name-specifier, if present.
if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
if (VisitNestedNameSpecifierLoc(QualifierLoc))
return true;
- if (D->isDefinition()) {
+ 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)))
@@ -1642,7 +1631,7 @@ DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
-DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList,
+DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
ExplicitTemplateArgsVisitKind)
DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
#undef DEF_JOB
@@ -1687,27 +1676,6 @@ public:
SourceLocation getLoc() const {
return SourceLocation::getFromPtrEncoding(data[1]); }
};
-class NestedNameSpecifierVisit : public VisitorJob {
-public:
- NestedNameSpecifierVisit(NestedNameSpecifier *NS, SourceRange R,
- CXCursor parent)
- : VisitorJob(parent, VisitorJob::NestedNameSpecifierVisitKind,
- NS, R.getBegin().getPtrEncoding(),
- R.getEnd().getPtrEncoding()) {}
- static bool classof(const VisitorJob *VJ) {
- return VJ->getKind() == VisitorJob::NestedNameSpecifierVisitKind;
- }
- NestedNameSpecifier *get() const {
- return static_cast<NestedNameSpecifier*>(data[0]);
- }
- SourceRange getSourceRange() const {
- SourceLocation A =
- SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
- SourceLocation B =
- SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[2]);
- return SourceRange(A, B);
- }
-};
class NestedNameSpecifierLocVisit : public VisitorJob {
public:
@@ -1809,9 +1777,8 @@ public:
private:
void AddDeclarationNameInfo(Stmt *S);
- void AddNestedNameSpecifier(NestedNameSpecifier *NS, SourceRange R);
void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
- void AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A);
+ void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
void AddMemberRef(FieldDecl *D, SourceLocation L);
void AddStmt(Stmt *S);
void AddDecl(Decl *D, bool isFirst = true);
@@ -1825,11 +1792,6 @@ void EnqueueVisitor::AddDeclarationNameInfo(Stmt *S) {
// statement we are visiting.
WL.push_back(DeclarationNameInfoVisit(S, Parent));
}
-void EnqueueVisitor::AddNestedNameSpecifier(NestedNameSpecifier *N,
- SourceRange R) {
- if (N)
- WL.push_back(NestedNameSpecifierVisit(N, R, Parent));
-}
void
EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
@@ -1846,10 +1808,10 @@ void EnqueueVisitor::AddDecl(Decl *D, bool isFirst) {
WL.push_back(DeclVisit(D, Parent, isFirst));
}
void EnqueueVisitor::
- AddExplicitTemplateArgs(const ExplicitTemplateArgumentList *A) {
+ AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
if (A)
WL.push_back(ExplicitTemplateArgsVisit(
- const_cast<ExplicitTemplateArgumentList*>(A), Parent));
+ const_cast<ASTTemplateArgumentListInfo*>(A), Parent));
}
void EnqueueVisitor::AddMemberRef(FieldDecl *D, SourceLocation L) {
if (D)
@@ -2114,7 +2076,7 @@ void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
}
void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) {
- EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S);
+ EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
}
bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
@@ -2142,13 +2104,14 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
// For now, perform default visitation for Decls.
- if (Visit(MakeCXCursor(D, TU, cast<DeclVisit>(&LI)->isFirst())))
+ if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
+ cast<DeclVisit>(&LI)->isFirst())))
return true;
continue;
}
case VisitorJob::ExplicitTemplateArgsVisitKind: {
- const ExplicitTemplateArgumentList *ArgList =
+ const ASTTemplateArgumentListInfo *ArgList =
cast<ExplicitTemplateArgsVisit>(&LI)->get();
for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
*ArgEnd = Arg + ArgList->NumTemplateArgs;
@@ -2174,14 +2137,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
}
continue;
}
-
- case VisitorJob::NestedNameSpecifierVisitKind: {
- NestedNameSpecifierVisit *V = cast<NestedNameSpecifierVisit>(&LI);
- if (VisitNestedNameSpecifier(V->get(), V->getSourceRange()))
- return true;
- continue;
- }
-
+
case VisitorJob::NestedNameSpecifierLocVisitKind: {
NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
if (VisitNestedNameSpecifierLoc(V->get()))
@@ -2207,7 +2163,7 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
continue;
// Update the current cursor.
- CXCursor Cursor = MakeCXCursor(S, StmtParent, TU);
+ CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
if (!IsInRegionOfInterest(Cursor))
continue;
switch (Visitor(Cursor, Parent, ClientData)) {
@@ -2313,6 +2269,47 @@ bool CursorVisitor::Visit(Stmt *S) {
return result;
}
+namespace {
+typedef llvm::SmallVector<SourceRange, 4> RefNamePieces;
+RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
+ const DeclarationNameInfo &NI,
+ const SourceRange &QLoc,
+ const ASTTemplateArgumentListInfo *TemplateArgs = 0){
+ const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
+ const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
+ const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
+
+ const DeclarationName::NameKind Kind = NI.getName().getNameKind();
+
+ RefNamePieces Pieces;
+
+ if (WantQualifier && QLoc.isValid())
+ Pieces.push_back(QLoc);
+
+ if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
+ Pieces.push_back(NI.getLoc());
+
+ if (WantTemplateArgs && TemplateArgs)
+ Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
+ TemplateArgs->RAngleLoc));
+
+ if (Kind == DeclarationName::CXXOperatorName) {
+ Pieces.push_back(SourceLocation::getFromRawEncoding(
+ NI.getInfo().CXXOperatorName.BeginOpNameLoc));
+ Pieces.push_back(SourceLocation::getFromRawEncoding(
+ NI.getInfo().CXXOperatorName.EndOpNameLoc));
+ }
+
+ if (WantSinglePiece) {
+ SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
+ Pieces.clear();
+ Pieces.push_back(R);
+ }
+
+ return Pieces;
+}
+}
+
//===----------------------------------------------------------------------===//
// Misc. API hooks.
//===----------------------------------------------------------------------===//
@@ -2369,7 +2366,7 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
FileSystemOptions FileSystemOpts;
FileSystemOpts.WorkingDir = CXXIdx->getWorkingDirectory();
- llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
CXXIdx->getOnlyLocalDecls(),
0, 0, true);
@@ -2378,9 +2375,7 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
unsigned clang_defaultEditingTranslationUnitOptions() {
return CXTranslationUnit_PrecompiledPreamble |
- CXTranslationUnit_CacheCompletionResults |
- CXTranslationUnit_CXXPrecompiledPreamble |
- CXTranslationUnit_CXXChainedPCH;
+ CXTranslationUnit_CacheCompletionResults;
}
CXTranslationUnit
@@ -2426,24 +2421,21 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
- bool CompleteTranslationUnit
- = ((options & CXTranslationUnit_Incomplete) == 0);
+ // FIXME: Add a flag for modules.
+ TranslationUnitKind TUKind
+ = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
bool CacheCodeCompetionResults
= options & CXTranslationUnit_CacheCompletionResults;
- bool CXXPrecompilePreamble
- = options & CXTranslationUnit_CXXPrecompiledPreamble;
- bool CXXChainedPCH
- = options & CXTranslationUnit_CXXChainedPCH;
// Configure the diagnostics.
DiagnosticOptions DiagOpts;
- llvm::IntrusiveRefCntPtr<Diagnostic>
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine>
Diags(CompilerInstance::createDiagnostics(DiagOpts, num_command_line_args,
command_line_args));
// Recover resources if we crash before exiting this function.
- llvm::CrashRecoveryContextCleanupRegistrar<Diagnostic,
- llvm::CrashRecoveryContextReleaseRefCleanup<Diagnostic> >
+ llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
+ llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
DiagCleanup(Diags.getPtr());
llvm::OwningPtr<std::vector<ASTUnit::RemappedFile> >
@@ -2454,7 +2446,7 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
for (unsigned I = 0; I != num_unsaved_files; ++I) {
- llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
+ 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,
@@ -2517,10 +2509,8 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
RemappedFiles->size(),
/*RemappedFilesKeepOriginalName=*/true,
PrecompilePreamble,
- CompleteTranslationUnit,
+ TUKind,
CacheCodeCompetionResults,
- CXXPrecompilePreamble,
- CXXChainedPCH,
NestedMacroExpansions));
if (NumErrors != Diags->getClient()->getNumErrors()) {
@@ -2651,7 +2641,7 @@ static void clang_reparseTranslationUnit_Impl(void *UserData) {
std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
for (unsigned I = 0; I != num_unsaved_files; ++I) {
- llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
+ 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,
@@ -2691,7 +2681,7 @@ CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
}
CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
- CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } };
+ CXCursor Result = { CXCursor_TranslationUnit, 0, { 0, 0, TU } };
return Result;
}
@@ -2722,9 +2712,9 @@ CXSourceLocation clang_getLocation(CXTranslationUnit tu,
bool Logging = ::getenv("LIBCLANG_LOGGING");
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
+ ASTUnit::ConcurrencyCheck Check(*CXXUnit);
const FileEntry *File = static_cast<const FileEntry *>(file);
- SourceLocation SLoc
- = CXXUnit->getSourceManager().getLocation(File, line, column);
+ SourceLocation SLoc = CXXUnit->getLocation(File, line, column);
if (SLoc.isInvalid()) {
if (Logging)
llvm::errs() << "clang_getLocation(\"" << File->getName()
@@ -2747,14 +2737,8 @@ CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,
return clang_getNullLocation();
ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu->TUData);
- SourceLocation Start
- = CXXUnit->getSourceManager().getLocation(
- static_cast<const FileEntry *>(file),
- 1, 1);
- if (Start.isInvalid()) return clang_getNullLocation();
-
- SourceLocation SLoc = Start.getFileLocWithOffset(offset);
-
+ SourceLocation SLoc
+ = CXXUnit->getLocation(static_cast<const FileEntry *>(file), offset);
if (SLoc.isInvalid()) return clang_getNullLocation();
return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc);
@@ -2774,6 +2758,19 @@ CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) {
begin.int_data, end.int_data };
return Result;
}
+
+unsigned clang_equalRanges(CXSourceRange range1, CXSourceRange range2)
+{
+ return range1.ptr_data[0] == range2.ptr_data[0]
+ && range1.ptr_data[1] == range2.ptr_data[1]
+ && range1.begin_int_data == range2.begin_int_data
+ && range1.end_int_data == range2.end_int_data;
+}
+
+int clang_Range_isNull(CXSourceRange range) {
+ return clang_equalRanges(range, clang_getNullRange());
+}
+
} // end: extern "C"
static void createNullLocation(CXFile *file, unsigned *line,
@@ -2790,11 +2787,11 @@ static void createNullLocation(CXFile *file, unsigned *line,
}
extern "C" {
-void clang_getInstantiationLocation(CXSourceLocation location,
- CXFile *file,
- unsigned *line,
- unsigned *column,
- unsigned *offset) {
+void clang_getExpansionLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset) {
SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
if (!location.ptr_data[0] || Loc.isInvalid()) {
@@ -2804,11 +2801,11 @@ void clang_getInstantiationLocation(CXSourceLocation location,
const SourceManager &SM =
*static_cast<const SourceManager*>(location.ptr_data[0]);
- SourceLocation InstLoc = SM.getInstantiationLoc(Loc);
+ SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
// Check that the FileID is invalid on the expansion location.
// This can manifest in invalid code.
- FileID fileID = SM.getFileID(InstLoc);
+ FileID fileID = SM.getFileID(ExpansionLoc);
bool Invalid = false;
const SrcMgr::SLocEntry &sloc = SM.getSLocEntry(fileID, &Invalid);
if (!sloc.isFile() || Invalid) {
@@ -2819,11 +2816,48 @@ void clang_getInstantiationLocation(CXSourceLocation location,
if (file)
*file = (void *)SM.getFileEntryForSLocEntry(sloc);
if (line)
- *line = SM.getInstantiationLineNumber(InstLoc);
+ *line = SM.getExpansionLineNumber(ExpansionLoc);
if (column)
- *column = SM.getInstantiationColumnNumber(InstLoc);
+ *column = SM.getExpansionColumnNumber(ExpansionLoc);
if (offset)
- *offset = SM.getDecomposedLoc(InstLoc).second;
+ *offset = SM.getDecomposedLoc(ExpansionLoc).second;
+}
+
+void clang_getPresumedLocation(CXSourceLocation location,
+ CXString *filename,
+ unsigned *line,
+ unsigned *column) {
+ SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
+
+ if (!location.ptr_data[0] || Loc.isInvalid()) {
+ if (filename)
+ *filename = createCXString("");
+ if (line)
+ *line = 0;
+ if (column)
+ *column = 0;
+ }
+ else {
+ const SourceManager &SM =
+ *static_cast<const SourceManager*>(location.ptr_data[0]);
+ PresumedLoc PreLoc = SM.getPresumedLoc(Loc);
+
+ if (filename)
+ *filename = createCXString(PreLoc.getFilename());
+ if (line)
+ *line = PreLoc.getLine();
+ if (column)
+ *column = PreLoc.getColumn();
+ }
+}
+
+void clang_getInstantiationLocation(CXSourceLocation location,
+ CXFile *file,
+ unsigned *line,
+ unsigned *column,
+ unsigned *offset) {
+ // Redirect to new API.
+ clang_getExpansionLocation(location, file, line, column, offset);
}
void clang_getSpellingLocation(CXSourceLocation location,
@@ -2845,7 +2879,7 @@ void clang_getSpellingLocation(CXSourceLocation location,
SM.getFileEntryForID(SM.getDecomposedLoc(SimpleSpellingLoc).first))
SpellLoc = SimpleSpellingLoc;
else
- SpellLoc = SM.getInstantiationLoc(SpellLoc);
+ SpellLoc = SM.getExpansionLoc(SpellLoc);
}
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(SpellLoc);
@@ -2927,7 +2961,7 @@ unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file) {
//===----------------------------------------------------------------------===//
static Decl *getDeclFromExpr(Stmt *E) {
- if (CastExpr *CE = dyn_cast<CastExpr>(E))
+ if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
return getDeclFromExpr(CE->getSubExpr());
if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
@@ -2943,7 +2977,7 @@ static Decl *getDeclFromExpr(Stmt *E) {
if (CallExpr *CE = dyn_cast<CallExpr>(E))
return getDeclFromExpr(CE->getCallee());
- if (CXXConstructExpr *CE = llvm::dyn_cast<CXXConstructExpr>(E))
+ if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
if (!CE->isElidable())
return CE->getConstructor();
if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
@@ -2963,6 +2997,9 @@ static Decl *getDeclFromExpr(Stmt *E) {
}
static SourceLocation getLocationFromExpr(Expr *E) {
+ if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
+ return getLocationFromExpr(CE->getSubExpr());
+
if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
return /*FIXME:*/Msg->getLeftLoc();
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
@@ -2985,7 +3022,6 @@ unsigned clang_visitChildren(CXCursor parent,
CXCursorVisitor visitor,
CXClientData client_data) {
CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
- getCursorASTUnit(parent)->getMaxPCHLevel(),
false);
return CursorVis.VisitChildren(parent);
}
@@ -3030,7 +3066,7 @@ unsigned clang_visitChildrenWithBlock(CXCursor parent,
static CXString getDeclSpelling(Decl *D) {
NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D);
if (!ND) {
- if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
+ if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
return createCXString(Property->getIdentifier()->getName());
@@ -3165,6 +3201,11 @@ CXString clang_getCursorSpelling(CXCursor C) {
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());
+ }
+
return createCXString("");
}
@@ -3176,7 +3217,7 @@ CXString clang_getCursorDisplayName(CXCursor C) {
if (!D)
return createCXString("");
- PrintingPolicy &Policy = getCursorContext(C).PrintingPolicy;
+ PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
D = FunTmpl->getTemplatedDecl();
@@ -3314,10 +3355,86 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return createCXString("LabelRef");
case CXCursor_OverloadedDeclRef:
return createCXString("OverloadedDeclRef");
- case CXCursor_UnexposedExpr:
- return createCXString("UnexposedExpr");
+ case CXCursor_IntegerLiteral:
+ return createCXString("IntegerLiteral");
+ case CXCursor_FloatingLiteral:
+ return createCXString("FloatingLiteral");
+ case CXCursor_ImaginaryLiteral:
+ return createCXString("ImaginaryLiteral");
+ case CXCursor_StringLiteral:
+ return createCXString("StringLiteral");
+ case CXCursor_CharacterLiteral:
+ return createCXString("CharacterLiteral");
+ case CXCursor_ParenExpr:
+ return createCXString("ParenExpr");
+ case CXCursor_UnaryOperator:
+ return createCXString("UnaryOperator");
+ case CXCursor_ArraySubscriptExpr:
+ return createCXString("ArraySubscriptExpr");
+ case CXCursor_BinaryOperator:
+ return createCXString("BinaryOperator");
+ case CXCursor_CompoundAssignOperator:
+ return createCXString("CompoundAssignOperator");
+ case CXCursor_ConditionalOperator:
+ return createCXString("ConditionalOperator");
+ case CXCursor_CStyleCastExpr:
+ return createCXString("CStyleCastExpr");
+ case CXCursor_CompoundLiteralExpr:
+ return createCXString("CompoundLiteralExpr");
+ case CXCursor_InitListExpr:
+ return createCXString("InitListExpr");
+ case CXCursor_AddrLabelExpr:
+ return createCXString("AddrLabelExpr");
+ case CXCursor_StmtExpr:
+ return createCXString("StmtExpr");
+ case CXCursor_GenericSelectionExpr:
+ return createCXString("GenericSelectionExpr");
+ case CXCursor_GNUNullExpr:
+ return createCXString("GNUNullExpr");
+ case CXCursor_CXXStaticCastExpr:
+ return createCXString("CXXStaticCastExpr");
+ case CXCursor_CXXDynamicCastExpr:
+ return createCXString("CXXDynamicCastExpr");
+ case CXCursor_CXXReinterpretCastExpr:
+ return createCXString("CXXReinterpretCastExpr");
+ case CXCursor_CXXConstCastExpr:
+ return createCXString("CXXConstCastExpr");
+ case CXCursor_CXXFunctionalCastExpr:
+ return createCXString("CXXFunctionalCastExpr");
+ case CXCursor_CXXTypeidExpr:
+ return createCXString("CXXTypeidExpr");
+ case CXCursor_CXXBoolLiteralExpr:
+ return createCXString("CXXBoolLiteralExpr");
+ case CXCursor_CXXNullPtrLiteralExpr:
+ return createCXString("CXXNullPtrLiteralExpr");
+ case CXCursor_CXXThisExpr:
+ return createCXString("CXXThisExpr");
+ case CXCursor_CXXThrowExpr:
+ return createCXString("CXXThrowExpr");
+ case CXCursor_CXXNewExpr:
+ return createCXString("CXXNewExpr");
+ case CXCursor_CXXDeleteExpr:
+ return createCXString("CXXDeleteExpr");
+ case CXCursor_UnaryExpr:
+ return createCXString("UnaryExpr");
+ case CXCursor_ObjCStringLiteral:
+ return createCXString("ObjCStringLiteral");
+ case CXCursor_ObjCEncodeExpr:
+ return createCXString("ObjCEncodeExpr");
+ case CXCursor_ObjCSelectorExpr:
+ return createCXString("ObjCSelectorExpr");
+ case CXCursor_ObjCProtocolExpr:
+ return createCXString("ObjCProtocolExpr");
+ case CXCursor_ObjCBridgedCastExpr:
+ return createCXString("ObjCBridgedCastExpr");
case CXCursor_BlockExpr:
return createCXString("BlockExpr");
+ case CXCursor_PackExpansionExpr:
+ return createCXString("PackExpansionExpr");
+ case CXCursor_SizeOfPackExpr:
+ return createCXString("SizeOfPackExpr");
+ case CXCursor_UnexposedExpr:
+ return createCXString("UnexposedExpr");
case CXCursor_DeclRefExpr:
return createCXString("DeclRefExpr");
case CXCursor_MemberRefExpr:
@@ -3328,8 +3445,66 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return createCXString("ObjCMessageExpr");
case CXCursor_UnexposedStmt:
return createCXString("UnexposedStmt");
+ case CXCursor_DeclStmt:
+ return createCXString("DeclStmt");
case CXCursor_LabelStmt:
return createCXString("LabelStmt");
+ case CXCursor_CompoundStmt:
+ return createCXString("CompoundStmt");
+ case CXCursor_CaseStmt:
+ return createCXString("CaseStmt");
+ case CXCursor_DefaultStmt:
+ return createCXString("DefaultStmt");
+ case CXCursor_IfStmt:
+ return createCXString("IfStmt");
+ case CXCursor_SwitchStmt:
+ return createCXString("SwitchStmt");
+ case CXCursor_WhileStmt:
+ return createCXString("WhileStmt");
+ case CXCursor_DoStmt:
+ return createCXString("DoStmt");
+ case CXCursor_ForStmt:
+ return createCXString("ForStmt");
+ case CXCursor_GotoStmt:
+ return createCXString("GotoStmt");
+ case CXCursor_IndirectGotoStmt:
+ return createCXString("IndirectGotoStmt");
+ case CXCursor_ContinueStmt:
+ return createCXString("ContinueStmt");
+ case CXCursor_BreakStmt:
+ return createCXString("BreakStmt");
+ case CXCursor_ReturnStmt:
+ return createCXString("ReturnStmt");
+ case CXCursor_AsmStmt:
+ return createCXString("AsmStmt");
+ case CXCursor_ObjCAtTryStmt:
+ return createCXString("ObjCAtTryStmt");
+ case CXCursor_ObjCAtCatchStmt:
+ return createCXString("ObjCAtCatchStmt");
+ case CXCursor_ObjCAtFinallyStmt:
+ return createCXString("ObjCAtFinallyStmt");
+ case CXCursor_ObjCAtThrowStmt:
+ return createCXString("ObjCAtThrowStmt");
+ case CXCursor_ObjCAtSynchronizedStmt:
+ return createCXString("ObjCAtSynchronizedStmt");
+ case CXCursor_ObjCAutoreleasePoolStmt:
+ return createCXString("ObjCAutoreleasePoolStmt");
+ case CXCursor_ObjCForCollectionStmt:
+ return createCXString("ObjCForCollectionStmt");
+ case CXCursor_CXXCatchStmt:
+ return createCXString("CXXCatchStmt");
+ case CXCursor_CXXTryStmt:
+ return createCXString("CXXTryStmt");
+ case CXCursor_CXXForRangeStmt:
+ return createCXString("CXXForRangeStmt");
+ case CXCursor_SEHTryStmt:
+ return createCXString("SEHTryStmt");
+ case CXCursor_SEHExceptStmt:
+ return createCXString("SEHExceptStmt");
+ case CXCursor_SEHFinallyStmt:
+ return createCXString("SEHFinallyStmt");
+ case CXCursor_NullStmt:
+ return createCXString("NullStmt");
case CXCursor_InvalidFile:
return createCXString("InvalidFile");
case CXCursor_InvalidCode:
@@ -3348,6 +3523,12 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return createCXString("attribute(iboutlet)");
case CXCursor_IBOutletCollectionAttr:
return createCXString("attribute(iboutletcollection)");
+ case CXCursor_CXXFinalAttr:
+ return createCXString("attribute(final)");
+ case CXCursor_CXXOverrideAttr:
+ return createCXString("attribute(override)");
+ case CXCursor_AnnotateAttr:
+ return createCXString("attribute(annotate)");
case CXCursor_PreprocessingDirective:
return createCXString("preprocessing directive");
case CXCursor_MacroDefinition:
@@ -3392,6 +3573,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return createCXString("ObjCSynthesizeDecl");
case CXCursor_ObjCDynamicDecl:
return createCXString("ObjCDynamicDecl");
+ case CXCursor_CXXAccessSpecifier:
+ return createCXString("CXXAccessSpecifier");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -3400,18 +3583,35 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
struct GetCursorData {
SourceLocation TokenBeginLoc;
+ bool PointsAtMacroArgExpansion;
CXCursor &BestCursor;
- GetCursorData(SourceLocation tokenBegin, CXCursor &outputCursor)
- : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) { }
+ GetCursorData(SourceManager &SM,
+ SourceLocation tokenBegin, CXCursor &outputCursor)
+ : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
+ PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
+ }
};
-enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
- CXCursor parent,
- CXClientData client_data) {
+static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
+ CXCursor parent,
+ CXClientData client_data) {
GetCursorData *Data = static_cast<GetCursorData *>(client_data);
CXCursor *BestCursor = &Data->BestCursor;
+ // If we point inside a macro argument we should provide info of what the
+ // token is so use the actual cursor, don't replace it with a macro expansion
+ // cursor.
+ if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
+ return CXChildVisit_Recurse;
+
+ if (clang_isDeclaration(cursor.kind)) {
+ // Avoid having the implicit methods override the property decls.
+ if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(getCursorDecl(cursor)))
+ if (MD->isImplicit())
+ return CXChildVisit_Break;
+ }
+
if (clang_isExpression(cursor.kind) &&
clang_isDeclaration(BestCursor->kind)) {
Decl *D = getCursorDecl(*BestCursor);
@@ -3431,14 +3631,12 @@ enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
// clang_getCursor() to point at the constructor.
if (clang_isExpression(BestCursor->kind) &&
isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
- cursor.kind == CXCursor_TypeRef)
- return CXChildVisit_Recurse;
-
- // Don't override a preprocessing cursor with another preprocessing
- // cursor; we want the outermost preprocessing cursor.
- if (clang_isPreprocessing(cursor.kind) &&
- clang_isPreprocessing(BestCursor->kind))
+ cursor.kind == CXCursor_TypeRef) {
+ // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
+ // as having the actual point on the type reference.
+ *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
return CXChildVisit_Recurse;
+ }
*BestCursor = cursor;
return CXChildVisit_Recurse;
@@ -3451,31 +3649,10 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
ASTUnit::ConcurrencyCheck Check(*CXXUnit);
- // Translate the given source location to make it point at the beginning of
- // the token under the cursor.
SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
-
- // Guard against an invalid SourceLocation, or we may assert in one
- // of the following calls.
- if (SLoc.isInvalid())
- return clang_getNullCursor();
+ CXCursor Result = cxcursor::getCursor(TU, SLoc);
bool Logging = getenv("LIBCLANG_LOGGING");
- SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
- CXXUnit->getASTContext().getLangOptions());
-
- CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
- if (SLoc.isValid()) {
- // FIXME: Would be great to have a "hint" cursor, then walk from that
- // hint cursor upward until we find a cursor whose source range encloses
- // the region of interest, rather than starting from the translation unit.
- GetCursorData ResultData(SLoc, Result);
- CXCursor Parent = clang_getTranslationUnitCursor(TU);
- CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
- Decl::MaxPCHLevel, true, SourceLocation(SLoc));
- CursorVis.VisitChildren(Parent);
- }
-
if (Logging) {
CXFile SearchFile;
unsigned SearchLine, SearchColumn;
@@ -3485,10 +3662,9 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
- clang_getInstantiationLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
- 0);
- clang_getInstantiationLocation(ResultLoc, &ResultFile, &ResultLine,
- &ResultColumn, 0);
+ clang_getExpansionLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
+ clang_getExpansionLocation(ResultLoc, &ResultFile, &ResultLine,
+ &ResultColumn, 0);
SearchFileName = clang_getFileName(SearchFile);
ResultFileName = clang_getFileName(ResultFile);
KindSpelling = clang_getCursorKindSpelling(Result.kind);
@@ -3510,8 +3686,8 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
= clang_getCursorKindSpelling(Definition.kind);
CXFile DefinitionFile;
unsigned DefinitionLine, DefinitionColumn;
- clang_getInstantiationLocation(DefinitionLoc, &DefinitionFile,
- &DefinitionLine, &DefinitionColumn, 0);
+ clang_getExpansionLocation(DefinitionLoc, &DefinitionFile,
+ &DefinitionLine, &DefinitionColumn, 0);
CXString DefinitionFileName = clang_getFileName(DefinitionFile);
fprintf(stderr, " -> %s(%s:%d:%d)\n",
clang_getCString(DefinitionKindSpelling),
@@ -3694,8 +3870,6 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
Decl *D = getCursorDecl(C);
SourceLocation Loc = D->getLocation();
- if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
- Loc = Class->getClassLoc();
// FIXME: Multiple variables declared in a single declaration
// currently lack the information needed to correctly determine their
// ranges when accounting for the type-specifier. We use context
@@ -3711,6 +3885,37 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) {
} // end extern "C"
+CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
+ assert(TU);
+
+ // Guard against an invalid SourceLocation, or we may assert in one
+ // of the following calls.
+ if (SLoc.isInvalid())
+ return clang_getNullCursor();
+
+ ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+
+ // Translate the given source location to make it point at the beginning of
+ // the token under the cursor.
+ SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
+ CXXUnit->getASTContext().getLangOptions());
+
+ CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
+ if (SLoc.isValid()) {
+ // FIXME: Would be great to have a "hint" cursor, then walk from that
+ // hint cursor upward until we find a cursor whose source range encloses
+ // the region of interest, rather than starting from the translation unit.
+ GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
+ CXCursor Parent = clang_getTranslationUnitCursor(TU);
+ CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
+ /*VisitPreprocessorLast=*/true,
+ SourceLocation(SLoc));
+ CursorVis.VisitChildren(Parent);
+ }
+
+ return Result;
+}
+
static SourceRange getRawCursorExtent(CXCursor C) {
if (clang_isReference(C.kind)) {
switch (C.kind) {
@@ -3756,17 +3961,29 @@ static SourceRange getRawCursorExtent(CXCursor C) {
if (clang_isStatement(C.kind))
return getCursorStmt(C)->getSourceRange();
+ if (clang_isAttribute(C.kind))
+ return getCursorAttr(C)->getRange();
+
if (C.kind == CXCursor_PreprocessingDirective)
return cxcursor::getCursorPreprocessingDirective(C);
- if (C.kind == CXCursor_MacroExpansion)
- return cxcursor::getCursorMacroExpansion(C)->getSourceRange();
+ if (C.kind == CXCursor_MacroExpansion) {
+ ASTUnit *TU = getCursorASTUnit(C);
+ SourceRange Range = cxcursor::getCursorMacroExpansion(C)->getSourceRange();
+ return TU->mapRangeFromPreamble(Range);
+ }
- if (C.kind == CXCursor_MacroDefinition)
- return cxcursor::getCursorMacroDefinition(C)->getSourceRange();
+ if (C.kind == CXCursor_MacroDefinition) {
+ ASTUnit *TU = getCursorASTUnit(C);
+ SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
+ return TU->mapRangeFromPreamble(Range);
+ }
- if (C.kind == CXCursor_InclusionDirective)
- return cxcursor::getCursorInclusionDirective(C)->getSourceRange();
+ if (C.kind == CXCursor_InclusionDirective) {
+ ASTUnit *TU = getCursorASTUnit(C);
+ SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
+ return TU->mapRangeFromPreamble(Range);
+ }
if (C.kind >= CXCursor_FirstDecl && C.kind <= CXCursor_LastDecl) {
Decl *D = cxcursor::getCursorDecl(C);
@@ -3847,7 +4064,7 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
if (ObjCForwardProtocolDecl *Protocols
= dyn_cast<ObjCForwardProtocolDecl>(D))
return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), tu);
- if (ObjCPropertyImplDecl *PropImpl =llvm::dyn_cast<ObjCPropertyImplDecl>(D))
+ if (ObjCPropertyImplDecl *PropImpl =dyn_cast<ObjCPropertyImplDecl>(D))
if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
return MakeCXCursor(Property, tu);
@@ -3857,8 +4074,12 @@ CXCursor clang_getCursorReferenced(CXCursor C) {
if (clang_isExpression(C.kind)) {
Expr *E = getCursorExpr(C);
Decl *D = getDeclFromExpr(E);
- if (D)
- return MakeCXCursor(D, tu);
+ if (D) {
+ CXCursor declCursor = MakeCXCursor(D, tu);
+ declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
+ declCursor);
+ return declCursor;
+ }
if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
return MakeCursorOverloadedDeclRef(Ovl, tu);
@@ -3981,6 +4202,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
case Decl::StaticAssert:
case Decl::Block:
case Decl::Label: // FIXME: Is this right??
+ case Decl::ClassScopeFunctionSpecialization:
return C;
// Declaration kinds that don't make any sense here, but are
@@ -4171,8 +4393,8 @@ unsigned clang_getNumOverloadedDecls(CXCursor C) {
Decl *D = Storage.get<Decl*>();
if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
return Using->shadow_size();
- if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
- return Classes->size();
+ if (isa<ObjCClassDecl>(D))
+ return 1;
if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
return Protocols->protocol_size();
@@ -4202,10 +4424,8 @@ CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
std::advance(Pos, index);
return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
}
-
if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
- return MakeCXCursor(Classes->begin()[index].getInterface(), TU);
-
+ return MakeCXCursor(Classes->getForwardInterfaceDecl(), TU);
if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
return MakeCXCursor(Protocols->protocol_begin()[index], TU);
@@ -4233,6 +4453,54 @@ void clang_getDefinitionSpellingAndExtent(CXCursor C,
*endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
}
+
+CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
+ unsigned PieceIndex) {
+ RefNamePieces Pieces;
+
+ switch (C.kind) {
+ case CXCursor_MemberRefExpr:
+ if (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)))
+ Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
+ E->getQualifierLoc().getSourceRange(),
+ E->getExplicitTemplateArgsOpt());
+ break;
+
+ case CXCursor_CallExpr:
+ if (CXXOperatorCallExpr *OCE =
+ dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
+ Expr *Callee = OCE->getCallee();
+ if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
+ Callee = ICE->getSubExpr();
+
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
+ Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
+ DRE->getQualifierLoc().getSourceRange());
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (Pieces.empty()) {
+ if (PieceIndex == 0)
+ return clang_getCursorExtent(C);
+ } else if (PieceIndex < Pieces.size()) {
+ SourceRange R = Pieces[PieceIndex];
+ if (R.isValid())
+ return cxloc::translateSourceRange(getCursorContext(C), R);
+ }
+
+ return clang_getNullRange();
+}
+
void clang_enableStackTraces(void) {
llvm::sys::PrintStackTraceOnErrorSignal();
}
@@ -4273,7 +4541,7 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
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(llvm::StringRef(Text, CXTok.int_data[2]));
+ return createCXString(StringRef(Text, CXTok.int_data[2]));
}
case CXToken_Punctuation:
@@ -4289,9 +4557,9 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
std::pair<FileID, unsigned> LocInfo
- = CXXUnit->getSourceManager().getDecomposedLoc(Loc);
+ = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
bool Invalid = false;
- llvm::StringRef Buffer
+ StringRef Buffer
= CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
if (Invalid)
return createCXString("");
@@ -4317,28 +4585,13 @@ CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
}
-void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
- CXToken **Tokens, unsigned *NumTokens) {
- if (Tokens)
- *Tokens = 0;
- if (NumTokens)
- *NumTokens = 0;
-
- ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
- if (!CXXUnit || !Tokens || !NumTokens)
- return;
-
- ASTUnit::ConcurrencyCheck Check(*CXXUnit);
-
- SourceRange R = cxloc::translateCXSourceRange(Range);
- if (R.isInvalid())
- return;
-
+static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
+ SmallVectorImpl<CXToken> &CXTokens) {
SourceManager &SourceMgr = CXXUnit->getSourceManager();
std::pair<FileID, unsigned> BeginLocInfo
- = SourceMgr.getDecomposedLoc(R.getBegin());
+ = SourceMgr.getDecomposedLoc(Range.getBegin());
std::pair<FileID, unsigned> EndLocInfo
- = SourceMgr.getDecomposedLoc(R.getEnd());
+ = SourceMgr.getDecomposedLoc(Range.getEnd());
// Cannot tokenize across files.
if (BeginLocInfo.first != EndLocInfo.first)
@@ -4346,7 +4599,7 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
// Create a lexer
bool Invalid = false;
- llvm::StringRef Buffer
+ StringRef Buffer
= SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
if (Invalid)
return;
@@ -4358,7 +4611,6 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
// Lex tokens until we hit the end of the range.
const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
- llvm::SmallVector<CXToken, 32> CXTokens;
Token Tok;
bool previousWasAt = false;
do {
@@ -4403,6 +4655,27 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
CXTokens.push_back(CXTok);
previousWasAt = Tok.is(tok::at);
} while (Lex.getBufferLocation() <= EffectiveBufferEnd);
+}
+
+void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
+ CXToken **Tokens, unsigned *NumTokens) {
+ if (Tokens)
+ *Tokens = 0;
+ if (NumTokens)
+ *NumTokens = 0;
+
+ ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+ if (!CXXUnit || !Tokens || !NumTokens)
+ return;
+
+ ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+ SourceRange R = cxloc::translateCXSourceRange(Range);
+ if (R.isInvalid())
+ return;
+
+ SmallVector<CXToken, 32> CXTokens;
+ getTokens(CXXUnit, R, CXTokens);
if (CXTokens.empty())
return;
@@ -4445,6 +4718,16 @@ class AnnotateTokensWorker {
SourceLocation GetTokenLoc(unsigned tokI) {
return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
}
+ bool isFunctionMacroToken(unsigned tokI) const {
+ return Tokens[tokI].int_data[3] != 0;
+ }
+ SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
+ return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
+ }
+
+ void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
+ void annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
+ SourceRange);
public:
AnnotateTokensWorker(AnnotateTokensData &annotated,
@@ -4453,8 +4736,7 @@ public:
: Annotated(annotated), Tokens(tokens), Cursors(cursors),
NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
AnnotateVis(tu,
- AnnotateTokensVisitor, this,
- Decl::MaxPCHLevel, true, RegionOfInterest),
+ AnnotateTokensVisitor, this, true, RegionOfInterest),
SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
HasContextSensitiveKeywords(false) { }
@@ -4497,6 +4779,65 @@ void AnnotateTokensWorker::AnnotateTokens(CXCursor parent) {
}
}
+/// \brief It annotates and advances tokens with a cursor until the comparison
+//// between the cursor location and the source range is the same as
+/// \arg compResult.
+///
+/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
+/// Pass RangeOverlap to annotate tokens inside a range.
+void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
+ RangeComparisonResult compResult,
+ SourceRange range) {
+ while (MoreTokens()) {
+ const unsigned I = NextToken();
+ if (isFunctionMacroToken(I))
+ return annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range);
+
+ SourceLocation TokLoc = GetTokenLoc(I);
+ if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
+ Cursors[I] = updateC;
+ AdvanceToken();
+ continue;
+ }
+ break;
+ }
+}
+
+/// \brief Special annotation handling for macro argument tokens.
+void AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
+ CXCursor updateC,
+ RangeComparisonResult compResult,
+ SourceRange range) {
+ assert(MoreTokens());
+ assert(isFunctionMacroToken(NextToken()) &&
+ "Should be called only for macro arg tokens");
+
+ // This works differently than annotateAndAdvanceTokens; because expanded
+ // macro arguments can have arbitrary translation-unit source order, we do not
+ // advance the token index one by one until a token fails the range test.
+ // We only advance once past all of the macro arg tokens if all of them
+ // pass the range test. If one of them fails we keep the token index pointing
+ // at the start of the macro arg tokens so that the failing token will be
+ // annotated by a subsequent annotation try.
+
+ bool atLeastOneCompFail = false;
+
+ unsigned I = NextToken();
+ for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
+ SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
+ if (TokLoc.isFileID())
+ continue; // not macro arg token, it's parens or comma.
+ if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
+ if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
+ Cursors[I] = updateC;
+ } else
+ atLeastOneCompFail = true;
+ }
+
+ if (!atLeastOneCompFail)
+ TokIdx = I; // All of the tokens were handled, advance beyond all of them.
+}
+
enum CXChildVisitResult
AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
CXSourceLocation Loc = clang_getCursorLocation(cursor);
@@ -4584,7 +4925,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
SourceLocation TokLoc = GetTokenLoc(I);
switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
case RangeBefore:
- assert(0 && "Infeasible");
+ llvm_unreachable("Infeasible");
case RangeAfter:
break;
case RangeOverlap:
@@ -4611,12 +4952,6 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
if (cursorK >= CXCursor_FirstDecl && cursorK <= CXCursor_LastDecl) {
Decl *D = cxcursor::getCursorDecl(cursor);
- // Don't visit synthesized ObjC methods, since they have no syntatic
- // representation in the source.
- if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- if (MD->isSynthesized())
- return CXChildVisit_Continue;
- }
SourceLocation StartLoc;
if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
@@ -4654,20 +4989,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
(clang_isInvalid(K) || K == CXCursor_TranslationUnit)
? clang_getNullCursor() : parent;
- while (MoreTokens()) {
- const unsigned I = NextToken();
- SourceLocation TokLoc = GetTokenLoc(I);
- switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
- case RangeBefore:
- Cursors[I] = updateC;
- AdvanceToken();
- continue;
- case RangeAfter:
- case RangeOverlap:
- break;
- }
- break;
- }
+ annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
// Avoid having the cursor of an expression "overwrite" the annotation of the
// variable declaration that it belongs to.
@@ -4692,46 +5014,19 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
VisitChildren(cursor);
const unsigned AfterChildren = NextToken();
- // Adjust 'Last' to the last token within the extent of the cursor.
- while (MoreTokens()) {
- const unsigned I = NextToken();
- SourceLocation TokLoc = GetTokenLoc(I);
- switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
- case RangeBefore:
- assert(0 && "Infeasible");
- case RangeAfter:
- break;
- case RangeOverlap:
- Cursors[I] = updateC;
- AdvanceToken();
- continue;
- }
- break;
- }
- const unsigned Last = NextToken();
+ // Scan the tokens that are at the end of the cursor, but are not captured
+ // but the child cursors.
+ annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
// Scan the tokens that are at the beginning of the cursor, but are not
// capture by the child cursors.
-
- // For AST elements within macros, rely on a post-annotate pass to
- // to correctly annotate the tokens with cursors. Otherwise we can
- // get confusing results of having tokens that map to cursors that really
- // are expanded by an instantiation.
- if (L.isMacroID())
- cursor = clang_getNullCursor();
-
for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
break;
Cursors[I] = cursor;
}
- // Scan the tokens that are at the end of the cursor, but are not captured
- // but the child cursors.
- for (unsigned I = AfterChildren; I != Last; ++I)
- Cursors[I] = cursor;
- TokIdx = Last;
return CXChildVisit_Continue;
}
@@ -4742,6 +5037,74 @@ static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
}
namespace {
+
+/// \brief Uses the macro expansions in the preprocessing record to find
+/// and mark tokens that are macro arguments. This info is used by the
+/// AnnotateTokensWorker.
+class MarkMacroArgTokensVisitor {
+ SourceManager &SM;
+ CXToken *Tokens;
+ unsigned NumTokens;
+ unsigned CurIdx;
+
+public:
+ MarkMacroArgTokensVisitor(SourceManager &SM,
+ CXToken *tokens, unsigned numTokens)
+ : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
+
+ CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
+ if (cursor.kind != CXCursor_MacroExpansion)
+ return CXChildVisit_Continue;
+
+ SourceRange macroRange = getCursorMacroExpansion(cursor)->getSourceRange();
+ if (macroRange.getBegin() == macroRange.getEnd())
+ return CXChildVisit_Continue; // it's not a function macro.
+
+ for (; CurIdx < NumTokens; ++CurIdx) {
+ if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
+ macroRange.getBegin()))
+ break;
+ }
+
+ if (CurIdx == NumTokens)
+ return CXChildVisit_Break;
+
+ for (; CurIdx < NumTokens; ++CurIdx) {
+ SourceLocation tokLoc = getTokenLoc(CurIdx);
+ if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
+ break;
+
+ setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
+ }
+
+ if (CurIdx == NumTokens)
+ return CXChildVisit_Break;
+
+ return CXChildVisit_Continue;
+ }
+
+private:
+ SourceLocation getTokenLoc(unsigned tokI) {
+ return SourceLocation::getFromRawEncoding(Tokens[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();
+ }
+};
+
+} // end anonymous namespace
+
+static CXChildVisitResult
+MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
+ CXClientData client_data) {
+ return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
+ parent);
+}
+
+namespace {
struct clang_annotateTokens_Data {
CXTranslationUnit TU;
ASTUnit *CXXUnit;
@@ -4751,6 +5114,73 @@ namespace {
};
}
+static void annotatePreprocessorTokens(CXTranslationUnit TU,
+ SourceRange RegionOfInterest,
+ AnnotateTokensData &Annotated) {
+ ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU->TUData);
+
+ SourceManager &SourceMgr = CXXUnit->getSourceManager();
+ std::pair<FileID, unsigned> BeginLocInfo
+ = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
+ std::pair<FileID, unsigned> EndLocInfo
+ = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
+
+ if (BeginLocInfo.first != EndLocInfo.first)
+ return;
+
+ StringRef Buffer;
+ bool Invalid = false;
+ Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
+ if (Buffer.empty() || Invalid)
+ return;
+
+ Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
+ CXXUnit->getASTContext().getLangOptions(),
+ Buffer.begin(), Buffer.data() + BeginLocInfo.second,
+ Buffer.end());
+ Lex.SetCommentRetentionState(true);
+
+ // 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);
+
+ 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.
+ //
+ // 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;
+ }
+
+ if (Tok.isAtStartOfLine())
+ goto reprocess;
+
+ continue;
+ }
+
+ if (Tok.is(tok::eof))
+ break;
+ }
+}
+
// This gets run a separate thread to avoid stack blowout.
static void clang_annotateTokensImpl(void *UserData) {
CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
@@ -4770,65 +5200,19 @@ static void clang_annotateTokensImpl(void *UserData) {
// 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.
- SourceManager &SourceMgr = CXXUnit->getSourceManager();
- std::pair<FileID, unsigned> BeginLocInfo
- = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin());
- std::pair<FileID, unsigned> EndLocInfo
- = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd());
+ annotatePreprocessorTokens(TU, RegionOfInterest, Annotated);
- llvm::StringRef Buffer;
- bool Invalid = false;
- if (BeginLocInfo.first == EndLocInfo.first &&
- ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) &&
- !Invalid) {
- Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
- CXXUnit->getASTContext().getLangOptions(),
- Buffer.begin(), Buffer.data() + BeginLocInfo.second,
- Buffer.end());
- Lex.SetCommentRetentionState(true);
-
- // 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);
-
- 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.
- //
- // FIXME: Some simple tests here could identify macro definitions and
- // #undefs, to provide specific cursor kinds for those.
- llvm::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;
- }
-
- if (Tok.isAtStartOfLine())
- goto reprocess;
-
- continue;
- }
-
- if (Tok.is(tok::eof))
- break;
- }
+ if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
+ // Search and mark tokens that are macro argument expansions.
+ MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
+ Tokens, NumTokens);
+ CursorVisitor MacroArgMarker(TU,
+ MarkMacroArgTokensVisitorDelegate, &Visitor,
+ true, RegionOfInterest);
+ MacroArgMarker.visitPreprocessedEntitiesInRegion();
}
// Annotate all of the source locations in the region of interest that map to
@@ -4888,44 +5272,10 @@ static void clang_annotateTokensImpl(void *UserData) {
Tokens[I].int_data[0] = CXToken_Keyword;
continue;
}
-
- if (Cursors[I].kind == CXCursor_CXXMethod) {
- IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
- if (CXXMethodDecl *Method
- = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(Cursors[I]))) {
- if ((Method->hasAttr<FinalAttr>() ||
- Method->hasAttr<OverrideAttr>()) &&
- Method->getLocation().getRawEncoding() != Tokens[I].int_data[1] &&
- llvm::StringSwitch<bool>(II->getName())
- .Case("final", true)
- .Case("override", true)
- .Default(false))
- Tokens[I].int_data[0] = CXToken_Keyword;
- }
- continue;
- }
-
- if (Cursors[I].kind == CXCursor_ClassDecl ||
- Cursors[I].kind == CXCursor_StructDecl ||
- Cursors[I].kind == CXCursor_ClassTemplate) {
- IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
- if (II->getName() == "final") {
- // We have to be careful with 'final', since it could be the name
- // of a member class rather than the context-sensitive keyword.
- // So, check whether the cursor associated with this
- Decl *D = getCursorDecl(Cursors[I]);
- if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(D)) {
- if ((Record->hasAttr<FinalAttr>()) &&
- Record->getIdentifier() != II)
- Tokens[I].int_data[0] = CXToken_Keyword;
- } else if (ClassTemplateDecl *ClassTemplate
- = dyn_cast_or_null<ClassTemplateDecl>(D)) {
- CXXRecordDecl *Record = ClassTemplate->getTemplatedDecl();
- if ((Record->hasAttr<FinalAttr>()) &&
- Record->getIdentifier() != II)
- Tokens[I].int_data[0] = CXToken_Keyword;
- }
- }
+
+ if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
+ Cursors[I].kind == CXCursor_CXXOverrideAttr) {
+ Tokens[I].int_data[0] = CXToken_Keyword;
continue;
}
}
@@ -5122,62 +5472,6 @@ CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
return clang_getNullCursor();
}
-static void CollectOverriddenMethods(DeclContext *Ctx,
- ObjCMethodDecl *Method,
- llvm::SmallVectorImpl<ObjCMethodDecl *> &Methods) {
- if (!Ctx)
- return;
-
- // If we have a class or category implementation, jump straight to the
- // interface.
- if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
- return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
-
- ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
- if (!Container)
- return;
-
- // Check whether we have a matching method at this level.
- if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
- Method->isInstanceMethod()))
- if (Method != Overridden) {
- // We found an override at this level; there is no need to look
- // into other protocols or categories.
- Methods.push_back(Overridden);
- return;
- }
-
- if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
- for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
- PEnd = Protocol->protocol_end();
- P != PEnd; ++P)
- CollectOverriddenMethods(*P, Method, Methods);
- }
-
- if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
- for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
- PEnd = Category->protocol_end();
- P != PEnd; ++P)
- CollectOverriddenMethods(*P, Method, Methods);
- }
-
- if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
- for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
- PEnd = Interface->protocol_end();
- P != PEnd; ++P)
- CollectOverriddenMethods(*P, Method, Methods);
-
- for (ObjCCategoryDecl *Category = Interface->getCategoryList();
- Category; Category = Category->getNextClassCategory())
- CollectOverriddenMethods(Category, Method, Methods);
-
- // We only look into the superclass if we haven't found anything yet.
- if (Methods.empty())
- if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
- return CollectOverriddenMethods(Super, Method, Methods);
- }
-}
-
void clang_getOverriddenCursors(CXCursor cursor,
CXCursor **overridden,
unsigned *num_overridden) {
@@ -5188,45 +5482,12 @@ void clang_getOverriddenCursors(CXCursor cursor,
if (!overridden || !num_overridden)
return;
- if (!clang_isDeclaration(cursor.kind))
- return;
-
- Decl *D = getCursorDecl(cursor);
- if (!D)
- return;
+ SmallVector<CXCursor, 8> Overridden;
+ cxcursor::getOverriddenCursors(cursor, Overridden);
- // Handle C++ member functions.
- CXTranslationUnit TU = getCursorTU(cursor);
- if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
- *num_overridden = CXXMethod->size_overridden_methods();
- if (!*num_overridden)
- return;
-
- *overridden = new CXCursor [*num_overridden];
- unsigned I = 0;
- for (CXXMethodDecl::method_iterator
- M = CXXMethod->begin_overridden_methods(),
- MEnd = CXXMethod->end_overridden_methods();
- M != MEnd; (void)++M, ++I)
- (*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
- return;
- }
-
- ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
- if (!Method)
- return;
-
- // Handle Objective-C methods.
- llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
- CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
-
- if (Methods.empty())
- return;
-
- *num_overridden = Methods.size();
- *overridden = new CXCursor [Methods.size()];
- for (unsigned I = 0, N = Methods.size(); I != N; ++I)
- (*overridden)[I] = MakeCXCursor(Methods[I], TU);
+ *num_overridden = Overridden.size();
+ *overridden = new CXCursor [Overridden.size()];
+ std::copy(Overridden.begin(), Overridden.end(), *overridden);
}
void clang_disposeOverriddenCursors(CXCursor *overridden) {
@@ -5274,7 +5535,6 @@ unsigned clang_CXXMethod_isVirtual(CXCursor C) {
Method = dyn_cast_or_null<CXXMethodDecl>(D);
return (Method && Method->isVirtual()) ? 1 : 0;
}
-
} // end: extern "C"
//===----------------------------------------------------------------------===//
@@ -5289,7 +5549,7 @@ CXType clang_getIBOutletCollectionType(CXCursor C) {
IBOutletCollectionAttr *A =
cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
- return cxtype::MakeCXType(A->getInterFace(), cxcursor::getCursorTU(C));
+ return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
}
} // end: extern "C"
@@ -5347,6 +5607,12 @@ const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
case CXTUResourceUsage_PreprocessingRecord:
str = "Preprocessor: PreprocessingRecord";
break;
+ case CXTUResourceUsage_SourceManager_DataStructures:
+ str = "SourceManager: data structures and tables";
+ break;
+ case CXTUResourceUsage_Preprocessor_HeaderSearch:
+ str = "Preprocessor: header search tables";
+ break;
}
return str;
}
@@ -5399,9 +5665,13 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
createCXTUResourceUsageEntry(*entries,
CXTUResourceUsage_SourceManager_Membuffer_Malloc,
(unsigned long) srcBufs.malloc_bytes);
- createCXTUResourceUsageEntry(*entries,
+ createCXTUResourceUsageEntry(*entries,
CXTUResourceUsage_SourceManager_Membuffer_MMap,
(unsigned long) srcBufs.mmap_bytes);
+ createCXTUResourceUsageEntry(*entries,
+ CXTUResourceUsage_SourceManager_DataStructures,
+ (unsigned long) astContext.getSourceManager()
+ .getDataStructureSizes());
// How much memory is being used by the ExternalASTSource?
if (ExternalASTSource *esrc = astContext.getExternalSource()) {
@@ -5428,6 +5698,9 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
pRec->getTotalMemory());
}
+ createCXTUResourceUsageEntry(*entries,
+ CXTUResourceUsage_Preprocessor_HeaderSearch,
+ pp.getHeaderSearchInfo().getTotalMemory());
CXTUResourceUsage usage = { (void*) entries.get(),
(unsigned) entries->size(),
diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp
index 0f49f65c2b809..fb0ccb146f7dc 100644
--- a/tools/libclang/CIndexCXX.cpp
+++ b/tools/libclang/CIndexCXX.cpp
@@ -31,11 +31,16 @@ unsigned clang_isVirtualBase(CXCursor C) {
}
enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) {
- if (C.kind != CXCursor_CXXBaseSpecifier)
+ AccessSpecifier spec = AS_none;
+
+ if (C.kind == CXCursor_CXXAccessSpecifier)
+ spec = getCursorDecl(C)->getAccess();
+ else if (C.kind == CXCursor_CXXBaseSpecifier)
+ spec = getCursorCXXBaseSpecifier(C)->getAccessSpecifier();
+ else
return CX_CXXInvalidAccessSpecifier;
- CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
- switch (B->getAccessSpecifier()) {
+ switch (spec) {
case AS_public: return CX_CXXPublic;
case AS_protected: return CX_CXXProtected;
case AS_private: return CX_CXXPrivate;
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 832e2f2f7147f..c19b3404920f6 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -15,7 +15,12 @@
#include "CIndexer.h"
#include "CXTranslationUnit.h"
#include "CXString.h"
+#include "CXCursor.h"
+#include "CXString.h"
#include "CIndexDiagnostic.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/Frontend/ASTUnit.h"
@@ -198,6 +203,20 @@ clang_getCompletionAvailability(CXCompletionString completion_string) {
: CXAvailability_Available;
}
+unsigned clang_getCompletionNumAnnotations(CXCompletionString completion_string)
+{
+ CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
+ return CCStr ? CCStr->getAnnotationCount() : 0;
+}
+
+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);
+}
+
+
/// \brief The CXCodeCompleteResults structure we allocate internally;
/// the client only sees the initial CXCodeCompleteResults structure.
struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
@@ -205,10 +224,10 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
~AllocatedCXCodeCompleteResults();
/// \brief Diagnostics produced while performing code completion.
- llvm::SmallVector<StoredDiagnostic, 8> Diagnostics;
+ SmallVector<StoredDiagnostic, 8> Diagnostics;
/// \brief Diag object
- llvm::IntrusiveRefCntPtr<Diagnostic> Diag;
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diag;
/// \brief Language options used to adjust source locations.
LangOptions LangOpts;
@@ -227,7 +246,7 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
/// \brief Temporary buffers that will be deleted once we have finished with
/// the code-completion results.
- llvm::SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
+ SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
/// \brief Allocator used to store globally cached code-completion results.
llvm::IntrusiveRefCntPtr<clang::GlobalCodeCompletionAllocator>
@@ -242,6 +261,18 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
/// \brief A bitfield representing the acceptable completions for the
/// current context.
unsigned long long Contexts;
+
+ /// \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;
+ /// \brief a boolean value indicating whether there is complete information
+ /// about the container
+ unsigned ContainerIsIncomplete;
+
+ /// \brief A string containing the Objective-C selector entered thus far for a
+ /// message send.
+ std::string Selector;
};
/// \brief Tracks the number of code-completion result objects that are
@@ -253,11 +284,16 @@ static llvm::sys::cas_flag CodeCompletionResultObjects;
AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
const FileSystemOptions& FileSystemOpts)
: CXCodeCompleteResults(),
- Diag(new Diagnostic(
+ Diag(new DiagnosticsEngine(
llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs))),
FileSystemOpts(FileSystemOpts),
FileMgr(new FileManager(FileSystemOpts)),
- SourceMgr(new SourceManager(*Diag, *FileMgr)) {
+ SourceMgr(new SourceManager(*Diag, *FileMgr)),
+ Contexts(CXCompletionContext_Unknown),
+ ContainerKind(CXCursor_InvalidCode),
+ ContainerUSR(createCXString("")),
+ ContainerIsIncomplete(1)
+{
if (getenv("LIBCLANG_OBJTRACKING")) {
llvm::sys::AtomicIncrement(&CodeCompletionResultObjects);
fprintf(stderr, "+++ %d completion results\n", CodeCompletionResultObjects);
@@ -267,6 +303,8 @@ 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)
@@ -420,7 +458,7 @@ static unsigned long long getContextsForContextKind(
contexts = CXCompletionContext_ObjCClassMessage;
break;
}
- case CodeCompletionContext::CCC_ObjCSuperclass: {
+ case CodeCompletionContext::CCC_ObjCInterfaceName: {
contexts = CXCompletionContext_ObjCInterface;
break;
}
@@ -454,11 +492,13 @@ static unsigned long long getContextsForContextKind(
namespace {
class CaptureCompletionResults : public CodeCompleteConsumer {
AllocatedCXCodeCompleteResults &AllocatedResults;
- llvm::SmallVector<CXCompletionResult, 16> StoredResults;
+ SmallVector<CXCompletionResult, 16> StoredResults;
+ CXTranslationUnit *TU;
public:
- CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results)
+ CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results,
+ CXTranslationUnit *TranslationUnit)
: CodeCompleteConsumer(true, false, true, false),
- AllocatedResults(Results) { }
+ AllocatedResults(Results), TU(TranslationUnit) { }
~CaptureCompletionResults() { Finish(); }
virtual void ProcessCodeCompleteResults(Sema &S,
@@ -477,10 +517,77 @@ namespace {
StoredResults.push_back(R);
}
- enum CodeCompletionContext::Kind kind = Context.getKind();
+ enum CodeCompletionContext::Kind contextKind = Context.getKind();
- AllocatedResults.ContextKind = kind;
- AllocatedResults.Contexts = getContextsForContextKind(kind, S);
+ AllocatedResults.ContextKind = contextKind;
+ AllocatedResults.Contexts = getContextsForContextKind(contextKind, S);
+
+ AllocatedResults.Selector = "";
+ if (Context.getNumSelIdents() > 0) {
+ for (unsigned i = 0; i < Context.getNumSelIdents(); i++) {
+ IdentifierInfo *selIdent = Context.getSelIdents()[i];
+ if (selIdent != NULL) {
+ StringRef selectorString = Context.getSelIdents()[i]->getName();
+ AllocatedResults.Selector += selectorString;
+ }
+ AllocatedResults.Selector += ":";
+ }
+ }
+
+ QualType baseType = Context.getBaseType();
+ NamedDecl *D = NULL;
+
+ if (!baseType.isNull()) {
+ // Get the declaration for a class/struct/union/enum type
+ if (const TagType *Tag = baseType->getAs<TagType>())
+ D = Tag->getDecl();
+ // Get the @interface declaration for a (possibly-qualified) Objective-C
+ // object pointer type, e.g., NSString*
+ else if (const ObjCObjectPointerType *ObjPtr =
+ baseType->getAs<ObjCObjectPointerType>())
+ D = ObjPtr->getInterfaceDecl();
+ // Get the @interface declaration for an Objective-C object type
+ else if (const ObjCObjectType *Obj = baseType->getAs<ObjCObjectType>())
+ D = Obj->getInterface();
+ // Get the class for a C++ injected-class-name
+ else if (const InjectedClassNameType *Injected =
+ baseType->getAs<InjectedClassNameType>())
+ D = Injected->getDecl();
+ }
+
+ 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;
+
+ const Type *type = baseType.getTypePtrOrNull();
+ if (type != NULL) {
+ AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
+ }
+ else {
+ AllocatedResults.ContainerIsIncomplete = 1;
+ }
+ }
+ else {
+ AllocatedResults.ContainerKind = CXCursor_InvalidCode;
+ AllocatedResults.ContainerUSR = createCXString("");
+ AllocatedResults.ContainerIsIncomplete = 1;
+ }
}
virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
@@ -551,9 +658,9 @@ void clang_codeCompleteAt_Impl(void *UserData) {
ASTUnit::ConcurrencyCheck Check(*AST);
// Perform the remapping of source files.
- llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
+ SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
for (unsigned I = 0; I != num_unsaved_files; ++I) {
- llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
+ 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,
@@ -571,7 +678,7 @@ void clang_codeCompleteAt_Impl(void *UserData) {
Results->NumResults = 0;
// Create a code-completion consumer to capture the results.
- CaptureCompletionResults Capture(*Results);
+ CaptureCompletionResults Capture(*Results, &TU);
// Perform completion.
AST->CodeComplete(complete_filename, complete_line, complete_column,
@@ -621,7 +728,7 @@ void clang_codeCompleteAt_Impl(void *UserData) {
}
pchName.push_back('\0');
struct stat stat_results;
- if (stat(pchName.data(), &stat_results) == 0)
+ if (stat(pchName.str().c_str(), &stat_results) == 0)
usesPCH = true;
continue;
}
@@ -639,7 +746,7 @@ void clang_codeCompleteAt_Impl(void *UserData) {
os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
os << " }";
- llvm::StringRef res = os.str();
+ StringRef res = os.str();
if (res.size() > 0) {
do {
// Setup the UDP socket.
@@ -731,6 +838,40 @@ clang_codeCompleteGetContexts(CXCodeCompleteResults *ResultsIn) {
return Results->Contexts;
}
+enum CXCursorKind clang_codeCompleteGetContainerKind(
+ CXCodeCompleteResults *ResultsIn,
+ unsigned *IsIncomplete) {
+ AllocatedCXCodeCompleteResults *Results =
+ static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
+ if (!Results)
+ return CXCursor_InvalidCode;
+
+ if (IsIncomplete != NULL) {
+ *IsIncomplete = Results->ContainerIsIncomplete;
+ }
+
+ return Results->ContainerKind;
+}
+
+CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
+ AllocatedCXCodeCompleteResults *Results =
+ static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
+ if (!Results)
+ return createCXString("");
+
+ return createCXString(clang_getCString(Results->ContainerUSR));
+}
+
+
+CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
+ AllocatedCXCodeCompleteResults *Results =
+ static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
+ if (!Results)
+ return createCXString("");
+
+ return createCXString(Results->Selector);
+}
+
} // end extern "C"
/// \brief Simple utility function that appends a \p New string to the given
@@ -744,7 +885,7 @@ clang_codeCompleteGetContexts(CXCodeCompleteResults *ResultsIn) {
///
/// \param Buffer A buffer that stores the actual, concatenated string. It will
/// be used if the old string is already-non-empty.
-static void AppendToString(llvm::StringRef &Old, llvm::StringRef New,
+static void AppendToString(StringRef &Old, StringRef New,
llvm::SmallString<256> &Buffer) {
if (Old.empty()) {
Old = New;
@@ -764,9 +905,9 @@ static void AppendToString(llvm::StringRef &Old, llvm::StringRef New,
/// concatenated.
///
/// \param Buffer A buffer used for storage of the completed name.
-static llvm::StringRef GetTypedName(CodeCompletionString *String,
+static StringRef GetTypedName(CodeCompletionString *String,
llvm::SmallString<256> &Buffer) {
- llvm::StringRef Result;
+ StringRef Result;
for (CodeCompletionString::iterator C = String->begin(), CEnd = String->end();
C != CEnd; ++C) {
if (C->Kind == CodeCompletionString::CK_TypedText)
@@ -786,9 +927,9 @@ namespace {
= (CodeCompletionString *)YR.CompletionString;
llvm::SmallString<256> XBuffer;
- llvm::StringRef XText = GetTypedName(X, XBuffer);
+ StringRef XText = GetTypedName(X, XBuffer);
llvm::SmallString<256> YBuffer;
- llvm::StringRef YText = GetTypedName(Y, YBuffer);
+ StringRef YText = GetTypedName(Y, YBuffer);
if (XText.empty() || YText.empty())
return !XText.empty();
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 0fcdab70bebcc..26f69b06c1957 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -106,7 +106,7 @@ CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
/* Print warning/error/etc. */
switch (Severity) {
- case CXDiagnostic_Ignored: assert(0 && "impossible"); break;
+ case CXDiagnostic_Ignored: llvm_unreachable("impossible");
case CXDiagnostic_Note: Out << "note: "; break;
case CXDiagnostic_Warning: Out << "warning: "; break;
case CXDiagnostic_Error: Out << "error: "; break;
@@ -182,11 +182,11 @@ enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
return CXDiagnostic_Ignored;
switch (StoredDiag->Diag.getLevel()) {
- case Diagnostic::Ignored: return CXDiagnostic_Ignored;
- case Diagnostic::Note: return CXDiagnostic_Note;
- case Diagnostic::Warning: return CXDiagnostic_Warning;
- case Diagnostic::Error: return CXDiagnostic_Error;
- case Diagnostic::Fatal: return CXDiagnostic_Fatal;
+ case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored;
+ case DiagnosticsEngine::Note: return CXDiagnostic_Note;
+ case DiagnosticsEngine::Warning: return CXDiagnostic_Warning;
+ case DiagnosticsEngine::Error: return CXDiagnostic_Error;
+ case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal;
}
llvm_unreachable("Invalid diagnostic level");
@@ -220,11 +220,11 @@ CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
return createCXString("");
unsigned ID = StoredDiag->Diag.getID();
- llvm::StringRef Option = DiagnosticIDs::getWarningOptionForDiag(ID);
+ StringRef Option = DiagnosticIDs::getWarningOptionForDiag(ID);
if (!Option.empty()) {
if (Disable)
- *Disable = createCXString((llvm::Twine("-Wno-") + Option).str());
- return createCXString((llvm::Twine("-W") + Option).str());
+ *Disable = createCXString((Twine("-Wno-") + Option).str());
+ return createCXString((Twine("-W") + Option).str());
}
if (ID == diag::fatal_too_many_errors) {
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
new file mode 100644
index 0000000000000..b5a05eaafc0ba
--- /dev/null
+++ b/tools/libclang/CIndexHigh.cpp
@@ -0,0 +1,315 @@
+//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Index_Internal.h"
+#include "CXCursor.h"
+#include "CXSourceLocation.h"
+#include "CXTranslationUnit.h"
+
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/AST/DeclObjC.h"
+
+using namespace clang;
+
+static void getTopOverriddenMethods(CXTranslationUnit TU,
+ Decl *D,
+ SmallVectorImpl<Decl *> &Methods) {
+ if (!isa<ObjCMethodDecl>(D) && !isa<CXXMethodDecl>(D))
+ return;
+
+ SmallVector<CXCursor, 8> Overridden;
+ cxcursor::getOverriddenCursors(cxcursor::MakeCXCursor(D, TU), Overridden);
+
+ if (Overridden.empty()) {
+ Methods.push_back(D->getCanonicalDecl());
+ return;
+ }
+
+ for (SmallVector<CXCursor, 8>::iterator
+ I = Overridden.begin(), E = Overridden.end(); I != E; ++I)
+ getTopOverriddenMethods(TU, cxcursor::getCursorDecl(*I), Methods);
+}
+
+namespace {
+
+struct FindFileIdRefVisitData {
+ CXTranslationUnit TU;
+ FileID FID;
+ Decl *Dcl;
+ int SelectorIdIdx;
+ CXCursorAndRangeVisitor visitor;
+
+ typedef SmallVector<Decl *, 8> TopMethodsTy;
+ TopMethodsTy TopMethods;
+
+ FindFileIdRefVisitData(CXTranslationUnit TU, FileID FID,
+ Decl *D, int selectorIdIdx,
+ CXCursorAndRangeVisitor visitor)
+ : TU(TU), FID(FID), SelectorIdIdx(selectorIdIdx), visitor(visitor) {
+ Dcl = getCanonical(D);
+ getTopOverriddenMethods(TU, Dcl, TopMethods);
+ }
+
+ ASTContext &getASTContext() const {
+ return static_cast<ASTUnit *>(TU->TUData)->getASTContext();
+ }
+
+ /// \brief We are looking to find all semantically relevant identifiers,
+ /// so the definition of "canonical" here is different than in the AST, e.g.
+ ///
+ /// \code
+ /// class C {
+ /// C() {}
+ /// };
+ /// \endcode
+ ///
+ /// 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 {
+ D = D->getCanonicalDecl();
+
+ if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
+ return getCanonical(ImplD->getClassInterface());
+ if (CXXConstructorDecl *CXXCtorD = dyn_cast<CXXConstructorDecl>(D))
+ return getCanonical(CXXCtorD->getParent());
+
+ return D;
+ }
+
+ bool isHit(Decl *D) const {
+ D = getCanonical(D);
+ if (D == Dcl)
+ return true;
+
+ if (isa<ObjCMethodDecl>(D) || isa<CXXMethodDecl>(D))
+ return isOverriddingMethod(D);
+
+ return false;
+ }
+
+private:
+ bool isOverriddingMethod(Decl *D) const {
+ if (std::find(TopMethods.begin(), TopMethods.end(), D) !=
+ TopMethods.end())
+ return true;
+
+ TopMethodsTy methods;
+ getTopOverriddenMethods(TU, D, methods);
+ for (TopMethodsTy::iterator
+ I = methods.begin(), E = methods.end(); I != E; ++I) {
+ if (std::find(TopMethods.begin(), TopMethods.end(), *I) !=
+ TopMethods.end())
+ return true;
+ }
+
+ return false;
+ }
+};
+
+} // end anonymous namespace.
+
+/// \brief For a macro \arg Loc, returns the file spelling location and sets
+/// to \arg isMacroArg whether the spelling resides inside a macro definition or
+/// a macro argument.
+static SourceLocation getFileSpellingLoc(SourceManager &SM,
+ SourceLocation Loc,
+ bool &isMacroArg) {
+ assert(Loc.isMacroID());
+ SourceLocation SpellLoc = SM.getImmediateSpellingLoc(Loc);
+ if (SpellLoc.isMacroID())
+ return getFileSpellingLoc(SM, SpellLoc, isMacroArg);
+
+ isMacroArg = SM.isMacroArgExpansion(Loc);
+ return SpellLoc;
+}
+
+static enum CXChildVisitResult findFileIdRefVisit(CXCursor cursor,
+ CXCursor parent,
+ CXClientData client_data) {
+ CXCursor declCursor = clang_getCursorReferenced(cursor);
+ if (!clang_isDeclaration(declCursor.kind))
+ return CXChildVisit_Recurse;
+
+ Decl *D = cxcursor::getCursorDecl(declCursor);
+ FindFileIdRefVisitData *data = (FindFileIdRefVisitData *)client_data;
+ if (data->isHit(D)) {
+ cursor = cxcursor::getSelectorIdentifierCursor(data->SelectorIdIdx, cursor);
+
+ // We are looking for identifiers to highlight so for objc methods (and
+ // not a parameter) we can only highlight the selector identifiers.
+ if ((cursor.kind == CXCursor_ObjCClassMethodDecl ||
+ cursor.kind == CXCursor_ObjCInstanceMethodDecl) &&
+ cxcursor::getSelectorIdentifierIndex(cursor) == -1)
+ return CXChildVisit_Recurse;
+
+ if (clang_isExpression(cursor.kind)) {
+ if (cursor.kind == CXCursor_DeclRefExpr ||
+ cursor.kind == CXCursor_MemberRefExpr) {
+ // continue..
+
+ } else if (cursor.kind == CXCursor_ObjCMessageExpr &&
+ cxcursor::getSelectorIdentifierIndex(cursor) != -1) {
+ // continue..
+
+ } else
+ return CXChildVisit_Recurse;
+ }
+
+ SourceLocation
+ Loc = cxloc::translateSourceLocation(clang_getCursorLocation(cursor));
+ SourceLocation SelIdLoc = cxcursor::getSelectorIdentifierLoc(cursor);
+ if (SelIdLoc.isValid())
+ Loc = SelIdLoc;
+
+ SourceManager &SM = data->getASTContext().getSourceManager();
+ bool isInMacroDef = false;
+ if (Loc.isMacroID()) {
+ bool isMacroArg;
+ Loc = getFileSpellingLoc(SM, Loc, isMacroArg);
+ isInMacroDef = !isMacroArg;
+ }
+
+ // We are looking for identifiers in a specific file.
+ std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+ if (LocInfo.first != data->FID)
+ return CXChildVisit_Recurse;
+
+ if (isInMacroDef) {
+ // FIXME: For a macro definition make sure that all expansions
+ // of it expand to the same reference before allowing to point to it.
+ Loc = SourceLocation();
+ }
+
+ data->visitor.visit(data->visitor.context, cursor,
+ cxloc::translateSourceRange(D->getASTContext(), Loc));
+ }
+ return CXChildVisit_Recurse;
+}
+
+static void findIdRefsInFile(CXTranslationUnit TU, CXCursor declCursor,
+ const FileEntry *File,
+ CXCursorAndRangeVisitor Visitor) {
+ assert(clang_isDeclaration(declCursor.kind));
+ ASTUnit *Unit = static_cast<ASTUnit*>(TU->TUData);
+ ASTContext &Ctx = Unit->getASTContext();
+ SourceManager &SM = Unit->getSourceManager();
+
+ FileID FID = SM.translateFile(File);
+ Decl *Dcl = cxcursor::getCursorDecl(declCursor);
+ 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 (FID == SM.getMainFileID() && !Unit->isMainFileAST()) {
+ SourceLocation FileLoc = SM.getLocForStartOfFile(FID);
+ TranslationUnitDecl *TUD = Ctx.getTranslationUnitDecl();
+ CXCursor TUCursor = clang_getTranslationUnitCursor(TU);
+ for (DeclContext::decl_iterator
+ I = TUD->noload_decls_begin(), E = TUD->noload_decls_end();
+ I != E; ++I) {
+ Decl *D = *I;
+
+ SourceRange R = D->getSourceRange();
+ if (R.isInvalid())
+ continue;
+ if (SM.isBeforeInTranslationUnit(R.getEnd(), FileLoc))
+ continue;
+
+ if (TagDecl *TD = dyn_cast<TagDecl>(D))
+ if (!TD->isFreeStanding())
+ continue;
+
+ CXCursor CurCursor = cxcursor::MakeCXCursor(D, TU);
+ findFileIdRefVisit(CurCursor, TUCursor, &data);
+ clang_visitChildren(CurCursor, findFileIdRefVisit, &data);
+ }
+ return;
+ }
+
+ clang_visitChildren(clang_getTranslationUnitCursor(TU),
+ findFileIdRefVisit, &data);
+}
+
+
+//===----------------------------------------------------------------------===//
+// libclang public APIs.
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+
+void clang_findReferencesInFile(CXCursor cursor, CXFile file,
+ CXCursorAndRangeVisitor visitor) {
+ bool Logging = ::getenv("LIBCLANG_LOGGING");
+
+ if (clang_Cursor_isNull(cursor)) {
+ if (Logging)
+ llvm::errs() << "clang_findReferencesInFile: Null cursor\n";
+ return;
+ }
+ if (!file) {
+ if (Logging)
+ llvm::errs() << "clang_findReferencesInFile: Null file\n";
+ return;
+ }
+ if (!visitor.visit) {
+ if (Logging)
+ llvm::errs() << "clang_findReferencesInFile: Null visitor\n";
+ return;
+ }
+
+ // We are interested in semantics of identifiers so for C++ constructor exprs
+ // prefer type references, e.g.:
+ //
+ // return MyStruct();
+ //
+ // for 'MyStruct' we'll have a cursor pointing at the constructor decl but
+ // we are actually interested in the type declaration.
+ cursor = cxcursor::getTypeRefCursor(cursor);
+
+ CXCursor refCursor = clang_getCursorReferenced(cursor);
+
+ if (!clang_isDeclaration(refCursor.kind)) {
+ if (Logging)
+ llvm::errs() << "clang_findReferencesInFile: cursor is not referencing a "
+ "declaration\n";
+ return;
+ }
+
+ ASTUnit *CXXUnit = cxcursor::getCursorASTUnit(cursor);
+ ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+ findIdRefsInFile(cxcursor::getCursorTU(cursor),
+ refCursor,
+ static_cast<const FileEntry *>(file),
+ visitor);
+}
+
+static enum CXVisitorResult _visitCursorAndRange(void *context,
+ CXCursor cursor,
+ CXSourceRange range) {
+ CXCursorAndRangeVisitorBlock block = (CXCursorAndRangeVisitorBlock)context;
+ return INVOKE_BLOCK2(block, cursor, range);
+}
+
+void clang_findReferencesInFileWithBlock(CXCursor cursor,
+ CXFile file,
+ CXCursorAndRangeVisitorBlock block) {
+ CXCursorAndRangeVisitor visitor = { block,
+ block ? _visitCursorAndRange : 0 };
+ return clang_findReferencesInFile(cursor, file, visitor);
+}
+
+} // end: extern "C"
+
diff --git a/tools/libclang/CIndexInclusionStack.cpp b/tools/libclang/CIndexInclusionStack.cpp
index 6bc4f2e776a35..848ca31a5e32b 100644
--- a/tools/libclang/CIndexInclusionStack.cpp
+++ b/tools/libclang/CIndexInclusionStack.cpp
@@ -29,19 +29,22 @@ void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
SourceManager &SM = CXXUnit->getSourceManager();
ASTContext &Ctx = CXXUnit->getASTContext();
- llvm::SmallVector<CXSourceLocation, 10> InclusionStack;
- unsigned i = SM.sloc_loaded_entry_size();
- unsigned n = SM.sloc_entry_size();
+ SmallVector<CXSourceLocation, 10> InclusionStack;
+ unsigned n = SM.local_sloc_entry_size();
// In the case where all the SLocEntries are in an external source, traverse
// those SLocEntries as well. This is the case where we are looking
// at the inclusion stack of an AST/PCH file.
- if (i >= n)
- i = 0;
-
- for ( ; i < n ; ++i) {
+ const SrcMgr::SLocEntry &(SourceManager::*Getter)(unsigned, bool*) const;
+ if (n == 1) {
+ Getter = &SourceManager::getLoadedSLocEntry;
+ n = SM.loaded_sloc_entry_size();
+ } else
+ Getter = &SourceManager::getLocalSLocEntry;
+
+ for (unsigned i = 0 ; i < n ; ++i) {
bool Invalid = false;
- const SrcMgr::SLocEntry &SL = SM.getSLocEntry(i, &Invalid);
+ const SrcMgr::SLocEntry &SL = (SM.*Getter)(i, &Invalid);
if (!SL.isFile() || Invalid)
continue;
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index 4f1f071c1dd20..121d67d1d2e7d 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -31,28 +31,28 @@ using namespace clang::cxstring;
namespace {
class USRGenerator : public DeclVisitor<USRGenerator> {
llvm::OwningPtr<llvm::SmallString<128> > OwnedBuf;
- llvm::SmallVectorImpl<char> &Buf;
+ SmallVectorImpl<char> &Buf;
llvm::raw_svector_ostream Out;
bool IgnoreResults;
- ASTUnit *AU;
+ ASTContext *Context;
bool generatedLoc;
llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
public:
- USRGenerator(const CXCursor *C = 0, llvm::SmallVectorImpl<char> *extBuf = 0)
+ explicit USRGenerator(ASTContext *Ctx = 0, SmallVectorImpl<char> *extBuf = 0)
: OwnedBuf(extBuf ? 0 : new llvm::SmallString<128>()),
Buf(extBuf ? *extBuf : *OwnedBuf.get()),
Out(Buf),
IgnoreResults(false),
- AU(C ? cxcursor::getCursorASTUnit(*C) : 0),
+ Context(Ctx),
generatedLoc(false)
{
// Add the USR space prefix.
Out << "c:";
}
- llvm::StringRef str() {
+ StringRef str() {
return Out.str();
}
@@ -114,19 +114,19 @@ public:
/// itself.
/// Generate a USR for an Objective-C class.
- void GenObjCClass(llvm::StringRef cls);
+ void GenObjCClass(StringRef cls);
/// Generate a USR for an Objective-C class category.
- void GenObjCCategory(llvm::StringRef cls, llvm::StringRef cat);
+ void GenObjCCategory(StringRef cls, StringRef cat);
/// Generate a USR fragment for an Objective-C instance variable. The
/// complete USR can be created by concatenating the USR for the
/// encompassing class with this USR fragment.
- void GenObjCIvar(llvm::StringRef ivar);
+ void GenObjCIvar(StringRef ivar);
/// Generate a USR fragment for an Objective-C method.
- void GenObjCMethod(llvm::StringRef sel, bool isInstanceMethod);
+ void GenObjCMethod(StringRef sel, bool isInstanceMethod);
/// Generate a USR fragment for an Objective-C property.
- void GenObjCProperty(llvm::StringRef prop);
+ void GenObjCProperty(StringRef prop);
/// Generate a USR for an Objective-C protocol.
- void GenObjCProtocol(llvm::StringRef prot);
+ void GenObjCProtocol(StringRef prot);
void VisitType(QualType T);
void VisitTemplateParameterList(const TemplateParameterList *Params);
@@ -190,7 +190,7 @@ void USRGenerator::VisitFunctionDecl(FunctionDecl *D) {
Out << "@F@";
D->printName(Out);
- ASTContext &Ctx = AU->getASTContext();
+ ASTContext &Ctx = *Context;
if (!Ctx.getLangOptions().CPlusPlus || D->isExternC())
return;
@@ -235,7 +235,7 @@ void USRGenerator::VisitVarDecl(VarDecl *D) {
VisitDeclContext(D->getDeclContext());
// Variables always have simple names.
- llvm::StringRef s = D->getName();
+ StringRef s = D->getName();
// The string can be empty if the declaration has no name; e.g., it is
// the ParmDecl with no name for declaration of a function pointer type, e.g.:
@@ -320,7 +320,7 @@ void USRGenerator::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) {
switch (D->getKind()) {
default:
- assert(false && "Invalid ObjC container.");
+ llvm_unreachable("Invalid ObjC container.");
case Decl::ObjCInterface:
case Decl::ObjCImplementation:
GenObjCClass(D->getName());
@@ -433,7 +433,7 @@ void USRGenerator::VisitTagDecl(TagDecl *D) {
if (EmitDeclName(D)) {
if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
Buf[off] = 'A';
- Out << '@' << TD;
+ Out << '@' << *TD;
}
else
Buf[off] = 'a';
@@ -480,13 +480,13 @@ bool USRGenerator::GenLoc(const Decl *D) {
// Use the location of canonical decl.
D = D->getCanonicalDecl();
- const SourceManager &SM = AU->getSourceManager();
+ const SourceManager &SM = Context->getSourceManager();
SourceLocation L = D->getLocStart();
if (L.isInvalid()) {
IgnoreResults = true;
return true;
}
- L = SM.getInstantiationLoc(L);
+ L = SM.getExpansionLoc(L);
const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
if (FE) {
@@ -508,7 +508,7 @@ void USRGenerator::VisitType(QualType T) {
// This method mangles in USR information for types. It can possibly
// just reuse the naming-mangling logic used by codegen, although the
// requirements for USRs might not be the same.
- ASTContext &Ctx = AU->getASTContext();
+ ASTContext &Ctx = *Context;
do {
T = Ctx.getCanonicalType(T);
@@ -570,6 +570,8 @@ void USRGenerator::VisitType(QualType T) {
c = 'K'; break;
case BuiltinType::Int128:
c = 'J'; break;
+ case BuiltinType::Half:
+ c = 'h'; break;
case BuiltinType::Float:
c = 'f'; break;
case BuiltinType::Double:
@@ -755,27 +757,27 @@ void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
// General purpose USR generation methods.
//===----------------------------------------------------------------------===//
-void USRGenerator::GenObjCClass(llvm::StringRef cls) {
+void USRGenerator::GenObjCClass(StringRef cls) {
Out << "objc(cs)" << cls;
}
-void USRGenerator::GenObjCCategory(llvm::StringRef cls, llvm::StringRef cat) {
+void USRGenerator::GenObjCCategory(StringRef cls, StringRef cat) {
Out << "objc(cy)" << cls << '@' << cat;
}
-void USRGenerator::GenObjCIvar(llvm::StringRef ivar) {
+void USRGenerator::GenObjCIvar(StringRef ivar) {
Out << '@' << ivar;
}
-void USRGenerator::GenObjCMethod(llvm::StringRef meth, bool isInstanceMethod) {
+void USRGenerator::GenObjCMethod(StringRef meth, bool isInstanceMethod) {
Out << (isInstanceMethod ? "(im)" : "(cm)") << meth;
}
-void USRGenerator::GenObjCProperty(llvm::StringRef prop) {
+void USRGenerator::GenObjCProperty(StringRef prop) {
Out << "(py)" << prop;
}
-void USRGenerator::GenObjCProtocol(llvm::StringRef prot) {
+void USRGenerator::GenObjCProtocol(StringRef prot) {
Out << "objc(pl)" << prot;
}
@@ -783,16 +785,14 @@ void USRGenerator::GenObjCProtocol(llvm::StringRef prot) {
// API hooks.
//===----------------------------------------------------------------------===//
-static inline llvm::StringRef extractUSRSuffix(llvm::StringRef s) {
+static inline StringRef extractUSRSuffix(StringRef s) {
return s.startswith("c:") ? s.substr(2) : "";
}
-static CXString getDeclCursorUSR(const CXCursor &C) {
- Decl *D = cxcursor::getCursorDecl(C);
-
+bool cxcursor::getDeclCursorUSR(Decl *D, SmallVectorImpl<char> &Buf) {
// Don't generate USRs for things with invalid locations.
if (!D || D->getLocStart().isInvalid())
- return createCXString("");
+ return true;
// Check if the cursor has 'NoLinkage'.
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
@@ -817,27 +817,15 @@ static CXString getDeclCursorUSR(const CXCursor &C) {
break;
}
- CXTranslationUnit TU = cxcursor::getCursorTU(C);
- if (!TU)
- return createCXString("");
-
- CXStringBuf *buf = cxstring::getCXStringBuf(TU);
- if (!buf)
- return createCXString("");
-
{
- USRGenerator UG(&C, &buf->Data);
+ USRGenerator UG(&D->getASTContext(), &Buf);
UG->Visit(D);
- if (UG->ignoreResults()) {
- disposeCXStringBuf(buf);
- return createCXString("");
- }
+ if (UG->ignoreResults())
+ return true;
}
- // Return the C-string, but don't make a copy since it is already in
- // the string buffer.
- buf->Data.push_back('\0');
- return createCXString(buf);
+
+ return false;
}
extern "C" {
@@ -845,8 +833,27 @@ extern "C" {
CXString clang_getCursorUSR(CXCursor C) {
const CXCursorKind &K = clang_getCursorKind(C);
- if (clang_isDeclaration(K))
- return getDeclCursorUSR(C);
+ if (clang_isDeclaration(K)) {
+ Decl *D = cxcursor::getCursorDecl(C);
+ CXTranslationUnit TU = cxcursor::getCursorTU(C);
+ if (!TU)
+ return createCXString("");
+
+ CXStringBuf *buf = cxstring::getCXStringBuf(TU);
+ if (!buf)
+ return createCXString("");
+
+ bool Ignore = cxcursor::getDeclCursorUSR(D, buf->Data);
+ if (Ignore) {
+ disposeCXStringBuf(buf);
+ return createCXString("");
+ }
+
+ // Return the C-string, but don't make a copy since it is already in
+ // the string buffer.
+ buf->Data.push_back('\0');
+ return createCXString(buf);
+ }
if (K == CXCursor_MacroDefinition) {
CXTranslationUnit TU = cxcursor::getCursorTU(C);
@@ -858,7 +865,8 @@ CXString clang_getCursorUSR(CXCursor C) {
return createCXString("");
{
- USRGenerator UG(&C, &buf->Data);
+ USRGenerator UG(&cxcursor::getCursorASTUnit(C)->getASTContext(),
+ &buf->Data);
UG << "macro@"
<< cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
}
diff --git a/tools/libclang/CIndexer.cpp b/tools/libclang/CIndexer.cpp
index 56974b9e999bb..995a8febb0886 100644
--- a/tools/libclang/CIndexer.cpp
+++ b/tools/libclang/CIndexer.cpp
@@ -74,7 +74,7 @@ std::string CIndexer::getClangResourcesPath() {
// This silly cast below avoids a C++ warning.
Dl_info info;
if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
- assert(0 && "Call to dladdr() failed");
+ llvm_unreachable("Call to dladdr() failed");
llvm::sys::Path LibClangPath(info.dli_fname);
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index f45389f0b9f4d..f754e980b93f4 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -21,6 +21,7 @@ set(SOURCES
CIndexCXX.cpp
CIndexCodeCompletion.cpp
CIndexDiagnostic.cpp
+ CIndexHigh.cpp
CIndexInclusionStack.cpp
CIndexUSRs.cpp
CIndexer.cpp
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index b3c57dc9344f7..db27500143515 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -20,8 +20,10 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
#include "clang-c/Index.h"
#include "llvm/Support/ErrorHandling.h"
@@ -30,7 +32,7 @@ using namespace cxcursor;
CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K) {
assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
- CXCursor C = { K, { 0, 0, 0 } };
+ CXCursor C = { K, 0, { 0, 0, 0 } };
return C;
}
@@ -41,6 +43,9 @@ static CXCursorKind GetCursorKind(const Attr *A) {
case attr::IBAction: return CXCursor_IBActionAttr;
case attr::IBOutlet: return CXCursor_IBOutletAttr;
case attr::IBOutletCollection: return CXCursor_IBOutletCollectionAttr;
+ case attr::Final: return CXCursor_CXXFinalAttr;
+ case attr::Override: return CXCursor_CXXOverrideAttr;
+ case attr::Annotate: return CXCursor_AnnotateAttr;
}
return CXCursor_UnexposedAttr;
@@ -49,152 +54,369 @@ static CXCursorKind GetCursorKind(const Attr *A) {
CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent,
CXTranslationUnit TU) {
assert(A && Parent && TU && "Invalid arguments!");
- CXCursor C = { GetCursorKind(A), { Parent, (void*)A, TU } };
+ CXCursor C = { GetCursorKind(A), 0, { Parent, (void*)A, TU } };
return C;
}
CXCursor cxcursor::MakeCXCursor(Decl *D, CXTranslationUnit TU,
+ SourceRange RegionOfInterest,
bool FirstInDeclGroup) {
assert(D && TU && "Invalid arguments!");
- CXCursor C = { getCursorKindForDecl(D),
- { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }
- };
+
+ CXCursorKind K = getCursorKindForDecl(D);
+
+ if (K == CXCursor_ObjCClassMethodDecl ||
+ K == CXCursor_ObjCInstanceMethodDecl) {
+ int SelectorIdIndex = -1;
+ // Check if cursor points to a selector id.
+ if (RegionOfInterest.isValid() &&
+ RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
+ SmallVector<SourceLocation, 16> SelLocs;
+ cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
+ SmallVector<SourceLocation, 16>::iterator
+ I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
+ if (I != SelLocs.end())
+ SelectorIdIndex = I - SelLocs.begin();
+ }
+ CXCursor C = { K, SelectorIdIndex,
+ { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
+ return C;
+ }
+
+ CXCursor C = { K, 0, { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
return C;
}
-CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
- CXTranslationUnit TU) {
+CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, CXTranslationUnit TU,
+ SourceRange RegionOfInterest) {
assert(S && TU && "Invalid arguments!");
CXCursorKind K = CXCursor_NotImplemented;
switch (S->getStmtClass()) {
case Stmt::NoStmtClass:
break;
-
- case Stmt::NullStmtClass:
- case Stmt::CompoundStmtClass:
+
case Stmt::CaseStmtClass:
+ K = CXCursor_CaseStmt;
+ break;
+
case Stmt::DefaultStmtClass:
- case Stmt::IfStmtClass:
- case Stmt::SwitchStmtClass:
- case Stmt::WhileStmtClass:
- case Stmt::DoStmtClass:
- case Stmt::ForStmtClass:
- case Stmt::GotoStmtClass:
+ K = CXCursor_DefaultStmt;
+ break;
+
+ case Stmt::IfStmtClass:
+ K = CXCursor_IfStmt;
+ break;
+
+ case Stmt::SwitchStmtClass:
+ K = CXCursor_SwitchStmt;
+ break;
+
+ case Stmt::WhileStmtClass:
+ K = CXCursor_WhileStmt;
+ break;
+
+ case Stmt::DoStmtClass:
+ K = CXCursor_DoStmt;
+ break;
+
+ case Stmt::ForStmtClass:
+ K = CXCursor_ForStmt;
+ break;
+
+ case Stmt::GotoStmtClass:
+ K = CXCursor_GotoStmt;
+ break;
+
case Stmt::IndirectGotoStmtClass:
- case Stmt::ContinueStmtClass:
- case Stmt::BreakStmtClass:
- case Stmt::ReturnStmtClass:
- case Stmt::DeclStmtClass:
- case Stmt::AsmStmtClass:
- case Stmt::ObjCAtTryStmtClass:
- case Stmt::ObjCAtCatchStmtClass:
- case Stmt::ObjCAtFinallyStmtClass:
- case Stmt::ObjCAtThrowStmtClass:
- case Stmt::ObjCAtSynchronizedStmtClass:
- case Stmt::ObjCAutoreleasePoolStmtClass:
+ K = CXCursor_IndirectGotoStmt;
+ break;
+
+ case Stmt::ContinueStmtClass:
+ K = CXCursor_ContinueStmt;
+ break;
+
+ case Stmt::BreakStmtClass:
+ K = CXCursor_BreakStmt;
+ break;
+
+ case Stmt::ReturnStmtClass:
+ K = CXCursor_ReturnStmt;
+ break;
+
+ case Stmt::AsmStmtClass:
+ K = CXCursor_AsmStmt;
+ break;
+
+ case Stmt::ObjCAtTryStmtClass:
+ K = CXCursor_ObjCAtTryStmt;
+ break;
+
+ case Stmt::ObjCAtCatchStmtClass:
+ K = CXCursor_ObjCAtCatchStmt;
+ break;
+
+ case Stmt::ObjCAtFinallyStmtClass:
+ K = CXCursor_ObjCAtFinallyStmt;
+ break;
+
+ case Stmt::ObjCAtThrowStmtClass:
+ K = CXCursor_ObjCAtThrowStmt;
+ break;
+
+ case Stmt::ObjCAtSynchronizedStmtClass:
+ K = CXCursor_ObjCAtSynchronizedStmt;
+ break;
+
+ case Stmt::ObjCAutoreleasePoolStmtClass:
+ K = CXCursor_ObjCAutoreleasePoolStmt;
+ break;
+
case Stmt::ObjCForCollectionStmtClass:
+ K = CXCursor_ObjCForCollectionStmt;
+ break;
+
case Stmt::CXXCatchStmtClass:
- case Stmt::CXXTryStmtClass:
- case Stmt::CXXForRangeStmtClass:
+ K = CXCursor_CXXCatchStmt;
+ break;
+
+ case Stmt::CXXTryStmtClass:
+ K = CXCursor_CXXTryStmt;
+ break;
+
+ case Stmt::CXXForRangeStmtClass:
+ K = CXCursor_CXXForRangeStmt;
+ break;
+
case Stmt::SEHTryStmtClass:
+ K = CXCursor_SEHTryStmt;
+ break;
+
case Stmt::SEHExceptStmtClass:
+ K = CXCursor_SEHExceptStmt;
+ break;
+
case Stmt::SEHFinallyStmtClass:
+ K = CXCursor_SEHFinallyStmt;
+ break;
+
+ case Stmt::ArrayTypeTraitExprClass:
+ case Stmt::AsTypeExprClass:
+ case Stmt::AtomicExprClass:
+ case Stmt::BinaryConditionalOperatorClass:
+ case Stmt::BinaryTypeTraitExprClass:
+ case Stmt::CXXBindTemporaryExprClass:
+ case Stmt::CXXDefaultArgExprClass:
+ case Stmt::CXXScalarValueInitExprClass:
+ case Stmt::CXXUuidofExprClass:
+ case Stmt::ChooseExprClass:
+ case Stmt::DesignatedInitExprClass:
+ case Stmt::ExprWithCleanupsClass:
+ case Stmt::ExpressionTraitExprClass:
+ case Stmt::ExtVectorElementExprClass:
+ case Stmt::ImplicitCastExprClass:
+ case Stmt::ImplicitValueInitExprClass:
case Stmt::MaterializeTemporaryExprClass:
- K = CXCursor_UnexposedStmt;
+ case Stmt::ObjCIndirectCopyRestoreExprClass:
+ case Stmt::OffsetOfExprClass:
+ case Stmt::OpaqueValueExprClass:
+ case Stmt::ParenListExprClass:
+ case Stmt::PredefinedExprClass:
+ case Stmt::ShuffleVectorExprClass:
+ case Stmt::UnaryExprOrTypeTraitExprClass:
+ case Stmt::UnaryTypeTraitExprClass:
+ case Stmt::VAArgExprClass:
+ K = CXCursor_UnexposedExpr;
+ break;
+
+ case Stmt::CompoundStmtClass:
+ K = CXCursor_CompoundStmt;
break;
- case Stmt::LabelStmtClass:
- K = CXCursor_LabelStmt;
+ case Stmt::NullStmtClass:
+ K = CXCursor_NullStmt;
break;
- case Stmt::PredefinedExprClass:
- case Stmt::IntegerLiteralClass:
- case Stmt::FloatingLiteralClass:
- case Stmt::ImaginaryLiteralClass:
- case Stmt::StringLiteralClass:
- case Stmt::CharacterLiteralClass:
- case Stmt::ParenExprClass:
+ case Stmt::LabelStmtClass:
+ K = CXCursor_LabelStmt;
+ break;
+
+ case Stmt::DeclStmtClass:
+ K = CXCursor_DeclStmt;
+ break;
+
+ case Stmt::IntegerLiteralClass:
+ K = CXCursor_IntegerLiteral;
+ break;
+
+ case Stmt::FloatingLiteralClass:
+ K = CXCursor_FloatingLiteral;
+ break;
+
+ case Stmt::ImaginaryLiteralClass:
+ K = CXCursor_ImaginaryLiteral;
+ break;
+
+ case Stmt::StringLiteralClass:
+ K = CXCursor_StringLiteral;
+ break;
+
+ case Stmt::CharacterLiteralClass:
+ K = CXCursor_CharacterLiteral;
+ break;
+
+ case Stmt::ParenExprClass:
+ K = CXCursor_ParenExpr;
+ break;
+
case Stmt::UnaryOperatorClass:
- case Stmt::OffsetOfExprClass:
- case Stmt::UnaryExprOrTypeTraitExprClass:
- case Stmt::ArraySubscriptExprClass:
- case Stmt::BinaryOperatorClass:
+ K = CXCursor_UnaryOperator;
+ break;
+
+ case Stmt::CXXNoexceptExprClass:
+ K = CXCursor_UnaryExpr;
+ break;
+
+ case Stmt::ArraySubscriptExprClass:
+ K = CXCursor_ArraySubscriptExpr;
+ break;
+
+ case Stmt::BinaryOperatorClass:
+ K = CXCursor_BinaryOperator;
+ break;
+
case Stmt::CompoundAssignOperatorClass:
- case Stmt::ConditionalOperatorClass:
- case Stmt::BinaryConditionalOperatorClass:
- case Stmt::ImplicitCastExprClass:
+ K = CXCursor_CompoundAssignOperator;
+ break;
+
+ case Stmt::ConditionalOperatorClass:
+ K = CXCursor_ConditionalOperator;
+ break;
+
case Stmt::CStyleCastExprClass:
- case Stmt::CompoundLiteralExprClass:
- case Stmt::ExtVectorElementExprClass:
- case Stmt::InitListExprClass:
- case Stmt::DesignatedInitExprClass:
- case Stmt::ImplicitValueInitExprClass:
- case Stmt::ParenListExprClass:
- case Stmt::VAArgExprClass:
- case Stmt::AddrLabelExprClass:
- case Stmt::StmtExprClass:
- case Stmt::ChooseExprClass:
+ K = CXCursor_CStyleCastExpr;
+ break;
+
+ case Stmt::CompoundLiteralExprClass:
+ K = CXCursor_CompoundLiteralExpr;
+ break;
+
+ case Stmt::InitListExprClass:
+ K = CXCursor_InitListExpr;
+ break;
+
+ case Stmt::AddrLabelExprClass:
+ K = CXCursor_AddrLabelExpr;
+ break;
+
+ case Stmt::StmtExprClass:
+ K = CXCursor_StmtExpr;
+ break;
+
case Stmt::GenericSelectionExprClass:
- case Stmt::GNUNullExprClass:
- case Stmt::CXXStaticCastExprClass:
- case Stmt::CXXDynamicCastExprClass:
- case Stmt::CXXReinterpretCastExprClass:
- case Stmt::CXXConstCastExprClass:
+ K = CXCursor_GenericSelectionExpr;
+ break;
+
+ case Stmt::GNUNullExprClass:
+ K = CXCursor_GNUNullExpr;
+ break;
+
+ case Stmt::CXXStaticCastExprClass:
+ K = CXCursor_CXXStaticCastExpr;
+ break;
+
+ case Stmt::CXXDynamicCastExprClass:
+ K = CXCursor_CXXDynamicCastExpr;
+ break;
+
+ case Stmt::CXXReinterpretCastExprClass:
+ K = CXCursor_CXXReinterpretCastExpr;
+ break;
+
+ case Stmt::CXXConstCastExprClass:
+ K = CXCursor_CXXConstCastExpr;
+ break;
+
case Stmt::CXXFunctionalCastExprClass:
- case Stmt::CXXTypeidExprClass:
- case Stmt::CXXUuidofExprClass:
- case Stmt::CXXBoolLiteralExprClass:
- case Stmt::CXXNullPtrLiteralExprClass:
- case Stmt::CXXThisExprClass:
- case Stmt::CXXThrowExprClass:
- case Stmt::CXXDefaultArgExprClass:
- case Stmt::CXXScalarValueInitExprClass:
- case Stmt::CXXNewExprClass:
- case Stmt::CXXDeleteExprClass:
- case Stmt::CXXPseudoDestructorExprClass:
- case Stmt::UnresolvedLookupExprClass:
- case Stmt::UnaryTypeTraitExprClass:
- case Stmt::BinaryTypeTraitExprClass:
- case Stmt::ArrayTypeTraitExprClass:
- case Stmt::ExpressionTraitExprClass:
- case Stmt::DependentScopeDeclRefExprClass:
- case Stmt::CXXBindTemporaryExprClass:
- case Stmt::ExprWithCleanupsClass:
- case Stmt::CXXUnresolvedConstructExprClass:
- case Stmt::CXXDependentScopeMemberExprClass:
- case Stmt::UnresolvedMemberExprClass:
- case Stmt::CXXNoexceptExprClass:
- case Stmt::ObjCStringLiteralClass:
- case Stmt::ObjCEncodeExprClass:
- case Stmt::ObjCSelectorExprClass:
- case Stmt::ObjCProtocolExprClass:
- case Stmt::ObjCIsaExprClass:
- case Stmt::ObjCIndirectCopyRestoreExprClass:
+ K = CXCursor_CXXFunctionalCastExpr;
+ break;
+
+ case Stmt::CXXTypeidExprClass:
+ K = CXCursor_CXXTypeidExpr;
+ break;
+
+ case Stmt::CXXBoolLiteralExprClass:
+ K = CXCursor_CXXBoolLiteralExpr;
+ break;
+
+ case Stmt::CXXNullPtrLiteralExprClass:
+ K = CXCursor_CXXNullPtrLiteralExpr;
+ break;
+
+ case Stmt::CXXThisExprClass:
+ K = CXCursor_CXXThisExpr;
+ break;
+
+ case Stmt::CXXThrowExprClass:
+ K = CXCursor_CXXThrowExpr;
+ break;
+
+ case Stmt::CXXNewExprClass:
+ K = CXCursor_CXXNewExpr;
+ break;
+
+ case Stmt::CXXDeleteExprClass:
+ K = CXCursor_CXXDeleteExpr;
+ break;
+
+ case Stmt::ObjCStringLiteralClass:
+ K = CXCursor_ObjCStringLiteral;
+ break;
+
+ case Stmt::ObjCEncodeExprClass:
+ K = CXCursor_ObjCEncodeExpr;
+ break;
+
+ case Stmt::ObjCSelectorExprClass:
+ K = CXCursor_ObjCSelectorExpr;
+ break;
+
+ case Stmt::ObjCProtocolExprClass:
+ K = CXCursor_ObjCProtocolExpr;
+ break;
+
case Stmt::ObjCBridgedCastExprClass:
- case Stmt::ShuffleVectorExprClass:
- case Stmt::BlockExprClass:
- case Stmt::OpaqueValueExprClass:
+ K = CXCursor_ObjCBridgedCastExpr;
+ break;
+
+ case Stmt::BlockExprClass:
+ K = CXCursor_BlockExpr;
+ break;
+
case Stmt::PackExpansionExprClass:
+ K = CXCursor_PackExpansionExpr;
+ break;
+
case Stmt::SizeOfPackExprClass:
- case Stmt::AsTypeExprClass:
- K = CXCursor_UnexposedExpr;
+ K = CXCursor_SizeOfPackExpr;
break;
-
- case Stmt::DeclRefExprClass:
+
case Stmt::BlockDeclRefExprClass:
+ case Stmt::DeclRefExprClass:
+ case Stmt::DependentScopeDeclRefExprClass:
case Stmt::SubstNonTypeTemplateParmExprClass:
case Stmt::SubstNonTypeTemplateParmPackExprClass:
- // FIXME: UnresolvedLookupExpr?
- // FIXME: DependentScopeDeclRefExpr?
+ case Stmt::UnresolvedLookupExprClass:
K = CXCursor_DeclRefExpr;
break;
+ case Stmt::CXXDependentScopeMemberExprClass:
+ case Stmt::CXXPseudoDestructorExprClass:
case Stmt::MemberExprClass:
+ case Stmt::ObjCIsaExprClass:
case Stmt::ObjCIvarRefExprClass:
case Stmt::ObjCPropertyRefExprClass:
- // FIXME: UnresolvedMemberExpr?
- // FIXME: CXXDependentScopeMemberExpr?
+ case Stmt::UnresolvedMemberExprClass:
K = CXCursor_MemberRefExpr;
break;
@@ -204,16 +426,28 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
case Stmt::CUDAKernelCallExprClass:
case Stmt::CXXConstructExprClass:
case Stmt::CXXTemporaryObjectExprClass:
- // FIXME: CXXUnresolvedConstructExpr
+ case Stmt::CXXUnresolvedConstructExprClass:
K = CXCursor_CallExpr;
break;
case Stmt::ObjCMessageExprClass:
K = CXCursor_ObjCMessageExpr;
- break;
+ int SelectorIdIndex = -1;
+ // Check if cursor points to a selector id.
+ if (RegionOfInterest.isValid() &&
+ RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
+ SmallVector<SourceLocation, 16> SelLocs;
+ cast<ObjCMessageExpr>(S)->getSelectorLocs(SelLocs);
+ SmallVector<SourceLocation, 16>::iterator
+ I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
+ if (I != SelLocs.end())
+ SelectorIdIndex = I - SelLocs.begin();
+ }
+ CXCursor C = { K, 0, { Parent, S, TU } };
+ return getSelectorIdentifierCursor(SelectorIdIndex, C);
}
- CXCursor C = { K, { Parent, S, TU } };
+ CXCursor C = { K, 0, { Parent, S, TU } };
return C;
}
@@ -222,7 +456,7 @@ CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
CXTranslationUnit TU) {
assert(Super && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_ObjCSuperClassRef, { Super, RawLoc, TU } };
+ CXCursor C = { CXCursor_ObjCSuperClassRef, 0, { Super, RawLoc, TU } };
return C;
}
@@ -239,7 +473,7 @@ CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super,
CXTranslationUnit TU) {
assert(Super && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_ObjCProtocolRef, { Super, RawLoc, TU } };
+ CXCursor C = { CXCursor_ObjCProtocolRef, 0, { Super, RawLoc, TU } };
return C;
}
@@ -259,7 +493,7 @@ CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class,
return MakeCXCursorInvalid(CXCursor_InvalidCode);
assert(TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, TU } };
+ CXCursor C = { CXCursor_ObjCClassRef, 0, { Class, RawLoc, TU } };
return C;
}
@@ -275,7 +509,7 @@ CXCursor cxcursor::MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc,
CXTranslationUnit TU) {
assert(Type && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_TypeRef, { Type, RawLoc, TU } };
+ CXCursor C = { CXCursor_TypeRef, 0, { Type, RawLoc, TU } };
return C;
}
@@ -292,7 +526,7 @@ CXCursor cxcursor::MakeCursorTemplateRef(TemplateDecl *Template,
CXTranslationUnit TU) {
assert(Template && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_TemplateRef, { Template, RawLoc, TU } };
+ CXCursor C = { CXCursor_TemplateRef, 0, { Template, RawLoc, TU } };
return C;
}
@@ -310,7 +544,7 @@ CXCursor cxcursor::MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc,
assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
"Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_NamespaceRef, { NS, RawLoc, TU } };
+ CXCursor C = { CXCursor_NamespaceRef, 0, { NS, RawLoc, TU } };
return C;
}
@@ -327,7 +561,7 @@ CXCursor cxcursor::MakeCursorMemberRef(FieldDecl *Field, SourceLocation Loc,
assert(Field && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_MemberRef, { Field, RawLoc, TU } };
+ CXCursor C = { CXCursor_MemberRef, 0, { Field, RawLoc, TU } };
return C;
}
@@ -341,7 +575,7 @@ cxcursor::getCursorMemberRef(CXCursor C) {
CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B,
CXTranslationUnit TU){
- CXCursor C = { CXCursor_CXXBaseSpecifier, { B, 0, TU } };
+ CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { B, 0, TU } };
return C;
}
@@ -352,7 +586,7 @@ CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
CXTranslationUnit TU) {
- CXCursor C = { CXCursor_PreprocessingDirective,
+ CXCursor C = { CXCursor_PreprocessingDirective, 0,
{ reinterpret_cast<void *>(Range.getBegin().getRawEncoding()),
reinterpret_cast<void *>(Range.getEnd().getRawEncoding()),
TU }
@@ -362,15 +596,17 @@ CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
assert(C.kind == CXCursor_PreprocessingDirective);
- return SourceRange(SourceLocation::getFromRawEncoding(
+ SourceRange Range = SourceRange(SourceLocation::getFromRawEncoding(
reinterpret_cast<uintptr_t> (C.data[0])),
SourceLocation::getFromRawEncoding(
reinterpret_cast<uintptr_t> (C.data[1])));
+ ASTUnit *TU = getCursorASTUnit(C);
+ return TU->mapRangeFromPreamble(Range);
}
CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI,
CXTranslationUnit TU) {
- CXCursor C = { CXCursor_MacroDefinition, { MI, 0, TU } };
+ CXCursor C = { CXCursor_MacroDefinition, 0, { MI, 0, TU } };
return C;
}
@@ -381,7 +617,7 @@ MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
CXTranslationUnit TU) {
- CXCursor C = { CXCursor_MacroExpansion, { MI, 0, TU } };
+ CXCursor C = { CXCursor_MacroExpansion, 0, { MI, 0, TU } };
return C;
}
@@ -392,7 +628,7 @@ MacroExpansion *cxcursor::getCursorMacroExpansion(CXCursor C) {
CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
CXTranslationUnit TU) {
- CXCursor C = { CXCursor_InclusionDirective, { ID, 0, TU } };
+ CXCursor C = { CXCursor_InclusionDirective, 0, { ID, 0, TU } };
return C;
}
@@ -406,7 +642,7 @@ CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
assert(Label && TU && "Invalid arguments!");
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
- CXCursor C = { CXCursor_LabelRef, { Label, RawLoc, TU } };
+ CXCursor C = { CXCursor_LabelRef, 0, { Label, RawLoc, TU } };
return C;
}
@@ -424,7 +660,7 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(OverloadExpr *E,
OverloadedDeclRefStorage Storage(E);
void *RawLoc = reinterpret_cast<void *>(E->getNameLoc().getRawEncoding());
CXCursor C = {
- CXCursor_OverloadedDeclRef,
+ CXCursor_OverloadedDeclRef, 0,
{ Storage.getOpaqueValue(), RawLoc, TU }
};
return C;
@@ -437,7 +673,7 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(Decl *D,
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
OverloadedDeclRefStorage Storage(D);
CXCursor C = {
- CXCursor_OverloadedDeclRef,
+ CXCursor_OverloadedDeclRef, 0,
{ Storage.getOpaqueValue(), RawLoc, TU }
};
return C;
@@ -450,7 +686,7 @@ CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
CXCursor C = {
- CXCursor_OverloadedDeclRef,
+ CXCursor_OverloadedDeclRef, 0,
{ Storage.getOpaqueValue(), RawLoc, TU }
};
return C;
@@ -502,6 +738,173 @@ CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
return static_cast<CXTranslationUnit>(Cursor.data[2]);
}
+static void CollectOverriddenMethods(CXTranslationUnit TU,
+ DeclContext *Ctx,
+ ObjCMethodDecl *Method,
+ SmallVectorImpl<CXCursor> &Methods) {
+ if (!Ctx)
+ return;
+
+ // If we have a class or category implementation, jump straight to the
+ // interface.
+ if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
+ return CollectOverriddenMethods(TU, Impl->getClassInterface(),
+ Method, Methods);
+
+ ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
+ if (!Container)
+ return;
+
+ // Check whether we have a matching method at this level.
+ if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
+ Method->isInstanceMethod()))
+ if (Method != Overridden) {
+ // We found an override at this level; there is no need to look
+ // into other protocols or categories.
+ Methods.push_back(MakeCXCursor(Overridden, TU));
+ return;
+ }
+
+ if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
+ for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
+ PEnd = Protocol->protocol_end();
+ P != PEnd; ++P)
+ CollectOverriddenMethods(TU, *P, Method, Methods);
+ }
+
+ if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
+ for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
+ PEnd = Category->protocol_end();
+ P != PEnd; ++P)
+ CollectOverriddenMethods(TU, *P, Method, Methods);
+ }
+
+ if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
+ for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
+ PEnd = Interface->protocol_end();
+ P != PEnd; ++P)
+ CollectOverriddenMethods(TU, *P, Method, Methods);
+
+ for (ObjCCategoryDecl *Category = Interface->getCategoryList();
+ Category; Category = Category->getNextClassCategory())
+ CollectOverriddenMethods(TU, Category, Method, Methods);
+
+ // We only look into the superclass if we haven't found anything yet.
+ if (Methods.empty())
+ if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
+ return CollectOverriddenMethods(TU, Super, Method, Methods);
+ }
+}
+
+void cxcursor::getOverriddenCursors(CXCursor cursor,
+ SmallVectorImpl<CXCursor> &overridden) {
+ if (!clang_isDeclaration(cursor.kind))
+ return;
+
+ Decl *D = getCursorDecl(cursor);
+ if (!D)
+ return;
+
+ // Handle C++ member functions.
+ CXTranslationUnit TU = getCursorTU(cursor);
+ if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
+ for (CXXMethodDecl::method_iterator
+ M = CXXMethod->begin_overridden_methods(),
+ MEnd = CXXMethod->end_overridden_methods();
+ M != MEnd; ++M)
+ overridden.push_back(MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU));
+ return;
+ }
+
+ ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
+ if (!Method)
+ return;
+
+ // Handle Objective-C methods.
+ CollectOverriddenMethods(TU, Method->getDeclContext(), Method, overridden);
+}
+
+std::pair<int, SourceLocation>
+cxcursor::getSelectorIdentifierIndexAndLoc(CXCursor cursor) {
+ if (cursor.kind == CXCursor_ObjCMessageExpr) {
+ if (cursor.xdata != -1)
+ return std::make_pair(cursor.xdata,
+ cast<ObjCMessageExpr>(getCursorExpr(cursor))
+ ->getSelectorLoc(cursor.xdata));
+ } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
+ cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
+ if (cursor.xdata != -1)
+ return std::make_pair(cursor.xdata,
+ cast<ObjCMethodDecl>(getCursorDecl(cursor))
+ ->getSelectorLoc(cursor.xdata));
+ }
+
+ return std::make_pair(-1, SourceLocation());
+}
+
+CXCursor cxcursor::getSelectorIdentifierCursor(int SelIdx, CXCursor cursor) {
+ CXCursor newCursor = cursor;
+
+ if (cursor.kind == CXCursor_ObjCMessageExpr) {
+ if (SelIdx == -1 ||
+ unsigned(SelIdx) >= cast<ObjCMessageExpr>(getCursorExpr(cursor))
+ ->getNumSelectorLocs())
+ newCursor.xdata = -1;
+ else
+ newCursor.xdata = SelIdx;
+ } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
+ cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
+ if (SelIdx == -1 ||
+ unsigned(SelIdx) >= cast<ObjCMethodDecl>(getCursorDecl(cursor))
+ ->getNumSelectorLocs())
+ newCursor.xdata = -1;
+ else
+ newCursor.xdata = SelIdx;
+ }
+
+ return newCursor;
+}
+
+CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
+ if (cursor.kind != CXCursor_CallExpr)
+ return cursor;
+
+ if (cursor.xdata == 0)
+ return cursor;
+
+ Expr *E = getCursorExpr(cursor);
+ TypeSourceInfo *Type = 0;
+ if (CXXUnresolvedConstructExpr *
+ UnCtor = dyn_cast<CXXUnresolvedConstructExpr>(E)) {
+ Type = UnCtor->getTypeSourceInfo();
+ } else if (CXXTemporaryObjectExpr *Tmp = dyn_cast<CXXTemporaryObjectExpr>(E)){
+ Type = Tmp->getTypeSourceInfo();
+ }
+
+ if (!Type)
+ return cursor;
+
+ CXTranslationUnit TU = getCursorTU(cursor);
+ QualType Ty = Type->getType();
+ TypeLoc TL = Type->getTypeLoc();
+ SourceLocation Loc = TL.getBeginLoc();
+
+ if (const ElaboratedType *ElabT = Ty->getAs<ElaboratedType>()) {
+ Ty = ElabT->getNamedType();
+ ElaboratedTypeLoc ElabTL = cast<ElaboratedTypeLoc>(TL);
+ Loc = ElabTL.getNamedTypeLoc().getBeginLoc();
+ }
+
+ if (const TypedefType *Typedef = Ty->getAs<TypedefType>())
+ return MakeCursorTypeRef(Typedef->getDecl(), Loc, TU);
+ if (const TagType *Tag = Ty->getAs<TagType>())
+ return MakeCursorTypeRef(Tag->getDecl(), Loc, TU);
+ if (const TemplateTypeParmType *TemplP = Ty->getAs<TemplateTypeParmType>())
+ return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU);
+
+ return cursor;
+}
+
bool cxcursor::operator==(CXCursor X, CXCursor Y) {
return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
X.data[2] == Y.data[2];
@@ -515,6 +918,22 @@ bool cxcursor::isFirstInDeclGroup(CXCursor C) {
}
//===----------------------------------------------------------------------===//
+// libclang CXCursor APIs
+//===----------------------------------------------------------------------===//
+
+extern "C" {
+
+int clang_Cursor_isNull(CXCursor cursor) {
+ return clang_equalCursors(cursor, clang_getNullCursor());
+}
+
+CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
+ return getCursorTU(cursor);
+}
+
+} // end: extern "C"
+
+//===----------------------------------------------------------------------===//
// CXCursorSet.
//===----------------------------------------------------------------------===//
@@ -577,4 +996,40 @@ unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) {
entry = 1;
return flag;
}
+
+CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
+ enum CXCursorKind kind = clang_getCursorKind(cursor);
+ if (clang_isDeclaration(kind)) {
+ Decl *decl = getCursorDecl(cursor);
+ if (isa<NamedDecl>(decl)) {
+ NamedDecl *namedDecl = (NamedDecl *)decl;
+ ASTUnit *unit = getCursorASTUnit(cursor);
+ if (unit->hasSema()) {
+ Sema &S = unit->getSema();
+ CodeCompletionAllocator *Allocator
+ = unit->getCursorCompletionAllocator().getPtr();
+ CodeCompletionResult Result(namedDecl);
+ CodeCompletionString *String
+ = Result.CreateCodeCompletionString(S, *Allocator);
+ return String;
+ }
+ }
+ }
+ else if (kind == CXCursor_MacroDefinition) {
+ MacroDefinition *definition = getCursorMacroDefinition(cursor);
+ const IdentifierInfo *MacroInfo = definition->getName();
+ ASTUnit *unit = getCursorASTUnit(cursor);
+ if (unit->hasSema()) {
+ Sema &S = unit->getSema();
+ CodeCompletionAllocator *Allocator
+ = unit->getCursorCompletionAllocator().getPtr();
+ CodeCompletionResult Result(const_cast<IdentifierInfo *>(MacroInfo));
+ CodeCompletionString *String
+ = Result.CreateCodeCompletionString(S, *Allocator);
+ return String;
+ }
+ }
+ return NULL;
+}
+
} // end: extern "C"
diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h
index 68d09e76c1c07..e402d7f970ca9 100644
--- a/tools/libclang/CXCursor.h
+++ b/tools/libclang/CXCursor.h
@@ -43,13 +43,17 @@ class TemplateName;
class TypeDecl;
namespace cxcursor {
+
+CXCursor getCursor(CXTranslationUnit, SourceLocation);
CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent,
CXTranslationUnit TU);
CXCursor MakeCXCursor(clang::Decl *D, CXTranslationUnit TU,
+ SourceRange RegionOfInterest = SourceRange(),
bool FirstInDeclGroup = true);
CXCursor MakeCXCursor(clang::Stmt *S, clang::Decl *Parent,
- CXTranslationUnit TU);
+ CXTranslationUnit TU,
+ SourceRange RegionOfInterest = SourceRange());
CXCursor MakeCXCursorInvalid(CXCursorKind K);
/// \brief Create an Objective-C superclass reference at the given location.
@@ -189,7 +193,36 @@ Decl *getCursorParentDecl(CXCursor Cursor);
ASTContext &getCursorContext(CXCursor Cursor);
ASTUnit *getCursorASTUnit(CXCursor Cursor);
CXTranslationUnit getCursorTU(CXCursor Cursor);
-
+
+void getOverriddenCursors(CXCursor cursor,
+ SmallVectorImpl<CXCursor> &overridden);
+
+/// \brief Returns a index/location pair for a selector identifier if the cursor
+/// points to one.
+std::pair<int, SourceLocation> getSelectorIdentifierIndexAndLoc(CXCursor);
+static inline int getSelectorIdentifierIndex(CXCursor cursor) {
+ return getSelectorIdentifierIndexAndLoc(cursor).first;
+}
+static inline SourceLocation getSelectorIdentifierLoc(CXCursor cursor) {
+ return getSelectorIdentifierIndexAndLoc(cursor).second;
+}
+
+CXCursor getSelectorIdentifierCursor(int SelIdx, CXCursor cursor);
+
+static inline CXCursor getTypeRefedCallExprCursor(CXCursor cursor) {
+ CXCursor newCursor = cursor;
+ if (cursor.kind == CXCursor_CallExpr)
+ newCursor.xdata = 1;
+ return newCursor;
+}
+
+CXCursor getTypeRefCursor(CXCursor cursor);
+
+/// \brief Generate a USR for \arg D and put it in \arg Buf.
+/// \returns true if no USR was computed or the result should be ignored,
+/// false otherwise.
+bool getDeclCursorUSR(Decl *D, SmallVectorImpl<char> &Buf);
+
bool operator==(CXCursor X, CXCursor Y);
inline bool operator!=(CXCursor X, CXCursor Y) {
diff --git a/tools/libclang/CXString.cpp b/tools/libclang/CXString.cpp
index f2a6b091ece4c..bb09cd5cdc226 100644
--- a/tools/libclang/CXString.cpp
+++ b/tools/libclang/CXString.cpp
@@ -41,7 +41,7 @@ CXString cxstring::createCXString(const char *String, bool DupString){
return Str;
}
-CXString cxstring::createCXString(llvm::StringRef String, bool DupString) {
+CXString cxstring::createCXString(StringRef String, bool DupString) {
CXString Result;
if (DupString || (!String.empty() && String.data()[String.size()] != 0)) {
char *Spelling = (char *)malloc(String.size() + 1);
@@ -101,6 +101,10 @@ void cxstring::disposeCXStringBuf(CXStringBuf *buf) {
static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf);
}
+bool cxstring::isManagedByPool(CXString str) {
+ return ((CXStringFlag) str.private_flags) == CXS_StringBuf;
+}
+
//===----------------------------------------------------------------------===//
// libClang public APIs.
//===----------------------------------------------------------------------===//
diff --git a/tools/libclang/CXString.h b/tools/libclang/CXString.h
index f03a6b2903847..d36c7c1e68ba6 100644
--- a/tools/libclang/CXString.h
+++ b/tools/libclang/CXString.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_CXSTRING_H
#include "clang-c/Index.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
@@ -31,7 +32,7 @@ struct CXStringBuf {
CXString createCXString(const char *String, bool DupString = false);
/// \brief Create a CXString object from a StringRef.
-CXString createCXString(llvm::StringRef String, bool DupString = true);
+CXString createCXString(StringRef String, bool DupString = true);
/// \brief Create a CXString object that is backed by a string buffer.
CXString createCXString(CXStringBuf *buf);
@@ -46,6 +47,9 @@ 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 6df85b7d4dc9e..2b8f977539c24 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -21,4 +21,13 @@ struct CXTranslationUnitImpl {
};
}
+namespace clang {
+ class ASTUnit;
+
+namespace cxtu {
+
+CXTranslationUnitImpl *MakeCXTranslationUnit(ASTUnit *TU);
+
+}} // end namespace clang::cxtu
+
#endif
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 45c73468d9711..0e62e2734b0c1 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -84,6 +84,7 @@ static CXTypeKind GetTypeKind(QualType T) {
TKCASE(ObjCObjectPointer);
TKCASE(FunctionNoProto);
TKCASE(FunctionProto);
+ TKCASE(ConstantArray);
default:
return CXType_Unexposed;
}
@@ -330,6 +331,7 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
TKIND(ObjCObjectPointer);
TKIND(FunctionNoProto);
TKIND(FunctionProto);
+ TKIND(ConstantArray);
}
#undef TKIND
return cxstring::createCXString(s);
@@ -373,6 +375,40 @@ unsigned clang_isPODType(CXType X) {
return T.isPODType(AU->getASTContext()) ? 1 : 0;
}
+CXType clang_getArrayElementType(CXType CT) {
+ QualType ET = QualType();
+ QualType T = GetQualType(CT);
+ const Type *TP = T.getTypePtrOrNull();
+
+ if (TP) {
+ switch (TP->getTypeClass()) {
+ case Type::ConstantArray:
+ ET = cast<ConstantArrayType> (TP)->getElementType();
+ break;
+ default:
+ break;
+ }
+ }
+ return MakeCXType(ET, GetTU(CT));
+}
+
+long long clang_getArraySize(CXType CT) {
+ long long result = -1;
+ QualType T = GetQualType(CT);
+ const Type *TP = T.getTypePtrOrNull();
+
+ if (TP) {
+ switch (TP->getTypeClass()) {
+ case Type::ConstantArray:
+ result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
+ break;
+ default:
+ break;
+ }
+ }
+ return result;
+}
+
CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl))
return cxstring::createCXString("");
diff --git a/tools/libclang/Index_Internal.h b/tools/libclang/Index_Internal.h
new file mode 100644
index 0000000000000..df54d7c879653
--- /dev/null
+++ b/tools/libclang/Index_Internal.h
@@ -0,0 +1,43 @@
+//===- CXString.h - Routines for manipulating CXStrings -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines routines for manipulating CXStrings.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBCLANG_INDEX_INTERNAL_H
+#define LLVM_LIBCLANG_INDEX_INTERNAL_H
+
+#include "clang-c/Index.h"
+
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+#if __has_feature(blocks)
+
+#define INVOKE_BLOCK2(block, arg1, arg2) block(arg1, arg2)
+
+#else
+// If we are compiled with a compiler that doesn't have native blocks support,
+// define and call the block manually.
+
+#define INVOKE_BLOCK2(block, arg1, arg2) block->invoke(block, arg1, arg2)
+
+typedef struct _CXCursorAndRangeVisitorBlock {
+ void *isa;
+ int flags;
+ int reserved;
+ enum CXVisitorResult (*invoke)(_CXCursorAndRangeVisitorBlock *,
+ CXCursor, CXSourceRange);
+} *CXCursorAndRangeVisitorBlock;
+
+#endif // !__has_feature(blocks)
+
+#endif
diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports
deleted file mode 100644
index bfc5be9c078b9..0000000000000
--- a/tools/libclang/libclang.darwin.exports
+++ /dev/null
@@ -1,143 +0,0 @@
-_clang_CXCursorSet_contains
-_clang_CXCursorSet_insert
-_clang_CXXMethod_isStatic
-_clang_CXXMethod_isVirtual
-_clang_annotateTokens
-_clang_codeCompleteAt
-_clang_codeCompleteGetDiagnostic
-_clang_codeCompleteGetNumDiagnostics
-_clang_codeCompleteGetContexts
-_clang_constructUSR_ObjCCategory
-_clang_constructUSR_ObjCClass
-_clang_constructUSR_ObjCIvar
-_clang_constructUSR_ObjCMethod
-_clang_constructUSR_ObjCProperty
-_clang_constructUSR_ObjCProtocol
-_clang_createCXCursorSet
-_clang_createIndex
-_clang_createTranslationUnit
-_clang_createTranslationUnitFromSourceFile
-_clang_defaultCodeCompleteOptions
-_clang_defaultDiagnosticDisplayOptions
-_clang_defaultEditingTranslationUnitOptions
-_clang_defaultReparseOptions
-_clang_defaultSaveOptions
-_clang_disposeCXCursorSet
-_clang_disposeCXTUResourceUsage
-_clang_disposeCodeCompleteResults
-_clang_disposeDiagnostic
-_clang_disposeIndex
-_clang_disposeOverriddenCursors
-_clang_disposeString
-_clang_disposeTokens
-_clang_disposeTranslationUnit
-_clang_enableStackTraces
-_clang_equalCursors
-_clang_equalLocations
-_clang_equalTypes
-_clang_executeOnThread
-_clang_formatDiagnostic
-_clang_getCString
-_clang_getCXTUResourceUsage
-_clang_getCXXAccessSpecifier
-_clang_getCanonicalCursor
-_clang_getCanonicalType
-_clang_getClangVersion
-_clang_getCompletionAvailability
-_clang_getCompletionChunkCompletionString
-_clang_getCompletionChunkKind
-_clang_getCompletionChunkText
-_clang_getCompletionPriority
-_clang_getCursor
-_clang_getCursorAvailability
-_clang_getCursorDefinition
-_clang_getCursorDisplayName
-_clang_getCursorExtent
-_clang_getCursorKind
-_clang_getCursorKindSpelling
-_clang_getCursorLanguage
-_clang_getCursorLexicalParent
-_clang_getCursorLinkage
-_clang_getCursorLocation
-_clang_getCursorReferenced
-_clang_getCursorResultType
-_clang_getCursorSemanticParent
-_clang_getCursorSpelling
-_clang_getCursorType
-_clang_getCursorUSR
-_clang_getDeclObjCTypeEncoding
-_clang_getDefinitionSpellingAndExtent
-_clang_getDiagnostic
-_clang_getDiagnosticCategory
-_clang_getDiagnosticCategoryName
-_clang_getDiagnosticFixIt
-_clang_getDiagnosticLocation
-_clang_getDiagnosticNumFixIts
-_clang_getDiagnosticNumRanges
-_clang_getDiagnosticOption
-_clang_getDiagnosticRange
-_clang_getDiagnosticSeverity
-_clang_getDiagnosticSpelling
-_clang_getFile
-_clang_getFileName
-_clang_getFileTime
-_clang_getIBOutletCollectionType
-_clang_getIncludedFile
-_clang_getInclusions
-_clang_getInstantiationLocation
-_clang_getLocation
-_clang_getLocationForOffset
-_clang_getNullCursor
-_clang_getNullLocation
-_clang_getNullRange
-_clang_getNumCompletionChunks
-_clang_getNumDiagnostics
-_clang_getNumOverloadedDecls
-_clang_getOverloadedDecl
-_clang_getOverriddenCursors
-_clang_getPointeeType
-_clang_getRange
-_clang_getRangeEnd
-_clang_getRangeStart
-_clang_getResultType
-_clang_getSpecializedCursorTemplate
-_clang_getSpellingLocation
-_clang_getTUResourceUsageName
-_clang_getTemplateCursorKind
-_clang_getTokenExtent
-_clang_getTokenKind
-_clang_getTokenLocation
-_clang_getTokenSpelling
-_clang_getTranslationUnitCursor
-_clang_getTranslationUnitSpelling
-_clang_getTypeDeclaration
-_clang_getTypeKindSpelling
-_clang_hashCursor
-_clang_isAttribute
-_clang_isConstQualifiedType
-_clang_isCursorDefinition
-_clang_isDeclaration
-_clang_isExpression
-_clang_isFileMultipleIncludeGuarded
-_clang_isInvalid
-_clang_isPODType
-_clang_isPreprocessing
-_clang_isReference
-_clang_isRestrictQualifiedType
-_clang_isStatement
-_clang_isTranslationUnit
-_clang_isUnexposed
-_clang_isVirtualBase
-_clang_isVolatileQualifiedType
-_clang_parseTranslationUnit
-_clang_reparseTranslationUnit
-_clang_saveTranslationUnit
-_clang_sortCodeCompletionResults
-_clang_toggleCrashRecovery
-_clang_tokenize
-_clang_visitChildren
-_clang_visitChildrenWithBlock
-_clang_getRemappings
-_clang_remap_getNumFiles
-_clang_remap_getFilenames
-_clang_remap_dispose
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 47b703011c766..989ed837ea246 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -4,9 +4,12 @@ clang_CXXMethod_isStatic
clang_CXXMethod_isVirtual
clang_annotateTokens
clang_codeCompleteAt
+clang_codeCompleteGetContainerKind
+clang_codeCompleteGetContainerUSR
+clang_codeCompleteGetContexts
clang_codeCompleteGetDiagnostic
clang_codeCompleteGetNumDiagnostics
-clang_codeCompleteGetContexts
+clang_codeCompleteGetObjCSelector
clang_constructUSR_ObjCCategory
clang_constructUSR_ObjCClass
clang_constructUSR_ObjCIvar
@@ -17,6 +20,8 @@ clang_createCXCursorSet
clang_createIndex
clang_createTranslationUnit
clang_createTranslationUnitFromSourceFile
+clang_Cursor_getTranslationUnit
+clang_Cursor_isNull
clang_defaultCodeCompleteOptions
clang_defaultDiagnosticDisplayOptions
clang_defaultEditingTranslationUnitOptions
@@ -34,9 +39,14 @@ clang_disposeTranslationUnit
clang_enableStackTraces
clang_equalCursors
clang_equalLocations
+clang_equalRanges
clang_equalTypes
clang_executeOnThread
+clang_findReferencesInFile
+clang_findReferencesInFileWithBlock
clang_formatDiagnostic
+clang_getArrayElementType
+clang_getArraySize
clang_getCString
clang_getCXTUResourceUsage
clang_getCXXAccessSpecifier
@@ -44,12 +54,15 @@ clang_getCanonicalCursor
clang_getCanonicalType
clang_getClangVersion
clang_getCompletionAvailability
+clang_getCompletionAnnotation
clang_getCompletionChunkCompletionString
clang_getCompletionChunkKind
clang_getCompletionChunkText
+clang_getCompletionNumAnnotations
clang_getCompletionPriority
clang_getCursor
clang_getCursorAvailability
+clang_getCursorCompletionString
clang_getCursorDefinition
clang_getCursorDisplayName
clang_getCursorExtent
@@ -59,6 +72,7 @@ clang_getCursorLanguage
clang_getCursorLexicalParent
clang_getCursorLinkage
clang_getCursorLocation
+clang_getCursorReferenceNameRange
clang_getCursorReferenced
clang_getCursorResultType
clang_getCursorSemanticParent
@@ -96,9 +110,11 @@ clang_getNumOverloadedDecls
clang_getOverloadedDecl
clang_getOverriddenCursors
clang_getPointeeType
+clang_getPresumedLocation
clang_getRange
clang_getRangeEnd
clang_getRangeStart
+clang_getRemappings
clang_getResultType
clang_getSpecializedCursorTemplate
clang_getSpellingLocation
@@ -130,6 +146,10 @@ clang_isUnexposed
clang_isVirtualBase
clang_isVolatileQualifiedType
clang_parseTranslationUnit
+clang_Range_isNull
+clang_remap_dispose
+clang_remap_getFilenames
+clang_remap_getNumFiles
clang_reparseTranslationUnit
clang_saveTranslationUnit
clang_sortCodeCompletionResults
@@ -137,7 +157,3 @@ clang_toggleCrashRecovery
clang_tokenize
clang_visitChildren
clang_visitChildrenWithBlock
-clang_getRemappings
-clang_remap_getNumFiles
-clang_remap_getFilenames
-clang_remap_dispose