r254750 - Fix debug info for Objective-C properties from class extensions after r251874

Nico Weber via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 4 11:14:14 PST 2015


Author: nico
Date: Fri Dec  4 13:14:14 2015
New Revision: 254750

URL: http://llvm.org/viewvc/llvm-project?rev=254750&view=rev
Log:
Fix debug info for Objective-C properties from class extensions after r251874

After r251874, properties from class extensions no longer show up in
ObjCInterfaceDecl::properties().  Make debug info emission explicitly
look for properties in class extensions before looking at direct properties.

Also add a test that checks for this.  There are three interesting cases:

1. A property is only declared in a class extension, and the @implementation
   is in a different file.  This used to generated a DIObjcProperty before
   r251874 and does again with this fix.

2. A property is declared as readonly in the class itself and redeclared as
   readwrite in a class extension. clang before r251874 put the DIObjcProperty
   on the first declaration. clang after r251874 didn't emit any DIObjcProperty,
   and clang with this fix puts it on the readwrite redeclaration (which is
   what lookup finds).  This seems like a progression.

3. Like 2, but with an @implementation in the same file.  In this case,
   the property debug info gets generated a second time through the ivar
   from the definition.  In this case, lookup and declaration code need
   to agree on the line number so that the DIObjcProperty isn't emitted
   twice.  In this case, clang before r251874 emitted one DIObjcProperty
   on the first declaration, clang with r251874 emitted one on the second
   declaration, and clang with this patch still does the latter.


Added:
    cfe/trunk/test/CodeGenObjC/debug-info-property-class-extension.m
Modified:
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=254750&r1=254749&r2=254750&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Fri Dec  4 13:14:14 2015
@@ -1791,7 +1791,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef
   }
 
   // Create entries for all of the properties.
-  for (const auto *PD : ID->properties()) {
+  auto AddProperty = [&](const ObjCPropertyDecl *PD) {
     SourceLocation Loc = PD->getLocation();
     llvm::DIFile *PUnit = getOrCreateFile(Loc);
     unsigned PLine = getLineNumber(Loc);
@@ -1805,6 +1805,21 @@ llvm::DIType *CGDebugInfo::CreateTypeDef
                                          : getSelectorName(PD->getSetterName()),
         PD->getPropertyAttributes(), getOrCreateType(PD->getType(), PUnit));
     EltTys.push_back(PropertyNode);
+  };
+  {
+    llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
+    //for (const ObjCCategoryDecl *ClassExt : ID->known_extensions())
+    //  for (auto *PD : ClassExt->properties()) {
+    //    PropertySet.insert(PD->getIdentifier());
+    //    AddProperty(PD);
+    //  }
+    for (const auto *PD : ID->properties()) {
+      // Don't emit duplicate metadata for properties that were already in a
+      // class extension.
+      if (!PropertySet.insert(PD->getIdentifier()).second)
+        continue;
+      AddProperty(PD);
+    }
   }
 
   const ASTRecordLayout &RL = CGM.getContext().getASTObjCInterfaceLayout(ID);

Added: cfe/trunk/test/CodeGenObjC/debug-info-property-class-extension.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/debug-info-property-class-extension.m?rev=254750&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/debug-info-property-class-extension.m (added)
+++ cfe/trunk/test/CodeGenObjC/debug-info-property-class-extension.m Fri Dec  4 13:14:14 2015
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -S -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+
+// Checks debug info for properties from class extensions for a few cases.
+
+
+// Readonly property in interface made readwrite in a category, with @impl
+// The interesting bit is that when the ivar debug info is generated, the corresponding
+// property is looked up and also gets debug info. If the debug info from the interface's
+// declaration and from the ivar doesn't match, this will end up with two DIObjCProperty
+// entries which would be bad.
+ at interface FooROWithImpl
+// CHECK-NOT: !DIObjCProperty(name: "evolvingpropwithimpl"{{.*}}line: [[@LINE+1]]
+ at property (readonly) int evolvingpropwithimpl;
+ at end
+ at interface FooROWithImpl ()
+// CHECK: !DIObjCProperty(name: "evolvingpropwithimpl"{{.*}}line: [[@LINE+1]]
+ at property int evolvingpropwithimpl;
+ at end
+ at implementation FooROWithImpl
+ at synthesize evolvingpropwithimpl = _evolvingpropwithimpl;
+ at end
+
+
+// Simple property from a class extension:
+ at interface Foo
+ at end
+ at interface Foo()
+// CHECK: !DIObjCProperty(name: "myprop"{{.*}}line: [[@LINE+1]]
+ at property int myprop;
+ at end
+// There's intentionally no @implementation for Foo, because that would
+// generate debug info for the property via the backing ivar.
+
+
+// Readonly property in interface made readwrite in a category:
+ at interface FooRO
+// Shouldn't be here but in the class extension below.
+// CHECK-NOT: !DIObjCProperty(name: "evolvingprop"{{.*}}line: [[@LINE+1]]
+ at property (readonly) int evolvingprop;
+ at end
+ at interface FooRO ()
+// CHECK: !DIObjCProperty(name: "evolvingprop"{{.*}}line: [[@LINE+1]]
+ at property int evolvingprop;
+ at end
+
+
+// This references types in this file to force emission of their debug info.
+void foo(Foo *f, FooRO *g, FooROWithImpl* h) { }




More information about the cfe-commits mailing list