Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -2740,16 +2740,26 @@ EltTys.push_back(PropertyNode); }; { - llvm::SmallPtrSet PropertySet; + // Use 'char' for the isClassProperty bit as DenseSet requires space for + // empty/tombstone keys in the data type (and bool is too small for that). + typedef std::pair IsClassAndIdent; + /// List of already emitted properties. Two distinct class and instance + /// properties can share the same identifier (but not two instance + /// properties or two class properties). + llvm::DenseSet PropertySet; + /// Returns the IsClassAndIdent key for the given property. + auto GetIsClassAndIdent = [](const ObjCPropertyDecl *PD) { + return std::make_pair(PD->isClassProperty(), PD->getIdentifier()); + }; for (const ObjCCategoryDecl *ClassExt : ID->known_extensions()) for (auto *PD : ClassExt->properties()) { - PropertySet.insert(PD->getIdentifier()); + PropertySet.insert(GetIsClassAndIdent(PD)); 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) + if (!PropertySet.insert(GetIsClassAndIdent(PD)).second) continue; AddProperty(PD); } Index: clang/test/CodeGenObjC/debug-info-property-class-instance-same-name.m =================================================================== --- /dev/null +++ clang/test/CodeGenObjC/debug-info-property-class-instance-same-name.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -S -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s + +// Both properties should be emitted as having a class and an instance property +// with the same name is allowed. +@interface I1 +// CHECK: !DIObjCProperty(name: "p1" +// CHECK-SAME: line: [[@LINE+1]] +@property int p1; +// CHECK: !DIObjCProperty(name: "p1" +// CHECK-SAME: line: [[@LINE+1]] +@property(class) int p1; +@end + +@implementation I1 +@synthesize p1; +@end + +void foo(I1 *iptr) {}