2 // RUN: split-file %s %t
4 // Build first header file
5 // RUN: echo "#define FIRST" >> %t/include/first.h
6 // RUN: cat %t/test.c >> %t/include/first.h
7 // RUN: echo "#undef FIRST" >> %t/include/first.h
9 // Build second header file
10 // RUN: echo "#define SECOND" >> %t/include/second.h
11 // RUN: cat %t/test.c >> %t/include/second.h
12 // RUN: echo "#undef SECOND" >> %t/include/second.h
14 // Test that each header can compile
15 // RUN: %clang_cc1 -fsyntax-only -x objective-c %t/include/first.h -fblocks -fobjc-arc
16 // RUN: %clang_cc1 -fsyntax-only -x objective-c %t/include/second.h -fblocks -fobjc-arc
19 // RUN: %clang_cc1 -I%t/include -verify %t/test.c -fblocks -fobjc-arc \
20 // RUN: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache
22 // Run tests for nested structs
23 // DEFINE: %{filename} = test-nested-struct.c
24 // DEFINE: %{macro_flag} = -DCASE1=1
25 // DEFINE: %{command} = %clang_cc1 -I%t/include -verify %t/%{filename} -fblocks -fobjc-arc \
26 // DEFINE: -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/modules.cache \
27 // DEFINE: %{macro_flag} -emit-llvm -o %t/%{filename}.bc
29 // REDEFINE: %{macro_flag} = -DCASE2=1
31 // REDEFINE: %{macro_flag} = -DCASE3=1
34 // Run tests for anonymous nested structs and unions
35 // REDEFINE: %{filename} = test-anonymous.c
36 // REDEFINE: %{macro_flag} = -DCASE1=1
38 // REDEFINE: %{macro_flag} = -DCASE2=1
40 // REDEFINE: %{macro_flag} = -DCASE3=1
43 // Test that we don't accept different structs and unions with the same name
44 // from multiple modules but detect mismatches and provide actionable
47 //--- include/first-empty.h
48 //--- include/module.modulemap
51 header
"first-empty.h"
55 header
"first-nested-struct.h"
56 header
"first-anonymous.h"
62 header
"second-nested-struct.h"
63 header
"second-anonymous.h"
68 #if !defined(FIRST) && !defined(SECOND)
69 # include "first-empty.h"
74 struct CompareForwardDeclaration1
;
75 struct CompareForwardDeclaration2
{};
77 struct CompareForwardDeclaration1
{};
78 struct CompareForwardDeclaration2
;
80 struct CompareForwardDeclaration1
*compareForwardDeclaration1
;
81 struct CompareForwardDeclaration2
*compareForwardDeclaration2
;
85 struct CompareMatchingFields
{
86 int matchingFieldName
;
89 struct CompareFieldPresence1
{
92 struct CompareFieldPresence2
{};
94 struct CompareFieldName
{
98 struct CompareFieldOrder
{
102 #elif defined(SECOND)
103 struct CompareMatchingFields
{
104 int matchingFieldName
;
107 struct CompareFieldPresence1
{
109 struct CompareFieldPresence2
{
113 struct CompareFieldName
{
117 struct CompareFieldOrder
{
122 struct CompareMatchingFields compareMatchingFields
;
123 struct CompareFieldPresence1 compareFieldPresence1
;
124 // expected-error@first.h:* {{'CompareFieldPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found field}}
125 // expected-note@second.h:* {{but in 'Second' found end of class}}
126 struct CompareFieldPresence2 compareFieldPresence2
;
127 // expected-error@second.h:* {{'CompareFieldPresence2::fieldPresence2' from module 'Second' is not present in definition of 'struct CompareFieldPresence2' in module 'First.Hidden'}}
128 // expected-note@first.h:* {{definition has no member 'fieldPresence2'}}
129 struct CompareFieldName compareFieldName
;
130 // expected-error@second.h:* {{'CompareFieldName::fieldNameB' from module 'Second' is not present in definition of 'struct CompareFieldName' in module 'First.Hidden'}}
131 // expected-note@first.h:* {{definition has no member 'fieldNameB'}}
132 struct CompareFieldOrder compareFieldOrder
;
133 // expected-error@first.h:* {{'CompareFieldOrder' has different definitions in different modules; first difference is definition in module 'First.Hidden' found field 'fieldOrderX'}}
134 // expected-note@second.h:* {{but in 'Second' found field 'fieldOrderY'}}
138 struct CompareFieldType
{
142 typedef int FieldTypedefNameA
;
143 struct CompareFieldTypedefName
{
144 FieldTypedefNameA fieldTypedefName
;
147 typedef int TypedefUnderlyingType
;
148 struct CompareFieldTypeUnderlyingTypedef
{
149 TypedefUnderlyingType fieldTypeUnderlyingTypedef
;
152 typedef int TypedefFinal
;
153 struct CompareFieldTypedefChain
{
154 TypedefFinal fieldTypeTypedefChain
;
156 #elif defined(SECOND)
157 struct CompareFieldType
{
161 typedef int FieldTypedefNameB
;
162 struct CompareFieldTypedefName
{
163 FieldTypedefNameB fieldTypedefName
;
166 struct CompareFieldTypeUnderlyingTypedef
{
167 int fieldTypeUnderlyingTypedef
;
170 typedef int TypedefIntermediate
;
171 typedef TypedefIntermediate TypedefFinal
;
172 struct CompareFieldTypedefChain
{
173 TypedefFinal fieldTypeTypedefChain
;
176 struct CompareFieldType compareFieldType
;
177 // expected-error@second.h:* {{'CompareFieldType::fieldType' from module 'Second' is not present in definition of 'struct CompareFieldType' in module 'First.Hidden'}}
178 // expected-note@first.h:* {{declaration of 'fieldType' does not match}}
179 struct CompareFieldTypedefName compareFieldTypedefName
;
180 // expected-error@first.h:* {{'CompareFieldTypedefName' has different definitions in different modules; first difference is definition in module 'First.Hidden' found field 'fieldTypedefName' with type 'FieldTypedefNameA' (aka 'int')}}
181 // expected-note@second.h:* {{but in 'Second' found field 'fieldTypedefName' with type 'FieldTypedefNameB' (aka 'int')}}
182 struct CompareFieldTypeUnderlyingTypedef compareFieldTypeUnderlyingTypedef
;
183 // expected-error@first.h:* {{'CompareFieldTypeUnderlyingTypedef' has different definitions in different modules; first difference is definition in module 'First.Hidden' found field 'fieldTypeUnderlyingTypedef' with type 'TypedefUnderlyingType' (aka 'int')}}
184 // expected-note@second.h:* {{but in 'Second' found field 'fieldTypeUnderlyingTypedef' with type 'int'}}
185 struct CompareFieldTypedefChain compareFieldTypedefChain
;
189 struct CompareMatchingBitfields
{
190 unsigned matchingBitfields
: 3;
193 struct CompareBitfieldPresence1
{
194 unsigned bitfieldPresence1
: 1;
196 struct CompareBitfieldPresence2
{
197 unsigned bitfieldPresence2
;
200 struct CompareBitfieldWidth
{
201 unsigned bitfieldWidth
: 2;
204 struct CompareBitfieldWidthExpression
{
205 unsigned bitfieldWidthExpression
: 1 + 1;
207 #elif defined(SECOND)
208 struct CompareMatchingBitfields
{
209 unsigned matchingBitfields
: 3;
212 struct CompareBitfieldPresence1
{
213 unsigned bitfieldPresence1
;
215 struct CompareBitfieldPresence2
{
216 unsigned bitfieldPresence2
: 1;
219 struct CompareBitfieldWidth
{
220 unsigned bitfieldWidth
: 1;
223 struct CompareBitfieldWidthExpression
{
224 unsigned bitfieldWidthExpression
: 2;
227 struct CompareMatchingBitfields compareMatchingBitfields
;
228 struct CompareBitfieldPresence1 compareBitfieldPresence1
;
229 // expected-error@first.h:* {{'CompareBitfieldPresence1' has different definitions in different modules; first difference is definition in module 'First.Hidden' found bitfield 'bitfieldPresence1'}}
230 // expected-note@second.h:* {{but in 'Second' found non-bitfield 'bitfieldPresence1'}}
231 struct CompareBitfieldPresence2 compareBitfieldPresence2
;
232 // expected-error@first.h:* {{'CompareBitfieldPresence2' has different definitions in different modules; first difference is definition in module 'First.Hidden' found non-bitfield 'bitfieldPresence2'}}
233 // expected-note@second.h:* {{but in 'Second' found bitfield 'bitfieldPresence2'}}
234 struct CompareBitfieldWidth compareBitfieldWidth
;
235 // expected-error@first.h:* {{'CompareBitfieldWidth' has different definitions in different modules; first difference is definition in module 'First.Hidden' found bitfield 'bitfieldWidth' with one width expression}}
236 // expected-note@second.h:* {{but in 'Second' found bitfield 'bitfieldWidth' with different width expression}}
237 struct CompareBitfieldWidthExpression compareBitfieldWidthExpression
;
238 // expected-error@first.h:* {{'CompareBitfieldWidthExpression' has different definitions in different modules; first difference is definition in module 'First.Hidden' found bitfield 'bitfieldWidthExpression' with one width expression}}
239 // expected-note@second.h:* {{but in 'Second' found bitfield 'bitfieldWidthExpression' with different width expressio}}
243 struct CompareMatchingArrayFields
{
244 int matchingArrayField
[7];
247 struct CompareArrayLength
{
248 int arrayLengthField
[5];
251 struct CompareArrayType
{
252 int arrayTypeField
[5];
254 #elif defined(SECOND)
255 struct CompareMatchingArrayFields
{
256 int matchingArrayField
[7];
259 struct CompareArrayLength
{
260 int arrayLengthField
[7];
263 struct CompareArrayType
{
264 float arrayTypeField
[5];
267 struct CompareMatchingArrayFields compareMatchingArrayFields
;
268 struct CompareArrayLength compareArrayLength
;
269 // expected-error@second.h:* {{'CompareArrayLength::arrayLengthField' from module 'Second' is not present in definition of 'struct CompareArrayLength' in module 'First.Hidden'}}
270 // expected-note@first.h:* {{declaration of 'arrayLengthField' does not match}}
271 struct CompareArrayType compareArrayType
;
272 // expected-error@second.h:* {{'CompareArrayType::arrayTypeField' from module 'Second' is not present in definition of 'struct CompareArrayType' in module 'First.Hidden'}}
273 // expected-note@first.h:* {{declaration of 'arrayTypeField' does not match}}
277 struct CompareFieldAsForwardDeclaration
{
278 struct FieldForwardDeclaration
*fieldForwardDeclaration
;
281 enum FieldEnumA
{ kFieldEnumValue
};
282 struct CompareFieldAsEnum
{
283 enum FieldEnumA fieldEnum
;
286 struct FieldStructA
{};
287 struct CompareFieldAsStruct
{
288 struct FieldStructA fieldStruct
;
290 #elif defined(SECOND)
291 struct FieldForwardDeclaration
{};
292 struct CompareFieldAsForwardDeclaration
{
293 struct FieldForwardDeclaration
*fieldForwardDeclaration
;
296 enum FieldEnumB
{ kFieldEnumValue
};
297 struct CompareFieldAsEnum
{
298 enum FieldEnumB fieldEnum
;
301 struct FieldStructB
{};
302 struct CompareFieldAsStruct
{
303 struct FieldStructB fieldStruct
;
306 struct CompareFieldAsForwardDeclaration compareFieldAsForwardDeclaration
;
307 struct CompareFieldAsEnum compareFieldAsEnum
;
308 // expected-error@second.h:* {{'CompareFieldAsEnum::fieldEnum' from module 'Second' is not present in definition of 'struct CompareFieldAsEnum' in module 'First.Hidden'}}
309 // expected-note@first.h:* {{declaration of 'fieldEnum' does not match}}
310 struct CompareFieldAsStruct compareFieldAsStruct
;
311 // expected-error@second.h:* {{'CompareFieldAsStruct::fieldStruct' from module 'Second' is not present in definition of 'struct CompareFieldAsStruct' in module 'First.Hidden'}}
312 // expected-note@first.h:* {{declaration of 'fieldStruct' does not match}}
316 union CompareMatchingUnionFields
{
318 float matchingFieldB
;
321 union CompareUnionFieldOrder
{
322 int unionFieldOrderA
;
323 float unionFieldOrderB
;
326 union CompareUnionFieldType
{
329 #elif defined(SECOND)
330 union CompareMatchingUnionFields
{
332 float matchingFieldB
;
335 union CompareUnionFieldOrder
{
336 float unionFieldOrderB
;
337 int unionFieldOrderA
;
340 union CompareUnionFieldType
{
341 unsigned int unionFieldType
;
344 union CompareMatchingUnionFields compareMatchingUnionFields
;
345 union CompareUnionFieldOrder compareUnionFieldOrder
;
346 // expected-error@first.h:* {{'CompareUnionFieldOrder' has different definitions in different modules; first difference is definition in module 'First.Hidden' found field 'unionFieldOrderA'}}
347 // expected-note@second.h:* {{but in 'Second' found field 'unionFieldOrderB'}}
348 union CompareUnionFieldType compareUnionFieldType
;
349 // expected-error@second.h:* {{'CompareUnionFieldType::unionFieldType' from module 'Second' is not present in definition of 'union CompareUnionFieldType' in module 'First.Hidden'}}
350 // expected-note@first.h:* {{declaration of 'unionFieldType' does not match}}
353 // Test that we find and compare definitions even if they are not the first encountered declaration in a module.
355 struct CompareDefinitionsRegardlessForwardDeclarations
{
358 #elif defined(SECOND)
359 struct CompareDefinitionsRegardlessForwardDeclarations
;
360 struct CompareDefinitionsRegardlessForwardDeclarations
{
361 float definitionField
;
364 struct CompareDefinitionsRegardlessForwardDeclarations compareDefinitions
;
365 // expected-error@second.h:* {{'CompareDefinitionsRegardlessForwardDeclarations::definitionField' from module 'Second' is not present in definition of 'struct CompareDefinitionsRegardlessForwardDeclarations' in module 'First.Hidden'}}
366 // expected-note@first.h:* {{declaration of 'definitionField' does not match}}
369 //--- include/first-nested-struct.h
370 struct CompareNestedStruct
{
371 struct NestedLevel1
{
372 struct NestedLevel2
{
378 struct IndirectStruct
{
379 int mismatchingField
;
381 struct DirectStruct
{
382 struct IndirectStruct indirectField
;
384 struct CompareDifferentFieldInIndirectStruct
{
385 struct DirectStruct directField
;
387 struct CompareIndirectStructPointer
{
388 struct DirectStruct
*directFieldPointer
;
391 //--- include/second-nested-struct.h
392 struct CompareNestedStruct
{
393 struct NestedLevel1
{
394 struct NestedLevel2
{
400 struct IndirectStruct
{
401 float mismatchingField
;
403 struct DirectStruct
{
404 struct IndirectStruct indirectField
;
406 struct CompareDifferentFieldInIndirectStruct
{
407 struct DirectStruct directField
;
409 struct CompareIndirectStructPointer
{
410 struct DirectStruct
*directFieldPointer
;
413 //--- test-nested-struct.c
414 #include "first-empty.h"
415 #include "second-nested-struct.h"
418 struct CompareNestedStruct compareNestedStruct
;
419 // expected-error@second-nested-struct.h:* {{'NestedLevel2::b' from module 'Second' is not present in definition of 'struct NestedLevel2' in module 'First.Hidden'}}
420 // expected-note@first-nested-struct.h:* {{definition has no member 'b'}}
422 struct CompareDifferentFieldInIndirectStruct compareIndirectStruct
;
423 // expected-error@second-nested-struct.h:* {{'IndirectStruct::mismatchingField' from module 'Second' is not present in definition of 'struct IndirectStruct' in module 'First.Hidden'}}
424 // expected-note@first-nested-struct.h:* {{declaration of 'mismatchingField' does not match}}
426 // expected-error@second-nested-struct.h:* {{'IndirectStruct::mismatchingField' from module 'Second' is not present in definition of 'struct IndirectStruct' in module 'First.Hidden'}}
427 // expected-note@first-nested-struct.h:* {{declaration of 'mismatchingField' does not match}}
428 struct CompareIndirectStructPointer compareIndirectStructPointer
;
429 struct DirectStruct
test() {
430 // Make sure the type behind the pointer is inspected.
431 return *compareIndirectStructPointer
.directFieldPointer
;
435 //--- include/first-anonymous.h
436 struct CompareAnonymousNestedUnion
{
438 int anonymousNestedUnionField
;
442 struct CompareAnonymousNestedStruct
{
444 int anonymousNestedStructField
;
448 struct CompareDeeplyNestedAnonymousUnionsAndStructs
{
460 //--- include/second-anonymous.h
461 struct CompareAnonymousNestedUnion
{
463 float anonymousNestedUnionField
;
467 struct CompareAnonymousNestedStruct
{
469 float anonymousNestedStructField
;
473 struct CompareDeeplyNestedAnonymousUnionsAndStructs
{
485 //--- test-anonymous.c
486 #include "first-empty.h"
487 #include "second-anonymous.h"
490 struct CompareAnonymousNestedUnion compareAnonymousNestedUnion
;
491 // expected-error-re@second-anonymous.h:* {{'CompareAnonymousNestedUnion::(anonymous union)::anonymousNestedUnionField' from module 'Second' is not present in definition of 'union CompareAnonymousNestedUnion::(anonymous at {{.*}})' in module 'First.Hidden'}}
492 // expected-note@first-anonymous.h:* {{declaration of 'anonymousNestedUnionField' does not match}}
494 struct CompareAnonymousNestedStruct compareAnonymousNestedStruct
;
495 // expected-error-re@second-anonymous.h:* {{'CompareAnonymousNestedStruct::(anonymous struct)::anonymousNestedStructField' from module 'Second' is not present in definition of 'struct CompareAnonymousNestedStruct::(anonymous at {{.*}})' in module 'First.Hidden'}}
496 // expected-note@first-anonymous.h:* {{declaration of 'anonymousNestedStructField' does not match}}
498 struct CompareDeeplyNestedAnonymousUnionsAndStructs compareDeeplyNested
;
499 // expected-error-re@second-anonymous.h:* {{'CompareDeeplyNestedAnonymousUnionsAndStructs::(anonymous union)::(anonymous union)::(anonymous struct)::z' from module 'Second' is not present in definition of 'struct CompareDeeplyNestedAnonymousUnionsAndStructs::(anonymous at {{.*}})' in module 'First.Hidden'}}
500 // expected-note@first-anonymous.h:* {{declaration of 'z' does not match}}