1 // RUN: rm -rf %t 2 // RUN: split-file %s %t 3 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 8 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 13 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 17 18 // Run test 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 21 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 28 // RUN: %{command} 29 // REDEFINE: %{macro_flag} = -DCASE2=1 30 // RUN: %{command} 31 // REDEFINE: %{macro_flag} = -DCASE3=1 32 // RUN: %{command} 33 34 // Run tests for anonymous nested structs and unions 35 // REDEFINE: %{filename} = test-anonymous.c 36 // REDEFINE: %{macro_flag} = -DCASE1=1 37 // RUN: %{command} 38 // REDEFINE: %{macro_flag} = -DCASE2=1 39 // RUN: %{command} 40 // REDEFINE: %{macro_flag} = -DCASE3=1 41 // RUN: %{command} 42 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 45 // diagnostic. 46 47 //--- include/first-empty.h 48 //--- include/module.modulemap 49 module First { 50 module Empty { 51 header "first-empty.h" 52 } 53 module Hidden { 54 header "first.h" 55 header "first-nested-struct.h" 56 header "first-anonymous.h" 57 export * 58 } 59 } 60 module Second { 61 header "second.h" 62 header "second-nested-struct.h" 63 header "second-anonymous.h" 64 export * 65 } 66 67 //--- test.c 68 #if !defined(FIRST) && !defined(SECOND) 69 # include "first-empty.h" 70 # include "second.h" 71 #endif 72 73 #if defined(FIRST) 74 struct CompareForwardDeclaration1; 75 struct CompareForwardDeclaration2 {}; 76 #elif defined(SECOND) 77 struct CompareForwardDeclaration1 {}; 78 struct CompareForwardDeclaration2; 79 #else 80 struct CompareForwardDeclaration1 *compareForwardDeclaration1; 81 struct CompareForwardDeclaration2 *compareForwardDeclaration2; 82 #endif 83 84 #if defined(FIRST) 85 struct CompareMatchingFields { 86 int matchingFieldName; 87 }; 88 89 struct CompareFieldPresence1 { 90 int fieldPresence1; 91 }; 92 struct CompareFieldPresence2 {}; 93 94 struct CompareFieldName { 95 int fieldNameA; 96 }; 97 98 struct CompareFieldOrder { 99 int fieldOrderX; 100 int fieldOrderY; 101 }; 102 #elif defined(SECOND) 103 struct CompareMatchingFields { 104 int matchingFieldName; 105 }; 106 107 struct CompareFieldPresence1 { 108 }; 109 struct CompareFieldPresence2 { 110 int fieldPresence2; 111 }; 112 113 struct CompareFieldName { 114 int fieldNameB; 115 }; 116 117 struct CompareFieldOrder { 118 int fieldOrderY; 119 int fieldOrderX; 120 }; 121 #else 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'}} 135 #endif 136 137 #if defined(FIRST) 138 struct CompareFieldType { 139 int fieldType; 140 }; 141 142 typedef int FieldTypedefNameA; 143 struct CompareFieldTypedefName { 144 FieldTypedefNameA fieldTypedefName; 145 }; 146 147 typedef int TypedefUnderlyingType; 148 struct CompareFieldTypeUnderlyingTypedef { 149 TypedefUnderlyingType fieldTypeUnderlyingTypedef; 150 }; 151 152 typedef int TypedefFinal; 153 struct CompareFieldTypedefChain { 154 TypedefFinal fieldTypeTypedefChain; 155 }; 156 #elif defined(SECOND) 157 struct CompareFieldType { 158 float fieldType; 159 }; 160 161 typedef int FieldTypedefNameB; 162 struct CompareFieldTypedefName { 163 FieldTypedefNameB fieldTypedefName; 164 }; 165 166 struct CompareFieldTypeUnderlyingTypedef { 167 int fieldTypeUnderlyingTypedef; 168 }; 169 170 typedef int TypedefIntermediate; 171 typedef TypedefIntermediate TypedefFinal; 172 struct CompareFieldTypedefChain { 173 TypedefFinal fieldTypeTypedefChain; 174 }; 175 #else 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; 186 #endif 187 188 #if defined(FIRST) 189 struct CompareMatchingBitfields { 190 unsigned matchingBitfields : 3; 191 }; 192 193 struct CompareBitfieldPresence1 { 194 unsigned bitfieldPresence1 : 1; 195 }; 196 struct CompareBitfieldPresence2 { 197 unsigned bitfieldPresence2; 198 }; 199 200 struct CompareBitfieldWidth { 201 unsigned bitfieldWidth : 2; 202 }; 203 204 struct CompareBitfieldWidthExpression { 205 unsigned bitfieldWidthExpression : 1 + 1; 206 }; 207 #elif defined(SECOND) 208 struct CompareMatchingBitfields { 209 unsigned matchingBitfields : 3; 210 }; 211 212 struct CompareBitfieldPresence1 { 213 unsigned bitfieldPresence1; 214 }; 215 struct CompareBitfieldPresence2 { 216 unsigned bitfieldPresence2 : 1; 217 }; 218 219 struct CompareBitfieldWidth { 220 unsigned bitfieldWidth : 1; 221 }; 222 223 struct CompareBitfieldWidthExpression { 224 unsigned bitfieldWidthExpression : 2; 225 }; 226 #else 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 bit-field 'bitfieldPresence1'}} 230 // expected-note@second.h:* {{but in 'Second' found non-bit-field '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-bit-field 'bitfieldPresence2'}} 233 // expected-note@second.h:* {{but in 'Second' found bit-field '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 bit-field 'bitfieldWidth' with one width expression}} 236 // expected-note@second.h:* {{but in 'Second' found bit-field '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 bit-field 'bitfieldWidthExpression' with one width expression}} 239 // expected-note@second.h:* {{but in 'Second' found bit-field 'bitfieldWidthExpression' with different width expressio}} 240 #endif 241 242 #if defined(FIRST) 243 struct CompareMatchingArrayFields { 244 int matchingArrayField[7]; 245 }; 246 247 struct CompareArrayLength { 248 int arrayLengthField[5]; 249 }; 250 251 struct CompareArrayType { 252 int arrayTypeField[5]; 253 }; 254 #elif defined(SECOND) 255 struct CompareMatchingArrayFields { 256 int matchingArrayField[7]; 257 }; 258 259 struct CompareArrayLength { 260 int arrayLengthField[7]; 261 }; 262 263 struct CompareArrayType { 264 float arrayTypeField[5]; 265 }; 266 #else 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}} 274 #endif 275 276 #if defined(FIRST) 277 struct CompareFieldAsForwardDeclaration { 278 struct FieldForwardDeclaration *fieldForwardDeclaration; 279 }; 280 281 enum FieldEnumA { kFieldEnumValue }; 282 struct CompareFieldAsEnum { 283 enum FieldEnumA fieldEnum; 284 }; 285 286 struct FieldStructA {}; 287 struct CompareFieldAsStruct { 288 struct FieldStructA fieldStruct; 289 }; 290 #elif defined(SECOND) 291 struct FieldForwardDeclaration {}; 292 struct CompareFieldAsForwardDeclaration { 293 struct FieldForwardDeclaration *fieldForwardDeclaration; 294 }; 295 296 enum FieldEnumB { kFieldEnumValue }; 297 struct CompareFieldAsEnum { 298 enum FieldEnumB fieldEnum; 299 }; 300 301 struct FieldStructB {}; 302 struct CompareFieldAsStruct { 303 struct FieldStructB fieldStruct; 304 }; 305 #else 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}} 313 #endif 314 315 #if defined(FIRST) 316 union CompareMatchingUnionFields { 317 int matchingFieldA; 318 float matchingFieldB; 319 }; 320 321 union CompareUnionFieldOrder { 322 int unionFieldOrderA; 323 float unionFieldOrderB; 324 }; 325 326 union CompareUnionFieldType { 327 int unionFieldType; 328 }; 329 #elif defined(SECOND) 330 union CompareMatchingUnionFields { 331 int matchingFieldA; 332 float matchingFieldB; 333 }; 334 335 union CompareUnionFieldOrder { 336 float unionFieldOrderB; 337 int unionFieldOrderA; 338 }; 339 340 union CompareUnionFieldType { 341 unsigned int unionFieldType; 342 }; 343 #else 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}} 351 #endif 352 353 // Test that we find and compare definitions even if they are not the first encountered declaration in a module. 354 #if defined(FIRST) 355 struct CompareDefinitionsRegardlessForwardDeclarations { 356 int definitionField; 357 }; 358 #elif defined(SECOND) 359 struct CompareDefinitionsRegardlessForwardDeclarations; 360 struct CompareDefinitionsRegardlessForwardDeclarations { 361 float definitionField; 362 }; 363 #else 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}} 367 #endif 368 369 //--- include/first-nested-struct.h 370 struct CompareNestedStruct { 371 struct NestedLevel1 { 372 struct NestedLevel2 { 373 int a; 374 } y; 375 } x; 376 }; 377 378 struct IndirectStruct { 379 int mismatchingField; 380 }; 381 struct DirectStruct { 382 struct IndirectStruct indirectField; 383 }; 384 struct CompareDifferentFieldInIndirectStruct { 385 struct DirectStruct directField; 386 }; 387 struct CompareIndirectStructPointer { 388 struct DirectStruct *directFieldPointer; 389 }; 390 391 //--- include/second-nested-struct.h 392 struct CompareNestedStruct { 393 struct NestedLevel1 { 394 struct NestedLevel2 { 395 float b; 396 } y; 397 } x; 398 }; 399 400 struct IndirectStruct { 401 float mismatchingField; 402 }; 403 struct DirectStruct { 404 struct IndirectStruct indirectField; 405 }; 406 struct CompareDifferentFieldInIndirectStruct { 407 struct DirectStruct directField; 408 }; 409 struct CompareIndirectStructPointer { 410 struct DirectStruct *directFieldPointer; 411 }; 412 413 //--- test-nested-struct.c 414 #include "first-empty.h" 415 #include "second-nested-struct.h" 416 417 #if defined(CASE1) 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'}} 421 #elif defined(CASE2) 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}} 425 #elif defined(CASE3) 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; 432 } 433 #endif 434 435 //--- include/first-anonymous.h 436 struct CompareAnonymousNestedUnion { 437 union { 438 int anonymousNestedUnionField; 439 }; 440 }; 441 442 struct CompareAnonymousNestedStruct { 443 struct { 444 int anonymousNestedStructField; 445 }; 446 }; 447 448 struct CompareDeeplyNestedAnonymousUnionsAndStructs { 449 union { 450 int x; 451 union { 452 int y; 453 struct { 454 int z; 455 }; 456 }; 457 }; 458 }; 459 460 //--- include/second-anonymous.h 461 struct CompareAnonymousNestedUnion { 462 union { 463 float anonymousNestedUnionField; 464 }; 465 }; 466 467 struct CompareAnonymousNestedStruct { 468 struct { 469 float anonymousNestedStructField; 470 }; 471 }; 472 473 struct CompareDeeplyNestedAnonymousUnionsAndStructs { 474 union { 475 int x; 476 union { 477 int y; 478 struct { 479 float z; 480 }; 481 }; 482 }; 483 }; 484 485 //--- test-anonymous.c 486 #include "first-empty.h" 487 #include "second-anonymous.h" 488 489 #if defined(CASE1) 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}} 493 #elif defined(CASE2) 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}} 497 #elif defined(CASE3) 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}} 501 #endif 502