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