1// RUN: rm -rf %t
2// RUN: %clang_cc1 -fmodules -Wreturn-type -fmodules-cache-path=%t -I %S/Inputs %s -verify -Wno-objc-root-class
3
4@class C2;
5@class C3;
6@class C3;
7@import redecl_merge_left;
8typedef struct my_struct_type *my_struct_ref;
9@protocol P4;
10@class C3;
11@class C3;
12
13int *call_eventually_noreturn(void) {
14  eventually_noreturn();
15} // expected-warning{{control reaches end of non-void function}}
16
17int *call_eventually_noreturn2(void) {
18  eventually_noreturn2();
19} // expected-warning{{control reaches end of non-void function}}
20
21@import redecl_merge_right;
22
23int *call_eventually_noreturn_again(void) {
24  eventually_noreturn();
25}
26
27int *call_eventually_noreturn2_again(void) {
28  // noreturn and non-noreturn functions have different types
29  eventually_noreturn2(); // expected-error{{call to 'eventually_noreturn2' is ambiguous}}
30  // expected-note@Inputs/redecl-merge-left.h:93{{candidate function}}
31  // expected-note@Inputs/redecl-merge-right.h:90{{candidate function}}
32}
33
34@implementation A
35- (Super*)init { return self; }
36@end
37
38void f(A *a) {
39  [a init];
40}
41
42@class A;
43
44B *f1() {
45  return [B create_a_B];
46}
47
48@class B;
49
50void testProtoMerge(id<P1> p1, id<P2> p2) {
51  [p1 protoMethod1];
52  [p2 protoMethod2];
53}
54
55struct S1 {
56  int s1_field;
57};
58
59struct S3 {
60  int s3_field;
61};
62
63void testTagMerge() {
64  consume_S1(produce_S1());
65  struct S2 s2;
66  s2.field = 0;
67  consume_S2(produce_S2());
68  struct S1 s1;
69  s1.s1_field = 0;
70  consume_S3(produce_S3());
71  struct S4 s4;
72  s4.field = 0;
73  consume_S4(produce_S4());
74  struct S3 s3;
75  s3.s3_field = 0;
76}
77
78void testTypedefMerge(int i, double d) {
79  T1 *ip = &i;
80  // FIXME: Typedefs aren't actually merged in the sense of other merges, because
81  // we should only merge them when the types are identical.
82  // expected-note@Inputs/redecl-merge-left.h:60{{candidate found by name lookup is 'T2'}}
83  // expected-note@Inputs/redecl-merge-right.h:63{{candidate found by name lookup is 'T2'}}
84  T2 *dp = &d; // expected-error{{reference to 'T2' is ambiguous}}
85}
86
87void testFuncMerge(int i) {
88  func0(i);
89  func1(i);
90  // expected-note@Inputs/redecl-merge-left.h:64{{candidate function}}
91  // expected-note@Inputs/redecl-merge-right.h:70{{candidate function}}
92  func2(i); // expected-error{{call to 'func2' is ambiguous}}
93}
94
95void testVarMerge(int i) {
96  var1 = i;
97  // expected-note@Inputs/redecl-merge-left.h:77{{candidate found by name lookup is 'var2'}}
98  // expected-note@Inputs/redecl-merge-right.h:77{{candidate found by name lookup is 'var2'}}
99  var2 = i; // expected-error{{reference to 'var2' is ambiguous}}
100  // expected-note@Inputs/redecl-merge-left.h:79{{candidate found by name lookup is 'var3'}}
101  // expected-note@Inputs/redecl-merge-right.h:79{{candidate found by name lookup is 'var3'}}
102  var3 = i; // expected-error{{reference to 'var3' is ambiguous}}
103}
104
105// Test redeclarations of entities in explicit submodules, to make
106// sure we're maintaining the declaration chains even when normal name
107// lookup can't see what we're looking for.
108void testExplicit() {
109  Explicit *e;
110  int *(*fp)(void) = &explicit_func;
111  int *ip = explicit_func();
112
113  // FIXME: Should complain about definition not having been imported.
114  struct explicit_struct es = { 0 };
115}
116
117// Test resolution of declarations from multiple modules with no
118// common original declaration.
119void test_C(C *c) {
120  c = get_a_C();
121  accept_a_C(c);
122}
123
124void test_C2(C2 *c2) {
125  c2 = get_a_C2();
126  accept_a_C2(c2);
127}
128
129void test_C3(C3 *c3) {
130  c3 = get_a_C3();
131  accept_a_C3(c3);
132}
133
134C4 *global_C4;
135
136ClassWithDef *cwd1;
137
138@import redecl_merge_left_left;
139
140void test_C4a(C4 *c4) {
141  global_C4 = c4 = get_a_C4();
142  accept_a_C4(c4);
143}
144
145void test_ClassWithDef(ClassWithDef *cwd) {
146  [cwd method];
147}
148
149@import redecl_merge_bottom;
150
151void test_C4b() {
152  if (&refers_to_C4) {
153  }
154}
155
156@implementation B
157+ (B*)create_a_B { return 0; }
158@end
159
160void g(A *a) {
161  [a init];
162}
163
164@protocol P3
165- (void)p3_method;
166@end
167
168id<P4> p4;
169id<P3> p3;
170
171// Make sure we don't get conflicts with 'id'.
172funcptr_with_id fid;
173id id_global;
174
175
176