[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,