diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/CodeGenCXX/debug-info-namespace.cpp | 6 | ||||
-rw-r--r-- | test/Modules/Inputs/module.map | 4 | ||||
-rw-r--r-- | test/Modules/Inputs/objcAtKeywordMissingEnd.h | 3 | ||||
-rw-r--r-- | test/Modules/Inputs/submodule-visibility/b.h | 6 | ||||
-rw-r--r-- | test/Modules/Inputs/submodule-visibility/other.h | 9 | ||||
-rw-r--r-- | test/Modules/objc-at-keyword.m | 7 | ||||
-rw-r--r-- | test/Modules/odr_hash.cpp | 231 | ||||
-rw-r--r-- | test/Modules/submodule-visibility.cpp | 9 |
8 files changed, 274 insertions, 1 deletions
diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp index 5b81197671e2..95857e339085 100644 --- a/test/CodeGenCXX/debug-info-namespace.cpp +++ b/test/CodeGenCXX/debug-info-namespace.cpp @@ -60,6 +60,10 @@ void B::func_fwd() { anonymous = 0; } +namespace C { + void c(); +} +void C::c() {} // This should work even if 'i' and 'func' were declarations & not definitions, // but it doesn't yet. @@ -114,6 +118,8 @@ void B::func_fwd() { // CHECK: [[M16]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FUNC_FWD:![0-9]+]] // CHECK: [[FUNC_FWD]] = distinct !DISubprogram(name: "func_fwd",{{.*}} line: 53,{{.*}} isDefinition: true // CHECK: [[M17]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CTXT]], entity: [[I]] +// CHECK: distinct !DISubprogram(name: "c",{{.*}}, scope: ![[C:[0-9]+]],{{.*}}, line: 60,{{.*}} isDefinition: true +// CHECK: ![[C]] = !DINamespace(name: "C", // CHECK-GMLT: [[CU:![0-9]+]] = distinct !DICompileUnit( // CHECK-GMLT-SAME: emissionKind: LineTablesOnly, diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map index 7416d7008b85..c0fe6c557f22 100644 --- a/test/Modules/Inputs/module.map +++ b/test/Modules/Inputs/module.map @@ -441,3 +441,7 @@ module DebugNestedB { header "DebugNestedB.h" export * } + +module objcAtKeywordMissingEnd { + header "objcAtKeywordMissingEnd.h" +} diff --git a/test/Modules/Inputs/objcAtKeywordMissingEnd.h b/test/Modules/Inputs/objcAtKeywordMissingEnd.h new file mode 100644 index 000000000000..1196b87eef8e --- /dev/null +++ b/test/Modules/Inputs/objcAtKeywordMissingEnd.h @@ -0,0 +1,3 @@ +@interface MissingEnd // expected-note {{class started here}} + +@ // expected-error {{expected an Objective-C directive after '@'}} expected-error {{missing '@end'}} diff --git a/test/Modules/Inputs/submodule-visibility/b.h b/test/Modules/Inputs/submodule-visibility/b.h index 67ef6529dbd8..39df6a02cb40 100644 --- a/test/Modules/Inputs/submodule-visibility/b.h +++ b/test/Modules/Inputs/submodule-visibility/b.h @@ -4,7 +4,11 @@ int m = n; #include "c.h" #if defined(A) && !defined(ALLOW_NAME_LEAKAGE) -#error A is defined +#warning A is defined #endif #define B + +template<typename T> void b_template() { + N::C::f(0); +} diff --git a/test/Modules/Inputs/submodule-visibility/other.h b/test/Modules/Inputs/submodule-visibility/other.h index f40c757ca62e..4b68c489153c 100644 --- a/test/Modules/Inputs/submodule-visibility/other.h +++ b/test/Modules/Inputs/submodule-visibility/other.h @@ -1 +1,10 @@ #include "c.h" + +#ifndef OTHER_H +#define OTHER_H +namespace N { + struct C { + template<typename U> static void f(U) {} + }; +} +#endif diff --git a/test/Modules/objc-at-keyword.m b/test/Modules/objc-at-keyword.m new file mode 100644 index 000000000000..0e058a309017 --- /dev/null +++ b/test/Modules/objc-at-keyword.m @@ -0,0 +1,7 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -verify -x objective-c -fmodule-name=objcAtKeywordMissingEnd -emit-module %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=Empty -emit-module %S/Inputs/module.map +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -verify -I %S/Inputs %s + +@interface X // expected-note {{class started here}} +#pragma clang module import Empty // expected-error {{missing '@end'}} diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp index 58814dd6b3fb..947583bcfd21 100644 --- a/test/Modules/odr_hash.cpp +++ b/test/Modules/odr_hash.cpp @@ -634,6 +634,237 @@ S3 s3; #endif } // namespace Using +namespace RecordType { +#if defined(FIRST) +struct B1 {}; +struct S1 { + B1 x; +}; +#elif defined(SECOND) +struct A1 {}; +struct S1 { + A1 x; +}; +#else +S1 s1; +// expected-error@first.h:* {{'RecordType::S1::x' from module 'FirstModule' is not present in definition of 'RecordType::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif +} + +namespace DependentType { +#if defined(FIRST) +template <class T> +class S1 { + typename T::typeA x; +}; +#elif defined(SECOND) +template <class T> +class S1 { + typename T::typeB x; +}; +#else +template<class T> +using U1 = S1<T>; +// expected-error@first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T>' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif +} + +namespace ElaboratedType { +#if defined(FIRST) +namespace N1 { using type = double; } +struct S1 { + N1::type x; +}; +#elif defined(SECOND) +namespace N1 { using type = int; } +struct S1 { + N1::type x; +}; +#else +S1 s1; +// expected-error@first.h:* {{'ElaboratedType::S1::x' from module 'FirstModule' is not present in definition of 'ElaboratedType::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif +} + +namespace Enum { +#if defined(FIRST) +enum A1 {}; +struct S1 { + A1 x; +}; +#elif defined(SECOND) +enum A2 {}; +struct S1 { + A2 x; +}; +#else +S1 s1; +// expected-error@first.h:* {{'Enum::S1::x' from module 'FirstModule' is not present in definition of 'Enum::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif +} + +namespace NestedNamespaceSpecifier { +#if defined(FIRST) +namespace LevelA1 { +using Type = int; +} + +struct S1 { + LevelA1::Type x; +}; +# elif defined(SECOND) +namespace LevelB1 { +namespace LevelC1 { +using Type = int; +} +} + +struct S1 { + LevelB1::LevelC1::Type x; +}; +#else +S1 s1; +// expected-error@second.h:* {{'NestedNamespaceSpecifier::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'LevelB1::LevelC1::Type' (aka 'int')}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA1::Type' (aka 'int')}} +#endif + +#if defined(FIRST) +namespace LevelA2 { using Type = int; } +struct S2 { + LevelA2::Type x; +}; +# elif defined(SECOND) +struct S2 { + int x; +}; +#else +S2 s2; +// expected-error@second.h:* {{'NestedNamespaceSpecifier::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'int'}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA2::Type' (aka 'int')}} +#endif + +namespace LevelA3 { using Type = int; } +namespace LevelB3 { using Type = int; } +#if defined(FIRST) +struct S3 { + LevelA3::Type x; +}; +# elif defined(SECOND) +struct S3 { + LevelB3::Type x; +}; +#else +S3 s3; +// expected-error@second.h:* {{'NestedNamespaceSpecifier::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'LevelB3::Type' (aka 'int')}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'LevelA3::Type' (aka 'int')}} +#endif + +#if defined(FIRST) +struct TA4 { using Type = int; }; +struct S4 { + TA4::Type x; +}; +# elif defined(SECOND) +struct TB4 { using Type = int; }; +struct S4 { + TB4::Type x; +}; +#else +S4 s4; +// expected-error@second.h:* {{'NestedNamespaceSpecifier::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'TB4::Type' (aka 'int')}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'TA4::Type' (aka 'int')}} +#endif + +#if defined(FIRST) +struct T5 { using Type = int; }; +struct S5 { + T5::Type x; +}; +# elif defined(SECOND) +namespace T5 { using Type = int; }; +struct S5 { + T5::Type x; +}; +#else +S5 s5; +// expected-error@second.h:* {{'NestedNamespaceSpecifier::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'T5::Type' (aka 'int')}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'T5::Type' (aka 'int')}} +#endif + +#if defined(FIRST) +namespace N6 {using I = int;} +struct S6 { + NestedNamespaceSpecifier::N6::I x; +}; +# elif defined(SECOND) +using I = int; +struct S6 { + ::NestedNamespaceSpecifier::I x; +}; +#else +S6 s6; +// expected-error@second.h:* {{'NestedNamespaceSpecifier::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type '::NestedNamespaceSpecifier::I' (aka 'int')}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'NestedNamespaceSpecifier::N6::I' (aka 'int')}} +#endif + +#if defined(FIRST) +template <class T, class U> +class S7 { + typename T::type *x = {}; + int z = x->T::foo(); +}; +#elif defined(SECOND) +template <class T, class U> +class S7 { + typename T::type *x = {}; + int z = x->U::foo(); +}; +#else +template <class T, class U> +using U7 = S7<T, U>; +// expected-error@second.h:* {{'NestedNamespaceSpecifier::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'z' with an initializer}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'z' with a different initializer}} +#endif + +#if defined(FIRST) +template <class T> +class S8 { + int x = T::template X<int>::value; +}; +#elif defined(SECOND) +template <class T> +class S8 { + int x = T::template Y<int>::value; +}; +#else +template <class T> +using U8 = S8<T>; +// expected-error@second.h:* {{'NestedNamespaceSpecifier::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with an initializer}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}} +#endif + +#if defined(FIRST) +namespace N9 { using I = int; } +namespace O9 = N9; +struct S9 { + O9::I x; +}; +#elif defined(SECOND) +namespace N9 { using I = int; } +namespace P9 = N9; +struct S9 { + P9::I x; +}; +#else +S9 s9; +// expected-error@second.h:* {{'NestedNamespaceSpecifier::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with type 'P9::I' (aka 'int')}} +// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'O9::I' (aka 'int')}} +#endif +} // Interesting cases that should not cause errors. struct S should not error // while struct T should error at the access specifier mismatch at the end. diff --git a/test/Modules/submodule-visibility.cpp b/test/Modules/submodule-visibility.cpp index 345ae155bb32..4c066e6ab9b0 100644 --- a/test/Modules/submodule-visibility.cpp +++ b/test/Modules/submodule-visibility.cpp @@ -3,6 +3,11 @@ // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-local-submodule-visibility -fmodules-cache-path=%t -I%S/Inputs/submodule-visibility -verify %s -DIMPORT // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-local-submodule-visibility -fmodules-cache-path=%t -fmodule-name=x -I%S/Inputs/submodule-visibility -verify %s // RUN: %clang_cc1 -fimplicit-module-maps -fmodules-local-submodule-visibility -fmodules-cache-path=%t -I%S/Inputs/submodule-visibility -verify %s +// +// Explicit module builds. +// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -emit-module -x c++-module-map %S/Inputs/submodule-visibility/module.modulemap -fmodule-name=other -o %t/other.pcm +// RUN: %clang_cc1 -fmodules -fmodule-map-file=%S/Inputs/submodule-visibility/module.modulemap -fmodules-local-submodule-visibility -fmodule-file=%t/other.pcm -verify -fmodule-name=x -I%S/Inputs/submodule-visibility %s +// RUN: %clang_cc1 -fmodules -fmodule-map-file=%S/Inputs/submodule-visibility/module.modulemap -fmodule-file=%t/other.pcm -verify -fmodule-name=x -I%S/Inputs/submodule-visibility %s -DALLOW_TEXTUAL_NAME_LEAKAGE #include "a.h" #include "b.h" @@ -11,6 +16,8 @@ // expected-no-diagnostics #elif IMPORT // expected-error@-6 {{could not build module 'x'}} +#elif ALLOW_TEXTUAL_NAME_LEAKAGE +// expected-warning@b.h:7 {{A is defined}} #else // The use of -fmodule-name=x causes us to textually include the above headers. // The submodule visibility rules are still applied in this case. @@ -35,3 +42,5 @@ typedef struct { int p; void (*f)(int p); } name_for_linkage; + +void g() { b_template<int>(); } |