From 461a67fa15370a9ec88f8f8a240bf7c123bb2029 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 18 Dec 2017 20:11:37 +0000 Subject: Vendor import of clang trunk r321017: https://llvm.org/svn/llvm-project/cfe/trunk@321017 --- test/Modules/ExtDebugInfo.cpp | 9 + test/Modules/Inputs/DebugCXX.h | 6 +- test/Modules/Inputs/codegen/foo.h | 3 + test/Modules/Inputs/codegen/use.cpp | 3 + test/Modules/Inputs/export_as_test.modulemap | 9 + test/Modules/ModuleDebugInfo.cpp | 11 +- test/Modules/adl.cpp | 40 + test/Modules/anon-linkage.cpp | 12 + test/Modules/builtin-import.mm | 4 +- test/Modules/codegen-opt.test | 12 +- test/Modules/codegen.test | 4 +- test/Modules/crash-typo-correction-visibility.cpp | 5 +- test/Modules/crash-vfs-ivfsoverlay.m | 1 + test/Modules/cxx-templates.cpp | 14 + test/Modules/cxx17-inline-variables.cpp | 30 + test/Modules/export_as_test.c | 9 + test/Modules/merge-anon-in-extern_c.cpp | 19 + test/Modules/module-imported-by-pch-path.m | 17 + test/Modules/modules-cache-path-canonicalization.m | 4 +- test/Modules/odr_hash.cpp | 1042 +++++++++++++++++--- test/Modules/path-resolution.modulemap | 70 ++ test/Modules/umbrella-header-include-builtin.mm | 4 +- test/Modules/using-decl-inheritance.cpp | 34 + test/Modules/using-directive-redecl.cpp | 37 + test/Modules/using-directive.cpp | 62 ++ test/Modules/var-templates.cpp | 24 + test/Modules/visibility-in-instantiation.cpp | 51 + 27 files changed, 1395 insertions(+), 141 deletions(-) create mode 100644 test/Modules/Inputs/export_as_test.modulemap create mode 100644 test/Modules/adl.cpp create mode 100644 test/Modules/anon-linkage.cpp create mode 100644 test/Modules/cxx17-inline-variables.cpp create mode 100644 test/Modules/export_as_test.c create mode 100644 test/Modules/merge-anon-in-extern_c.cpp create mode 100644 test/Modules/module-imported-by-pch-path.m create mode 100644 test/Modules/path-resolution.modulemap create mode 100644 test/Modules/using-decl-inheritance.cpp create mode 100644 test/Modules/using-directive-redecl.cpp create mode 100644 test/Modules/using-directive.cpp create mode 100644 test/Modules/var-templates.cpp create mode 100644 test/Modules/visibility-in-instantiation.cpp (limited to 'test/Modules') diff --git a/test/Modules/ExtDebugInfo.cpp b/test/Modules/ExtDebugInfo.cpp index ed9d1e859d83..97386bc4d007 100644 --- a/test/Modules/ExtDebugInfo.cpp +++ b/test/Modules/ExtDebugInfo.cpp @@ -69,6 +69,8 @@ WithSpecializedBase definedLocally4; void foo() { anon.i = GlobalStruct.i = GlobalUnion.i = GlobalEnum; + A a; + Virtual virt; } // CHECK: ![[CPP:.*]] = !DIFile(filename: {{.*}}ExtDebugInfo.cpp" @@ -210,3 +212,10 @@ void foo() { // CHECK-SAME: dwoId: // CHECK-PCH: !DICompileUnit({{.*}}splitDebugFilename: // CHECK-PCH: dwoId: 18446744073709551614 + +// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A", +// CHECK-SAME: DIFlagFwdDecl, identifier: "_ZTS1A") + +// There is a full definition of the type available in the module. +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual", +// CHECK-SAME: DIFlagFwdDecl, identifier: "_ZTS7Virtual") diff --git a/test/Modules/Inputs/DebugCXX.h b/test/Modules/Inputs/DebugCXX.h index c9cd68f30c46..1ccf8d302f13 100644 --- a/test/Modules/Inputs/DebugCXX.h +++ b/test/Modules/Inputs/DebugCXX.h @@ -54,9 +54,9 @@ namespace DebugCXX { } // Virtual class with a forward declaration. -class FwdVirtual; -class FwdVirtual { - virtual ~FwdVirtual() {} +struct Virtual; +struct Virtual { + virtual ~Virtual() {} }; struct PureForwardDecl; diff --git a/test/Modules/Inputs/codegen/foo.h b/test/Modules/Inputs/codegen/foo.h index bd3b6489e710..76ad6559cca0 100644 --- a/test/Modules/Inputs/codegen/foo.h +++ b/test/Modules/Inputs/codegen/foo.h @@ -29,4 +29,7 @@ inline void inst_decl() { inst(); } +__attribute__((always_inline)) inline void always_inl() { +} + asm("narf"); diff --git a/test/Modules/Inputs/codegen/use.cpp b/test/Modules/Inputs/codegen/use.cpp index cd1a4a642d09..3e551881f636 100644 --- a/test/Modules/Inputs/codegen/use.cpp +++ b/test/Modules/Inputs/codegen/use.cpp @@ -6,3 +6,6 @@ void non_modular_use_of_implicit_dtor() { void use_of_instantiated_declaration_without_definition() { inst(); } +void call_always_inline() { + always_inl(); +} diff --git a/test/Modules/Inputs/export_as_test.modulemap b/test/Modules/Inputs/export_as_test.modulemap new file mode 100644 index 000000000000..4aaec4194ef5 --- /dev/null +++ b/test/Modules/Inputs/export_as_test.modulemap @@ -0,0 +1,9 @@ +module PrivateFoo { + export_as Foo + export_as Bar + export_as Bar + + module Sub { + export_as Wibble + } +} diff --git a/test/Modules/ModuleDebugInfo.cpp b/test/Modules/ModuleDebugInfo.cpp index 71b05e5aeb8b..008b3e4f2bab 100644 --- a/test/Modules/ModuleDebugInfo.cpp +++ b/test/Modules/ModuleDebugInfo.cpp @@ -86,10 +86,10 @@ // CHECK-SAME: flags: DIFlagFwdDecl // CHECK-SAME: identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE") -// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdVirtual" +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual" // CHECK-SAME: elements: -// CHECK-SAME: identifier: "_ZTS10FwdVirtual") -// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$FwdVirtual" +// CHECK-SAME: identifier: "_ZTS7Virtual") +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$Virtual" // CHECK: !DICompositeType(tag: DW_TAG_union_type, // CHECK-NOT: name: @@ -111,6 +111,11 @@ // CHECK-SAME: name: "InAnonymousNamespace", // CHECK-SAME: elements: !{{[0-9]+}}) +// CHECK: ![[A:.*]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, name: "A", +// CHECK-SAME: elements: +// CHECK-SAME: vtableHolder: ![[A]], +// CHECK-SAME: identifier: "_ZTS1A") + // CHECK: ![[DERIVED:.*]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, name: "Derived", // CHECK-SAME: identifier: "_ZTS7Derived") // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B", scope: ![[DERIVED]], diff --git a/test/Modules/adl.cpp b/test/Modules/adl.cpp new file mode 100644 index 000000000000..a1055a889d00 --- /dev/null +++ b/test/Modules/adl.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fmodules -verify -fno-modules-error-recovery -fno-spell-checking %s +// RUN: %clang_cc1 -fmodules -verify -fno-modules-error-recovery -DONLY_Y %s + +#pragma clang module build a +module a { + explicit module x {} + explicit module y {} +} +#pragma clang module contents +#pragma clang module begin a.x +namespace N { + template extern int f(T) { return 0; } +} +#pragma clang module end + +#pragma clang module begin a.y +#pragma clang module import a.x +using N::f; +#pragma clang module end +#pragma clang module endbuild + +namespace N { struct A {}; } +struct B {}; + +#ifndef ONLY_Y +#pragma clang module import a.x +void test1() { + f(N::A()); + f(B()); // expected-error {{use of undeclared identifier 'f'}} +} +#else +// expected-no-diagnostics +#endif + +#pragma clang module import a.y +void test2() { + // These are OK even if a.x is not imported. + f(N::A()); + f(B()); +} diff --git a/test/Modules/anon-linkage.cpp b/test/Modules/anon-linkage.cpp new file mode 100644 index 000000000000..590638292b5e --- /dev/null +++ b/test/Modules/anon-linkage.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -std=c++17 -fmodules-ts %s + +typedef struct { + int c; + union { + int n; + char c[4]; + } v; +} mbstate; + +export module M; +export using ::mbstate; diff --git a/test/Modules/builtin-import.mm b/test/Modules/builtin-import.mm index 2536ac51c42f..cbc312b05904 100644 --- a/test/Modules/builtin-import.mm +++ b/test/Modules/builtin-import.mm @@ -1,7 +1,5 @@ -// REQUIRES: system-darwin - // RUN: rm -rf %t -// RUN: %clang -cc1 -fsyntax-only -nostdinc++ -isysroot %S/Inputs/libc-libcxx/sysroot -isystem %S/Inputs/libc-libcxx/sysroot/usr/include/c++/v1 -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s +// RUN: %clang -cc1 -fsyntax-only -nobuiltininc -nostdinc++ -isysroot %S/Inputs/libc-libcxx/sysroot -isystem %S/Inputs/libc-libcxx/sysroot/usr/include/c++/v1 -isystem %S/Inputs/libc-libcxx/sysroot/usr/include -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s #include #include diff --git a/test/Modules/codegen-opt.test b/test/Modules/codegen-opt.test index 2f4997a7c73f..f62cf38a5356 100644 --- a/test/Modules/codegen-opt.test +++ b/test/Modules/codegen-opt.test @@ -25,7 +25,13 @@ FOO-NOT: {{define|declare}} FOO: declare void @_Z2f1Ri(i32* FOO-NOT: {{define|declare}} -FIXME: this internal function should be weak_odr, comdat, and with a new mangling +Internal functions are not modularly code generated - they are +internal wherever they're used. This might not be ideal, but +continues to workaround/support some oddities that backwards +compatible modules have seen and supported in the wild. To remove +the duplication here, the internal functions would need to be +promoted to weak_odr, placed in comdat and given a new mangling - +this would be needed for the C++ Modules TS anyway. FOO: define internal void @_ZL2f2v() #{{[0-9]+}} FOO-NOT: {{define|declare}} @@ -45,7 +51,7 @@ BAR-OPT: define available_externally void @_Z3foov() BAR-CMN-NOT: {{define|declare}} BAR-OPT: declare void @_Z2f1Ri(i32* BAR-OPT-NOT: {{define|declare}} -BAR-OPT: define available_externally void @_ZL2f2v() +BAR-OPT: define internal void @_ZL2f2v() BAR-OPT-NOT: {{define|declare}} @@ -61,5 +67,5 @@ USE-OPT: define available_externally void @_Z3foov() USE-OPT-NOT: {{define|declare}} USE-OPT: declare void @_Z2f1Ri(i32* USE-OPT-NOT: {{define|declare}} -USE-OPT: define available_externally void @_ZL2f2v() +USE-OPT: define internal void @_ZL2f2v() USE-OPT-NOT: {{define|declare}} diff --git a/test/Modules/codegen.test b/test/Modules/codegen.test index 1bdea5df4317..a919933da2d2 100644 --- a/test/Modules/codegen.test +++ b/test/Modules/codegen.test @@ -4,7 +4,7 @@ REQUIRES: x86-registered-target RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -fmodules-debuginfo -x c++ -fmodules -emit-module -fmodule-name=foo %S/Inputs/codegen/foo.modulemap -o %t/foo.pcm RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %t/foo.pcm | FileCheck --check-prefix=FOO --check-prefix=BOTH %s -RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -fmodules -fmodule-file=%t/foo.pcm %S/Inputs/codegen/use.cpp | FileCheck --check-prefix=BOTH --check-prefix=USE %s +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -fmodules -disable-llvm-passes -fmodule-file=%t/foo.pcm %S/Inputs/codegen/use.cpp | FileCheck --check-prefix=BOTH --check-prefix=USE %s For want of any better definition, inline asm goes "everywhere" the same as it if it were in a header (with the disadvantage that the inline asm will be @@ -23,6 +23,7 @@ USE: module asm "narf" FOO: $_Z2f1PKcz = comdat any FOO: $_ZN13implicit_dtorD1Ev = comdat any USE: $_Z4instIiEvv = comdat any +USE: $_Z10always_inlv = comdat any FOO: $_ZN13implicit_dtorD2Ev = comdat any FOO: define weak_odr void @_Z2f1PKcz(i8* %fmt, ...) #{{[0-9]+}} comdat FOO: call void @llvm.va_start(i8* %{{[a-zA-Z0-9]*}}) @@ -38,6 +39,7 @@ FOO: define weak_odr void @_ZN13implicit_dtorD2Ev USE: define linkonce_odr void @_ZN20uninst_implicit_dtorD1Ev USE: define linkonce_odr void @_Z4instIiEvv +USE: define linkonce_odr void @_Z10always_inlv USE: define linkonce_odr void @_ZN20uninst_implicit_dtorD2Ev Modular debug info puts the definition of a class defined in a module in that diff --git a/test/Modules/crash-typo-correction-visibility.cpp b/test/Modules/crash-typo-correction-visibility.cpp index 518293026a63..9f0ed3b7b132 100644 --- a/test/Modules/crash-typo-correction-visibility.cpp +++ b/test/Modules/crash-typo-correction-visibility.cpp @@ -1,5 +1,6 @@ -// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=module -o %T/module.pcm -emit-module %S/Inputs/crash-typo-correction-visibility/module.modulemap -// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%T/module.pcm %s -verify +// RUN: mkdir -p %t +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=module -o %t/module.pcm -emit-module %S/Inputs/crash-typo-correction-visibility/module.modulemap +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%t/module.pcm %s -verify struct S { int member; // expected-note {{declared here}} diff --git a/test/Modules/crash-vfs-ivfsoverlay.m b/test/Modules/crash-vfs-ivfsoverlay.m index abbc0151a8cf..85aaeaef67a5 100644 --- a/test/Modules/crash-vfs-ivfsoverlay.m +++ b/test/Modules/crash-vfs-ivfsoverlay.m @@ -7,6 +7,7 @@ // RUN: %S/../VFS/Inputs/vfsoverlay2.yaml > %t/srcvfs.yaml // RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \ +// RUN: ASAN_OPTIONS=detect_leaks=0 \ // RUN: %clang -fsyntax-only -nostdinc %s \ // RUN: -I %S/Inputs/crash-recovery/usr/include \ // RUN: -ivfsoverlay %t/srcvfs.yaml \ diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp index 401b7704900b..25f8a9992585 100644 --- a/test/Modules/cxx-templates.cpp +++ b/test/Modules/cxx-templates.cpp @@ -251,8 +251,22 @@ namespace Std { // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate // CHECK-DUMP-NEXT: TemplateArgument type 'char [2]' // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition +// CHECK-DUMP-NEXT: DefinitionData +// CHECK-DUMP-NEXT: DefaultConstructor +// CHECK-DUMP-NEXT: CopyConstructor +// CHECK-DUMP-NEXT: MoveConstructor +// CHECK-DUMP-NEXT: CopyAssignment +// CHECK-DUMP-NEXT: MoveAssignment +// CHECK-DUMP-NEXT: Destructor // CHECK-DUMP-NEXT: TemplateArgument type 'char [2]' // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate // CHECK-DUMP-NEXT: TemplateArgument type 'char [1]' // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition +// CHECK-DUMP-NEXT: DefinitionData +// CHECK-DUMP-NEXT: DefaultConstructor +// CHECK-DUMP-NEXT: CopyConstructor +// CHECK-DUMP-NEXT: MoveConstructor +// CHECK-DUMP-NEXT: CopyAssignment +// CHECK-DUMP-NEXT: MoveAssignment +// CHECK-DUMP-NEXT: Destructor // CHECK-DUMP-NEXT: TemplateArgument type 'char [1]' diff --git a/test/Modules/cxx17-inline-variables.cpp b/test/Modules/cxx17-inline-variables.cpp new file mode 100644 index 000000000000..be6a190a256b --- /dev/null +++ b/test/Modules/cxx17-inline-variables.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -fmodules %s + +#pragma clang module build a +module a {} +#pragma clang module contents +#pragma clang module begin a + +template struct ak { static constexpr c value = e; }; +ak instantiate_class_definition; + +#pragma clang module end /* a */ +#pragma clang module endbuild + + +#pragma clang module build o +module o {} +#pragma clang module contents +#pragma clang module begin o +#pragma clang module import a + +inline int instantiate_var_definition() { return ak::value; } + +#pragma clang module end +#pragma clang module endbuild + + +#pragma clang module import o +#pragma clang module import a + +int main() { return ak::value; } diff --git a/test/Modules/export_as_test.c b/test/Modules/export_as_test.c new file mode 100644 index 000000000000..a73d6bfc460d --- /dev/null +++ b/test/Modules/export_as_test.c @@ -0,0 +1,9 @@ +// RUN: rm -rf %t +// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/export_as_test.modulemap %s 2> %t.err +// RUN: FileCheck %s < %t.err + +// CHECK: export_as_test.modulemap:3:13: error: conflicting re-export of module 'PrivateFoo' as 'Foo' or 'Bar' +// CHECK: export_as_test.modulemap:4:13: warning: module 'PrivateFoo' already re-exported as 'Bar' +// CHECK: export_as_test.modulemap:7:15: error: only top-level modules can be re-exported as public + + diff --git a/test/Modules/merge-anon-in-extern_c.cpp b/test/Modules/merge-anon-in-extern_c.cpp new file mode 100644 index 000000000000..1443251f7e61 --- /dev/null +++ b/test/Modules/merge-anon-in-extern_c.cpp @@ -0,0 +1,19 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -verify %s +// expected-no-diagnostics + +#pragma clang module build sys_types +module sys_types {} +#pragma clang module contents +#pragma clang module begin sys_types +extern "C" { + typedef union { bool b; } pthread_mutex_t; +} +#pragma clang module end +#pragma clang module endbuild + +typedef union { bool b; } pthread_mutex_t; +#pragma clang module import sys_types + +const pthread_mutex_t *m; + diff --git a/test/Modules/module-imported-by-pch-path.m b/test/Modules/module-imported-by-pch-path.m new file mode 100644 index 000000000000..04c6caf24dec --- /dev/null +++ b/test/Modules/module-imported-by-pch-path.m @@ -0,0 +1,17 @@ +// RUN: rm -rf %t.dst %t.cache +// RUN: mkdir -p %t.dst/folder-with-modulemap %t.dst/pch-folder +// RUN: echo '#import "folder-with-modulemap/included.h"' > %t.dst/header.h +// RUN: echo 'extern int MyModuleVersion;' > %t.dst/folder-with-modulemap/MyModule.h +// RUN: echo '@import MyModule;' > %t.dst/folder-with-modulemap/included.h +// RUN: echo 'module MyModule { header "MyModule.h" }' > %t.dst/folder-with-modulemap/module.modulemap + +// RUN: %clang -o %t.dst/pch-folder/header.pch -x objective-c-header -fmodules-cache-path=%t.cache -fmodules %t.dst/header.h +// RUN: not %clang -fsyntax-only -fmodules-cache-path=%t.cache -fmodules %s -include-pch %t.dst/pch-folder/header.pch 2>&1 | FileCheck %s + +void test() { + (void)MyModuleVersion; // should be found by implicit import +} + +// CHECK: module 'MyModule' in AST file '{{.*MyModule.*pcm}}' (imported by AST file '[[PCH:.*header.pch]]') is not defined in any loaded module map file; maybe you need to load '[[PATH:.*folder-with-modulemap]] +// CHECK: consider adding '[[PATH]]' to the header search path +// CHECK: imported by '[[PCH]]' diff --git a/test/Modules/modules-cache-path-canonicalization.m b/test/Modules/modules-cache-path-canonicalization.m index 9d68cb06faf8..a9d3e3478604 100644 --- a/test/Modules/modules-cache-path-canonicalization.m +++ b/test/Modules/modules-cache-path-canonicalization.m @@ -1,4 +1,4 @@ -// RUN: rm -rf %t/cache %T/rel +// RUN: rm -rf %t/cache %t/rel // This testcase reproduces a use-after-free after looking up a PCM in // a non-canonical modules-cache-path. @@ -22,7 +22,7 @@ // Unrelated to the above: Check that a relative path is resolved correctly. // -// RUN: %clang_cc1 -working-directory %T/rel -fmodules-cache-path=./cache \ +// RUN: %clang_cc1 -working-directory %t/rel -fmodules-cache-path=./cache \ // RUN: -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild \ // RUN: -fdisable-module-hash %t.m -fsyntax-only -Rmodule-build 2>&1 \ // RUN: | FileCheck %s diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp index 68a988dc8e78..b672695dce15 100644 --- a/test/Modules/odr_hash.cpp +++ b/test/Modules/odr_hash.cpp @@ -12,6 +12,10 @@ // RUN: echo "#define SECOND" >> %t/Inputs/second.h // RUN: cat %s >> %t/Inputs/second.h +// Test that each header can compile +// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++1z %t/Inputs/first.h +// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++1z %t/Inputs/second.h + // Build module map file // RUN: echo "module FirstModule {" >> %t/Inputs/module.map // RUN: echo " header \"first.h\"" >> %t/Inputs/module.map @@ -28,6 +32,13 @@ #include "second.h" #endif +// Used for testing +#if defined(FIRST) +#define ACCESS public: +#elif defined(SECOND) +#define ACCESS private: +#endif + namespace AccessSpecifiers { #if defined(FIRST) struct S1 { @@ -55,6 +66,32 @@ S2 s2; // expected-error@second.h:* {{'AccessSpecifiers::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found protected access specifier}} // expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} #endif + +#define DECLS \ +public: \ +private: \ +protected: + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'AccessSpecifiers::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif + +#undef DECLS } // namespace AccessSpecifiers namespace StaticAssert { @@ -113,7 +150,31 @@ S4 s4; // expected-error@second.h:* {{'StaticAssert::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}} // expected-note@first.h:* {{but in 'FirstModule' found static assert}} #endif -} + +#define DECLS \ + static_assert(4 == 4, "Message"); \ + static_assert(5 == 5); + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'StaticAssert::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS +} // namespace StaticAssert namespace Field { #if defined(FIRST) @@ -302,6 +363,38 @@ S13 s13; // expected-error@first.h:* {{'Field::S13::x' from module 'FirstModule' is not present in definition of 'Field::S13' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'x' does not match}} #endif + +#define DECLS \ + int a; \ + int b : 3; \ + unsigned c : 1 + 2; \ + s d; \ + double e = 1.0; \ + long f[5]; + +#if defined(FIRST) || defined(SECOND) +typedef short s; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'Field::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS } // namespace Field namespace Method { @@ -531,6 +624,40 @@ S15 s15; // expected-error@first.h:* {{'Method::S15::A' from module 'FirstModule' is not present in definition of 'Method::S15' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'A' does not match}} #endif + +#define DECLS \ + void A(); \ + static void B(); \ + virtual void C(); \ + virtual void D() = 0; \ + inline void E(); \ + void F() const; \ + void G() volatile; \ + void H(int x); \ + void I(int x = 5 + 5); \ + void J(int); \ + void K(int x[2]); \ + int L(); + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1* v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1* i1; +// expected-error@second.h:* {{'Method::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS } // namespace Method namespace Constructor { @@ -565,6 +692,31 @@ S2* s2; // expected-error@second.h:* {{'Constructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor that has 2 parameters}} // expected-note@first.h:* {{but in 'FirstModule' found constructor that has 1 parameter}} #endif + +#define DECLS(CLASS) \ + CLASS(int); \ + CLASS(double); \ + CLASS(int, int); + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS(Valid1) +}; +#else +Valid1* v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS(Invalid1) + ACCESS +}; +#else +Invalid1* i1; +// expected-error@second.h:* {{'Constructor::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS } // namespace Constructor namespace Destructor { @@ -600,32 +752,44 @@ S2 s2; // expected-note@first.h:* {{but in 'FirstModule' found destructor is virtual}} #endif -} // namespace Destructor - -// Naive parsing of AST can lead to cycles in processing. Ensure -// self-references don't trigger an endless cycles of AST node processing. -namespace SelfReference { -#if defined(FIRST) -template