summaryrefslogtreecommitdiffstats
path: root/clang/tools/libclang/IndexingContext.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-11-22 07:24:51 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-11-22 07:24:51 +0000
commit4c910b1475a43076530c89835f9d7c5b44c21489 (patch)
tree326d120d2917199606c020957d6c0cee8fdd444c /clang/tools/libclang/IndexingContext.cpp
parentc55e1af13746105eaa4567a907503a035ad5db6c (diff)
downloadbcm5719-llvm-4c910b1475a43076530c89835f9d7c5b44c21489.tar.gz
bcm5719-llvm-4c910b1475a43076530c89835f9d7c5b44c21489.zip
[libclang] Indexing API: Support C++ symbols.
llvm-svn: 145058
Diffstat (limited to 'clang/tools/libclang/IndexingContext.cpp')
-rw-r--r--clang/tools/libclang/IndexingContext.cpp269
1 files changed, 235 insertions, 34 deletions
diff --git a/clang/tools/libclang/IndexingContext.cpp b/clang/tools/libclang/IndexingContext.cpp
index d31ccdf0615..77d48011137 100644
--- a/clang/tools/libclang/IndexingContext.cpp
+++ b/clang/tools/libclang/IndexingContext.cpp
@@ -12,7 +12,7 @@
#include "CIndexDiagnostic.h"
#include "clang/Frontend/ASTUnit.h"
-#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
using namespace clang;
@@ -28,7 +28,7 @@ IndexingContext::ObjCProtocolListInfo::ObjCProtocolListInfo(
I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
SourceLocation Loc = *LI;
ObjCProtocolDecl *PD = *I;
- ProtEntities.push_back(CXIdxEntityInfo());
+ ProtEntities.push_back(EntityInfo());
IdxCtx.getEntityInfo(PD, ProtEntities.back(), SA);
CXIdxObjCProtocolRefInfo ProtInfo = { 0,
MakeCursorObjCProtocolRef(PD, Loc, IdxCtx.CXTU),
@@ -80,8 +80,8 @@ IndexingContext::AttrListInfo::AttrListInfo(const Decl *D,
QualType Ty = IBAttr->getInterface();
if (const ObjCInterfaceType *InterTy = Ty->getAs<ObjCInterfaceType>()) {
if (const ObjCInterfaceDecl *InterD = InterTy->getInterface()) {
- IdxCtx.getEntityInfo(InterD, IBInfo.CXClassInfo, SA);
- IBInfo.IBCollInfo.objcClass = &IBInfo.CXClassInfo;
+ IdxCtx.getEntityInfo(InterD, IBInfo.ClassInfo, SA);
+ IBInfo.IBCollInfo.objcClass = &IBInfo.ClassInfo;
IBInfo.IBCollInfo.classCursor = MakeCursorObjCClassRef(InterD,
IBAttr->getInterfaceLoc(), IdxCtx.CXTU);
}
@@ -92,6 +92,32 @@ IndexingContext::AttrListInfo::AttrListInfo(const Decl *D,
CXAttrs.push_back(&Attrs[i]);
}
+IndexingContext::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
+ IndexingContext &IdxCtx,
+ IndexingContext::StrAdapter &SA) {
+ for (CXXRecordDecl::base_class_const_iterator
+ I = D->bases_begin(), E = D->bases_end(); I != E; ++I) {
+ const CXXBaseSpecifier &Base = *I;
+ BaseEntities.push_back(EntityInfo());
+ const CXXRecordDecl *BaseRD = 0;
+ if (const RecordType *RT = Base.getType()->getAs<RecordType>())
+ BaseRD = dyn_cast_or_null<CXXRecordDecl>(RT->getDecl());
+ IdxCtx.getEntityInfo(BaseRD, BaseEntities.back(), SA);
+ CXIdxBaseClassInfo BaseInfo = { 0,
+ MakeCursorCXXBaseSpecifier(&Base, IdxCtx.CXTU),
+ IdxCtx.getIndexLoc(Base.getSourceRange().getBegin()) };
+ BaseInfos.push_back(BaseInfo);
+ }
+
+ for (unsigned i = 0, e = BaseInfos.size(); i != e; ++i) {
+ if (BaseEntities[i].USR)
+ BaseInfos[i].base = &BaseEntities[i];
+ }
+
+ for (unsigned i = 0, e = BaseInfos.size(); i != e; ++i)
+ CXBases.push_back(&BaseInfos[i]);
+}
+
const char *IndexingContext::StrAdapter::toCStr(StringRef Str) {
if (Str.empty())
return "";
@@ -155,31 +181,33 @@ bool IndexingContext::handleDecl(const NamedDecl *D,
DeclInfo &DInfo) {
if (!CB.indexDeclaration || !D)
return false;
+ if (D->isImplicit() && shouldIgnoreIfImplicit(D))
+ return false;
StrAdapter SA(*this);
- getEntityInfo(D, DInfo.CXEntInfo, SA);
- if (!DInfo.CXEntInfo.USR || Loc.isInvalid())
+ getEntityInfo(D, DInfo.EntInfo, SA);
+ if (!DInfo.EntInfo.USR || Loc.isInvalid())
return false;
markEntityOccurrenceInFile(D, Loc);
- DInfo.entityInfo = &DInfo.CXEntInfo;
+ DInfo.entityInfo = &DInfo.EntInfo;
DInfo.cursor = Cursor;
DInfo.loc = getIndexLoc(Loc);
- DInfo.container = getIndexContainer(D);
DInfo.isImplicit = D->isImplicit();
AttrListInfo AttrList(D, *this, SA);
DInfo.attributes = AttrList.getAttrs();
DInfo.numAttributes = AttrList.getNumAttrs();
- CXIdxClientContainer clientCont = 0;
- CXIdxDeclOut DeclOut = { DInfo.isContainer ? &clientCont : 0 };
- CB.indexDeclaration(ClientData, &DInfo, &DeclOut);
-
- if (DInfo.isContainer)
- addContainerInMap(cast<DeclContext>(D), clientCont);
+ getContainerInfo(D->getDeclContext(), DInfo.Container);
+ DInfo.container = &DInfo.Container;
+ if (DInfo.isContainer) {
+ getContainerInfo(getEntityContainer(D), DInfo.DeclAsContainer);
+ DInfo.declAsContainer = &DInfo.DeclAsContainer;
+ }
+ CB.indexDeclaration(ClientData, &DInfo);
return true;
}
@@ -215,12 +243,15 @@ bool IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
}
bool IndexingContext::handleTagDecl(const TagDecl *D) {
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(D))
+ return handleCXXRecordDecl(CXXRD, D);
+
DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
D->isThisDeclarationADefinition());
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
}
-bool IndexingContext::handleTypedef(const TypedefDecl *D) {
+bool IndexingContext::handleTypedefName(const TypedefNameDecl *D) {
DeclInfo DInfo(!D->isFirstDeclaration(), /*isDefinition=*/true,
/*isContainer=*/false);
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
@@ -242,7 +273,7 @@ bool IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
StrAdapter SA(*this);
CXIdxBaseClassInfo BaseClass;
- CXIdxEntityInfo BaseEntity;
+ EntityInfo BaseEntity;
BaseClass.cursor = clang_getNullCursor();
if (ObjCInterfaceDecl *SuperD = D->getSuperClass()) {
getEntityInfo(SuperD, BaseEntity, SA);
@@ -293,7 +324,7 @@ bool IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
bool IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/false);
- CXIdxEntityInfo ClassEntity;
+ EntityInfo ClassEntity;
StrAdapter SA(*this);
const ObjCInterfaceDecl *IFaceD = D->getClassInterface();
SourceLocation ClassLoc = D->getLocation();
@@ -317,7 +348,7 @@ bool IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
bool IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
const ObjCCategoryDecl *CatD = D->getCategoryDecl();
ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/true);
- CXIdxEntityInfo ClassEntity;
+ EntityInfo ClassEntity;
StrAdapter SA(*this);
const ObjCInterfaceDecl *IFaceD = CatD->getClassInterface();
SourceLocation ClassLoc = D->getLocation();
@@ -362,6 +393,23 @@ bool IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
}
+bool IndexingContext::handleClassTemplate(const ClassTemplateDecl *D) {
+ return handleCXXRecordDecl(D->getTemplatedDecl(), D);
+}
+
+bool IndexingContext::handleFunctionTemplate(const FunctionTemplateDecl *D) {
+ DeclInfo DInfo(/*isRedeclaration=*/!D->isCanonicalDecl(),
+ /*isDefinition=*/D->isThisDeclarationADefinition(),
+ /*isContainer=*/D->isThisDeclarationADefinition());
+ return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
+}
+
+bool IndexingContext::handleTypeAliasTemplate(const TypeAliasTemplateDecl *D) {
+ DeclInfo DInfo(/*isRedeclaration=*/!D->isCanonicalDecl(),
+ /*isDefinition=*/true, /*isContainer=*/false);
+ return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
+}
+
bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
const NamedDecl *Parent,
const DeclContext *DC,
@@ -382,35 +430,41 @@ bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
const DeclContext *DC,
const Expr *E,
CXIdxEntityRefKind Kind) {
- if (!D)
+ if (!CB.indexEntityReference)
return false;
- if (D->getParentFunctionOrMethod())
+
+ if (!D)
return false;
if (Loc.isInvalid())
return false;
- if (!CB.indexEntityReference)
+ if (D->getParentFunctionOrMethod())
return false;
if (isNotFromSourceFile(D->getLocation()))
return false;
+ if (D->isImplicit() && shouldIgnoreIfImplicit(D))
+ return false;
+
+ if (suppressRefs()) {
+ if (markEntityOccurrenceInFile(D, Loc))
+ return false; // already occurred.
+ }
StrAdapter SA(*this);
- CXIdxEntityInfo RefEntity, ParentEntity;
+ EntityInfo RefEntity, ParentEntity;
getEntityInfo(D, RefEntity, SA);
if (!RefEntity.USR)
return false;
getEntityInfo(Parent, ParentEntity, SA);
- if (suppressRefs()) {
- if (markEntityOccurrenceInFile(D, Loc))
- return false; // already occurred.
- }
+ ContainerInfo Container;
+ getContainerInfo(DC, Container);
CXIdxEntityRefInfo Info = { Cursor,
getIndexLoc(Loc),
&RefEntity,
Parent ? &ParentEntity : 0,
- getIndexContainerForDC(DC),
+ &Container,
Kind };
CB.indexEntityReference(ClientData, &Info);
return true;
@@ -427,6 +481,9 @@ bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const {
void IndexingContext::addContainerInMap(const DeclContext *DC,
CXIdxClientContainer container) {
+ if (!DC)
+ return;
+
assert(getScopedContext(DC) == DC);
ContainerMapTy::iterator I = ContainerMap.find(DC);
if (I == ContainerMap.end()) {
@@ -442,6 +499,34 @@ void IndexingContext::addContainerInMap(const DeclContext *DC,
ContainerMap.erase(I);
}
+CXIdxClientEntity IndexingContext::getClientEntity(const Decl *D) const {
+ if (!D)
+ return 0;
+ EntityMapTy::const_iterator I = EntityMap.find(D);
+ if (I == EntityMap.end())
+ return 0;
+ return I->second;
+}
+
+void IndexingContext::setClientEntity(const Decl *D, CXIdxClientEntity client) {
+ if (!D)
+ return;
+ EntityMap[D] = client;
+}
+
+bool IndexingContext::handleCXXRecordDecl(const CXXRecordDecl *RD,
+ const NamedDecl *OrigD) {
+ StrAdapter SA(*this);
+ CXXClassDeclInfo DInfo(/*isRedeclaration=*/!OrigD->isCanonicalDecl(),
+ /*isDefinition=*/RD->isThisDeclarationADefinition());
+ CXXBasesListInfo BaseList(RD, *this, SA);
+ DInfo.CXXClassInfo.declInfo = &DInfo;
+ DInfo.CXXClassInfo.bases = BaseList.getBases();
+ DInfo.CXXClassInfo.numBases = BaseList.getNumBases();
+
+ return handleDecl(OrigD, OrigD->getLocation(), getCursor(OrigD), DInfo);
+}
+
bool IndexingContext::markEntityOccurrenceInFile(const NamedDecl *D,
SourceLocation Loc) {
SourceManager &SM = Ctx->getSourceManager();
@@ -476,12 +561,34 @@ const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const {
} else if (const ObjCCategoryImplDecl *
CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) {
return getEntityDecl(CatImplD->getCategoryDecl());
+ } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (FunctionTemplateDecl *TemplD = FD->getDescribedFunctionTemplate())
+ return getEntityDecl(TemplD);
+ } else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+ if (ClassTemplateDecl *TemplD = RD->getDescribedClassTemplate())
+ return getEntityDecl(TemplD);
}
return D;
}
const DeclContext *
+IndexingContext::getEntityContainer(const Decl *D) const {
+ const DeclContext *DC = dyn_cast<DeclContext>(D);
+ if (DC)
+ return DC;
+
+ if (const ClassTemplateDecl *ClassTempl = dyn_cast<ClassTemplateDecl>(D)) {
+ DC = ClassTempl->getTemplatedDecl();
+ } if (const FunctionTemplateDecl *
+ FuncTempl = dyn_cast<FunctionTemplateDecl>(D)) {
+ DC = FuncTempl->getTemplatedDecl();
+ }
+
+ return DC;
+}
+
+const DeclContext *
IndexingContext::getScopedContext(const DeclContext *DC) const {
// Local contexts are ignored for indexing.
const DeclContext *FuncCtx = cast<Decl>(DC)->getParentFunctionOrMethod();
@@ -502,13 +609,15 @@ IndexingContext::getScopedContext(const DeclContext *DC) const {
}
CXIdxClientContainer
-IndexingContext::getIndexContainerForDC(const DeclContext *DC) const {
+IndexingContext::getClientContainerForDC(const DeclContext *DC) const {
+ if (!DC)
+ return 0;
+
DC = getScopedContext(DC);
ContainerMapTy::const_iterator I = ContainerMap.find(DC);
if (I == ContainerMap.end())
return 0;
-// assert(I != ContainerMap.end() &&
-// "Failed to include a scoped context in the container map");
+
return I->second;
}
@@ -564,12 +673,18 @@ void IndexingContext::translateLoc(SourceLocation Loc,
}
void IndexingContext::getEntityInfo(const NamedDecl *D,
- CXIdxEntityInfo &EntityInfo,
- StrAdapter &SA) {
+ EntityInfo &EntityInfo,
+ StrAdapter &SA) {
+ EntityInfo.name = EntityInfo.USR = 0;
if (!D)
return;
+
D = getEntityDecl(D);
+ EntityInfo.cursor = getCursor(D);
+ EntityInfo.Dcl = D;
+ EntityInfo.IndexCtx = this;
EntityInfo.kind = CXIdxEntity_Unexposed;
+ EntityInfo.templateKind = CXIdxEntity_NonTemplate;
if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
switch (TD->getTagKind()) {
@@ -583,14 +698,29 @@ void IndexingContext::getEntityInfo(const NamedDecl *D,
EntityInfo.kind = CXIdxEntity_Enum; break;
}
+ if (const CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(D)) {
+ if (TD->getTagKind() == TTK_Struct && !CXXRec->isPOD())
+ EntityInfo.kind = CXIdxEntity_CXXClass;
+ }
+
+ if (isa<ClassTemplatePartialSpecializationDecl>(D)) {
+ EntityInfo.templateKind = CXIdxEntity_TemplatePartialSpecialization;
+ } else if (isa<ClassTemplateSpecializationDecl>(D)) {
+ EntityInfo.templateKind = CXIdxEntity_TemplateSpecialization;
+ }
+
} else {
switch (D->getKind()) {
case Decl::Typedef:
EntityInfo.kind = CXIdxEntity_Typedef; break;
case Decl::Function:
- EntityInfo.kind = CXIdxEntity_Function; break;
+ EntityInfo.kind = CXIdxEntity_Function;
+ break;
case Decl::Var:
- EntityInfo.kind = CXIdxEntity_Variable; break;
+ EntityInfo.kind = CXIdxEntity_Variable;
+ if (isa<CXXRecordDecl>(D->getDeclContext()))
+ EntityInfo.kind = CXIdxEntity_CXXStaticVariable;
+ break;
case Decl::Field:
EntityInfo.kind = CXIdxEntity_Field; break;
case Decl::EnumConstant:
@@ -611,11 +741,67 @@ void IndexingContext::getEntityInfo(const NamedDecl *D,
EntityInfo.kind = CXIdxEntity_ObjCProperty; break;
case Decl::ObjCIvar:
EntityInfo.kind = CXIdxEntity_ObjCIvar; break;
+ case Decl::Namespace:
+ EntityInfo.kind = CXIdxEntity_CXXNamespace; break;
+ case Decl::NamespaceAlias:
+ EntityInfo.kind = CXIdxEntity_CXXNamespaceAlias; break;
+ case Decl::CXXConstructor:
+ EntityInfo.kind = CXIdxEntity_CXXConstructor; break;
+ case Decl::CXXDestructor:
+ EntityInfo.kind = CXIdxEntity_CXXDestructor; break;
+ case Decl::CXXConversion:
+ EntityInfo.kind = CXIdxEntity_CXXConversionFunction; break;
+ case Decl::CXXMethod: {
+ const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
+ if (MD->isStatic())
+ EntityInfo.kind = CXIdxEntity_CXXStaticMethod;
+ else
+ EntityInfo.kind = CXIdxEntity_CXXInstanceMethod;
+ break;
+ }
+ case Decl::ClassTemplate:
+ EntityInfo.kind = CXIdxEntity_CXXClass;
+ EntityInfo.templateKind = CXIdxEntity_Template;
+ break;
+ case Decl::FunctionTemplate:
+ EntityInfo.kind = CXIdxEntity_Function;
+ EntityInfo.templateKind = CXIdxEntity_Template;
+ if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(
+ cast<FunctionTemplateDecl>(D)->getTemplatedDecl())) {
+ if (isa<CXXConstructorDecl>(MD))
+ EntityInfo.kind = CXIdxEntity_CXXConstructor;
+ else if (isa<CXXDestructorDecl>(MD))
+ EntityInfo.kind = CXIdxEntity_CXXDestructor;
+ else if (isa<CXXConversionDecl>(MD))
+ EntityInfo.kind = CXIdxEntity_CXXConversionFunction;
+ else {
+ if (MD->isStatic())
+ EntityInfo.kind = CXIdxEntity_CXXStaticMethod;
+ else
+ EntityInfo.kind = CXIdxEntity_CXXInstanceMethod;
+ }
+ }
+ break;
+ case Decl::TypeAliasTemplate:
+ EntityInfo.kind = CXIdxEntity_CXXTypeAlias;
+ EntityInfo.templateKind = CXIdxEntity_Template;
+ break;
+ case Decl::TypeAlias:
+ EntityInfo.kind = CXIdxEntity_CXXTypeAlias; break;
default:
break;
}
}
+ if (EntityInfo.kind == CXIdxEntity_Unexposed)
+ return;
+
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (FD->getTemplatedKind() ==
+ FunctionDecl::TK_FunctionTemplateSpecialization)
+ EntityInfo.templateKind = CXIdxEntity_TemplateSpecialization;
+ }
+
if (IdentifierInfo *II = D->getIdentifier()) {
EntityInfo.name = SA.toCStr(II->getName());
@@ -642,6 +828,13 @@ void IndexingContext::getEntityInfo(const NamedDecl *D,
}
}
+void IndexingContext::getContainerInfo(const DeclContext *DC,
+ ContainerInfo &ContInfo) {
+ ContInfo.cursor = getCursor(cast<Decl>(DC));
+ ContInfo.DC = DC;
+ ContInfo.IndexCtx = this;
+}
+
CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) {
if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
return MakeCursorTypeRef(TD, Loc, CXTU);
@@ -660,3 +853,11 @@ CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) {
return clang_getNullCursor();
}
+
+bool IndexingContext::shouldIgnoreIfImplicit(const NamedDecl *D) {
+ if (isa<ObjCIvarDecl>(D))
+ return false;
+ if (isa<ObjCMethodDecl>(D))
+ return false;
+ return true;
+}
OpenPOWER on IntegriCloud