[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Rewriter / instancetype-test.mm
blob1c4a92397f8dd1f0943281e062047f691faf5582
1 // RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp
2 // RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
3 // RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp
4 // RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp
6 void *sel_registerName(const char *);
8 @interface Root
9 + (instancetype)alloc;
10 - (instancetype)init; // expected-note{{overridden method is part of the 'init' method family}}
11 - (instancetype)self;
12 - (Class)class;
14 @property (assign) Root *selfProp;
15 - (instancetype)selfProp;
16 @end
18 @protocol Proto1
19 @optional
20 - (instancetype)methodInProto1;
21 @end
23 @protocol Proto2
24 @optional
25 - (instancetype)methodInProto2; // expected-note{{overridden method returns an instance of its class type}}
26 - (instancetype)otherMethodInProto2; // expected-note{{overridden method returns an instance of its class type}}
27 @end
29 @interface Subclass1 : Root
30 - (instancetype)initSubclass1;
31 - (void)methodOnSubclass1;
32 + (instancetype)allocSubclass1;
33 @end
35 @interface Subclass2 : Root
36 - (instancetype)initSubclass2;
37 - (void)methodOnSubclass2;
38 @end
40 // Check the basic initialization pattern.
41 void test_instancetype_alloc_init_simple() {
42   Root *r1 = [[Root alloc] init];
43   Subclass1 *sc1 = [[Subclass1 alloc] init];
46 // Test that message sends to instancetype methods have the right type.
47 void test_instancetype_narrow_method_search() {
48   // instancetype on class methods
49   Subclass1 *sc1 = [[Subclass1 alloc] initSubclass2]; // expected-warning{{'Subclass1' may not respond to 'initSubclass2'}}
50   Subclass2 *sc2 = [[Subclass2 alloc] initSubclass2]; // okay
52   // instancetype on instance methods
53   [[[Subclass1 alloc] init] methodOnSubclass2]; // expected-warning{{'Subclass1' may not respond to 'methodOnSubclass2'}}
54   [[[Subclass2 alloc] init] methodOnSubclass2];
55   
56   // instancetype on class methods using protocols
57   [[Subclass1<Proto1> alloc] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}
58   [[Subclass1<Proto2> alloc] methodInProto2];
60   // instancetype on instance methods
61   Subclass1<Proto1> *sc1proto1 = 0;
62   [[sc1proto1 self] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}
63   Subclass1<Proto2> *sc1proto2 = 0;
64   [[sc1proto2 self] methodInProto2];
66   // Exact type checks
67   // Message sends to Class.
68   // FIXME. This is not supported due to missing capability in rewriter and not due to instancetype issues
69   //  Subclass1<Proto1> *sc1proto1_2 = [[[sc1proto1 class] alloc] init];
71   // Property access
72   [sc1proto1.self methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}
73   [sc1proto2.self methodInProto2];
75   [sc1proto1.selfProp methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}
76   [sc1proto2.selfProp methodInProto2];