[Index/USRGeneration] Make sure that ObjC properties in categories also get namescope...
authorArgyrios Kyrtzidis <kyrtzidis@apple.com>
Sat, 7 Mar 2020 23:04:23 +0000 (15:04 -0800)
committerArgyrios Kyrtzidis <kyrtzidis@apple.com>
Sat, 7 Mar 2020 23:07:37 +0000 (15:07 -0800)
If the property is in a category that has module names from external_declaration property, make sure they are included in the USR.

rdar://59897320

clang/lib/Index/USRGeneration.cpp
clang/test/Index/Core/external-source-symbol-attr.m

index 394daf9..f3eb653 100644 (file)
@@ -382,6 +382,14 @@ void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
     Out << "@NA@" << D->getName();
 }
 
+static const ObjCCategoryDecl *getCategoryContext(const NamedDecl *D) {
+  if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
+    return CD;
+  if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
+    return ICD->getCategoryDecl();
+  return nullptr;
+};
+
 void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
   const DeclContext *container = D->getDeclContext();
   if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
@@ -395,14 +403,6 @@ void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
       IgnoreResults = true;
       return;
     }
-    auto getCategoryContext = [](const ObjCMethodDecl *D) ->
-                                    const ObjCCategoryDecl * {
-      if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
-        return CD;
-      if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
-        return ICD->getCategoryDecl();
-      return nullptr;
-    };
     auto *CD = getCategoryContext(D);
     VisitObjCContainerDecl(ID, CD);
   }
@@ -475,7 +475,7 @@ void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
   // The USR for a property declared in a class extension or category is based
   // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
   if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
-    Visit(ID);
+    VisitObjCContainerDecl(ID, getCategoryContext(D));
   else
     Visit(cast<Decl>(D->getDeclContext()));
   GenObjCProperty(D->getName(), D->isClassProperty());
index 41bb7a2..d2cef35 100644 (file)
@@ -21,6 +21,10 @@ EXT_DECL("some_module")
 // CHECK: [[@LINE-1]]:12 | class/Swift | I2 | c:@M@some_module@objc(cs)I2 | {{.*}} | Decl | rel: 0
 -(void)method;
 // CHECK: [[@LINE-1]]:8 | instance-method/Swift | method | c:@M@some_module@objc(cs)I2(im)method | -[I2 method] | Decl,Dyn,RelChild | rel: 1
+@property int prop;
+// CHECK: [[@LINE-1]]:15 | instance-method/acc-get/Swift | prop | c:@M@some_module@objc(cs)I2(im)prop |
+// CHECK: [[@LINE-2]]:15 | instance-method/acc-set/Swift | setProp: | c:@M@some_module@objc(cs)I2(im)setProp: |
+// CHECK: [[@LINE-3]]:15 | instance-property/Swift | prop | c:@M@some_module@objc(cs)I2(py)prop |
 @end
 
 void test1(I1 *o) {
@@ -45,6 +49,10 @@ EXT_DECL("cat_module")
 // CHECK: [[@LINE-1]]:15 | extension/Swift | cat2 | c:@CM@cat_module@some_module@objc(cy)I1@cat2 |
 -(void)cat_method2;
 // CHECK: [[@LINE-1]]:8 | instance-method/Swift | cat_method2 | c:@CM@cat_module@some_module@objc(cs)I1(im)cat_method2
+@property int cat_prop2;
+// CHECK: [[@LINE-1]]:15 | instance-method/acc-get/Swift | cat_prop2 | c:@CM@cat_module@some_module@objc(cs)I1(im)cat_prop2 |
+// CHECK: [[@LINE-2]]:15 | instance-method/acc-set/Swift | setCat_prop2: | c:@CM@cat_module@some_module@objc(cs)I1(im)setCat_prop2: |
+// CHECK: [[@LINE-3]]:15 | instance-property/Swift | cat_prop2 | c:@CM@cat_module@some_module@objc(cs)I1(py)cat_prop2 |
 @end
 
 #define NS_ENUM(_name, _type) enum _name:_type _name; enum _name : _type