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. 48void foo(Foo *f, FooRO *g, FooROWithImpl* h) { } 49