Special case ObjCPropertyDecl for printing
authorDavid Goldman <dallasftball@gmail.com>
Thu, 4 Apr 2019 20:13:22 +0000 (20:13 +0000)
committerDavid Goldman <dallasftball@gmail.com>
Thu, 4 Apr 2019 20:13:22 +0000 (20:13 +0000)
ObjCPropertyDecl should use the category interface as a context similar to what is done for methods.

Previously category methods would be printed as `::property`; now they are printed as `Class::property`.

llvm-svn: 357720

clang/lib/AST/Decl.cpp
clang/unittests/AST/NamedDeclPrinterTest.cpp

index d197707..00014d0 100644 (file)
@@ -1531,10 +1531,16 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
                                    const PrintingPolicy &P) const {
   const DeclContext *Ctx = getDeclContext();
 
-  // For ObjC methods, look through categories and use the interface as context.
+  // For ObjC methods and properties, look through categories and use the
+  // interface as context.
   if (auto *MD = dyn_cast<ObjCMethodDecl>(this))
     if (auto *ID = MD->getClassInterface())
       Ctx = ID;
+  if (auto *PD = dyn_cast<ObjCPropertyDecl>(this)) {
+    if (auto *MD = PD->getGetterMethodDecl())
+      if (auto *ID = MD->getClassInterface())
+        Ctx = ID;
+  }
 
   if (Ctx->isFunctionOrMethod()) {
     printName(OS);
index 172268c..d97299b 100644 (file)
@@ -115,6 +115,18 @@ PrintedWrittenNamedDeclCXX11Matches(StringRef Code, StringRef DeclName,
                                  "input.cc");
 }
 
+::testing::AssertionResult
+PrintedWrittenPropertyDeclObjCMatches(StringRef Code, StringRef DeclName,
+                                   StringRef ExpectedPrinted) {
+  std::vector<std::string> Args{"-std=c++11", "-xobjective-c++"};
+  return PrintedNamedDeclMatches(Code,
+                                 Args,
+                                 /*SuppressUnwrittenScope*/ true,
+                                 objcPropertyDecl(hasName(DeclName)).bind("id"),
+                                 ExpectedPrinted,
+                                 "input.m");
+}
+
 } // unnamed namespace
 
 TEST(NamedDeclPrinter, TestNamespace1) {
@@ -179,3 +191,31 @@ TEST(NamedDeclPrinter, TestLinkageInNamespace) {
     "A",
     "X::A"));
 }
+
+TEST(NamedDeclPrinter, TestObjCClassExtension) {
+  ASSERT_TRUE(PrintedWrittenPropertyDeclObjCMatches(
+    R"(
+      @interface Obj
+      @end
+
+      @interface Obj ()
+      @property(nonatomic) int property;
+      @end
+    )",
+    "property",
+    "Obj::property"));
+}
+
+TEST(NamedDeclPrinter, TestObjCClassExtensionWithGetter) {
+  ASSERT_TRUE(PrintedWrittenPropertyDeclObjCMatches(
+    R"(
+      @interface Obj
+      @end
+
+      @interface Obj ()
+      @property(nonatomic, getter=myPropertyGetter) int property;
+      @end
+    )",
+    "property",
+    "Obj::property"));
+}