1 // RUN: %clang_cc1 -S -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s 2 3 // Checks debug info for properties from class extensions for a few cases. 4 5 6 // Readonly property in interface made readwrite in a category, with @impl 7 // The interesting bit is that when the ivar debug info is generated, the corresponding 8 // property is looked up and also gets debug info. If the debug info from the interface's 9 // declaration and from the ivar doesn't match, this will end up with two DIObjCProperty 10 // entries which would be bad. 11 @interface FooROWithImpl 12 // CHECK-NOT: !DIObjCProperty(name: "evolvingpropwithimpl"{{.*}}line: [[@LINE+1]] 13 @property (readonly) int evolvingpropwithimpl; 14 @end 15 @interface FooROWithImpl () 16 // CHECK: !DIObjCProperty(name: "evolvingpropwithimpl"{{.*}}line: [[@LINE+1]] 17 @property int evolvingpropwithimpl; 18 @end 19 @implementation FooROWithImpl 20 @synthesize evolvingpropwithimpl = _evolvingpropwithimpl; 21 @end 22 23 24 // Simple property from a class extension: 25 @interface Foo 26 @end 27 @interface Foo() 28 // CHECK: !DIObjCProperty(name: "myprop"{{.*}}line: [[@LINE+1]] 29 @property int myprop; 30 @end 31 // There's intentionally no @implementation for Foo, because that would 32 // generate debug info for the property via the backing ivar. 33 34 35 // Readonly property in interface made readwrite in a category: 36 @interface FooRO 37 // Shouldn't be here but in the class extension below. 38 // CHECK-NOT: !DIObjCProperty(name: "evolvingprop"{{.*}}line: [[@LINE+1]] 39 @property (readonly) int evolvingprop; 40 @end 41 @interface FooRO () 42 // CHECK: !DIObjCProperty(name: "evolvingprop"{{.*}}line: [[@LINE+1]] 43 @property int evolvingprop; 44 @end 45 46 47 // This references types in this file to force emission of their debug info. 48 void foo(Foo *f, FooRO *g, FooROWithImpl* h) { } 49