[index] Add 'IBTypeOf' relation for ObjC methods marked with IBAction and properties with IBOutletCollection.
llvm-svn: 291703
diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp
index 1225391..6c5b2e5 100644
--- a/clang/lib/Index/IndexDecl.cpp
+++ b/clang/lib/Index/IndexDecl.cpp
@@ -46,10 +46,13 @@
}
void handleDeclarator(const DeclaratorDecl *D,
- const NamedDecl *Parent = nullptr) {
+ const NamedDecl *Parent = nullptr,
+ bool isIBType = false) {
if (!Parent) Parent = D;
- IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent);
+ IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent,
+ Parent->getLexicalDeclContext(),
+ /*isBase=*/false, isIBType);
IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
// Only index parameters in definitions, parameters in declarations are
@@ -92,8 +95,11 @@
if (!IndexCtx.handleDecl(D, (unsigned)SymbolRole::Dynamic, Relations))
return false;
IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
- for (const auto *I : D->parameters())
- handleDeclarator(I, D);
+ bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
+ for (const auto *I : D->parameters()) {
+ handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
+ hasIBActionAndFirst = false;
+ }
if (D->isThisDeclarationADefinition()) {
const Stmt *Body = D->getBody();
@@ -333,6 +339,9 @@
handleObjCMethod(MD, D);
if (!IndexCtx.handleDecl(D))
return false;
+ if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
+ IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
+ D->getLexicalDeclContext(), false, true);
IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
return true;
}
diff --git a/clang/lib/Index/IndexSymbol.cpp b/clang/lib/Index/IndexSymbol.cpp
index d7df097..5192122 100644
--- a/clang/lib/Index/IndexSymbol.cpp
+++ b/clang/lib/Index/IndexSymbol.cpp
@@ -290,6 +290,7 @@
APPLY_FOR_ROLE(RelationExtendedBy);
APPLY_FOR_ROLE(RelationAccessorOf);
APPLY_FOR_ROLE(RelationContainedBy);
+ APPLY_FOR_ROLE(RelationIBTypeOf);
#undef APPLY_FOR_ROLE
}
@@ -319,6 +320,7 @@
case SymbolRole::RelationExtendedBy: OS << "RelExt"; break;
case SymbolRole::RelationAccessorOf: OS << "RelAcc"; break;
case SymbolRole::RelationContainedBy: OS << "RelCont"; break;
+ case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break;
}
});
}
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index 619a9a4..38bbb30 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -26,12 +26,16 @@
public:
TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
- const DeclContext *DC, bool isBase)
+ const DeclContext *DC, bool isBase, bool isIBType)
: IndexCtx(indexCtx), Parent(parent), ParentDC(DC), IsBase(isBase) {
if (IsBase) {
assert(Parent);
Relations.emplace_back((unsigned)SymbolRole::RelationBaseOf, Parent);
}
+ if (isIBType) {
+ assert(Parent);
+ Relations.emplace_back((unsigned)SymbolRole::RelationIBTypeOf, Parent);
+ }
}
bool shouldWalkTypesOfTypeLocs() const { return false; }
@@ -93,13 +97,13 @@
bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
return IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
- Parent, ParentDC, SymbolRoleSet());
+ Parent, ParentDC, SymbolRoleSet(), Relations);
}
bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
- Parent, ParentDC, SymbolRoleSet());
+ Parent, ParentDC, SymbolRoleSet(), Relations);
}
return true;
}
@@ -130,23 +134,25 @@
void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
const NamedDecl *Parent,
const DeclContext *DC,
- bool isBase) {
+ bool isBase,
+ bool isIBType) {
if (!TInfo || TInfo->getTypeLoc().isNull())
return;
- indexTypeLoc(TInfo->getTypeLoc(), Parent, DC, isBase);
+ indexTypeLoc(TInfo->getTypeLoc(), Parent, DC, isBase, isIBType);
}
void IndexingContext::indexTypeLoc(TypeLoc TL,
const NamedDecl *Parent,
const DeclContext *DC,
- bool isBase) {
+ bool isBase,
+ bool isIBType) {
if (TL.isNull())
return;
if (!DC)
DC = Parent->getLexicalDeclContext();
- TypeIndexer(*this, Parent, DC, isBase).TraverseTypeLoc(TL);
+ TypeIndexer(*this, Parent, DC, isBase, isIBType).TraverseTypeLoc(TL);
}
void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
diff --git a/clang/lib/Index/IndexingContext.cpp b/clang/lib/Index/IndexingContext.cpp
index 2d5fc0d..6dd6c0c 100644
--- a/clang/lib/Index/IndexingContext.cpp
+++ b/clang/lib/Index/IndexingContext.cpp
@@ -314,9 +314,15 @@
if (Parent) {
if (IsRef) {
- addRelation(SymbolRelation{(unsigned)SymbolRole::RelationContainedBy, Parent});
+ addRelation(SymbolRelation{
+ (unsigned)SymbolRole::RelationContainedBy,
+ Parent
+ });
} else if (!cast<DeclContext>(Parent)->isFunctionOrMethod()) {
- addRelation(SymbolRelation{(unsigned)SymbolRole::RelationChildOf, Parent});
+ addRelation(SymbolRelation{
+ (unsigned)SymbolRole::RelationChildOf,
+ Parent
+ });
}
}
diff --git a/clang/lib/Index/IndexingContext.h b/clang/lib/Index/IndexingContext.h
index 600fc43..dd1dd32 100644
--- a/clang/lib/Index/IndexingContext.h
+++ b/clang/lib/Index/IndexingContext.h
@@ -85,11 +85,13 @@
void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
const DeclContext *DC = nullptr,
- bool isBase = false);
+ bool isBase = false,
+ bool isIBType = false);
void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent,
const DeclContext *DC = nullptr,
- bool isBase = false);
+ bool isBase = false,
+ bool isIBType = false);
void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
const NamedDecl *Parent,