diff options
Diffstat (limited to 'test/Modules')
164 files changed, 2720 insertions, 47 deletions
diff --git a/test/Modules/ExtDebugInfo.cpp b/test/Modules/ExtDebugInfo.cpp index 97386bc4d007c..c57f1f034eb23 100644 --- a/test/Modules/ExtDebugInfo.cpp +++ b/test/Modules/ExtDebugInfo.cpp @@ -187,7 +187,7 @@ void foo() { // CHECK: !DIGlobalVariable(name: "anon_enum", {{.*}}, type: ![[ANON_ENUM:[0-9]+]] // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, scope: ![[NS]], -// CHECK-SAME: line: 16 +// CHECK-SAME: line: 19 // CHECK: !DIGlobalVariable(name: "GlobalUnion", // CHECK-SAME: type: ![[GLOBAL_UNION:[0-9]+]] diff --git a/test/Modules/Inputs/DebugCXX.h b/test/Modules/Inputs/DebugCXX.h index 1ccf8d302f13b..8f83c0bc69dba 100644 --- a/test/Modules/Inputs/DebugCXX.h +++ b/test/Modules/Inputs/DebugCXX.h @@ -1,4 +1,7 @@ /* -*- C++ -*- */ + +#include "dummy.h" + namespace DebugCXX { // Records. struct Struct { diff --git a/test/Modules/Inputs/DependsOnModule.framework/module.map b/test/Modules/Inputs/DependsOnModule.framework/module.map index 4d468f2a8c01c..948a1efd743af 100644 --- a/test/Modules/Inputs/DependsOnModule.framework/module.map +++ b/test/Modules/Inputs/DependsOnModule.framework/module.map @@ -37,4 +37,22 @@ framework module DependsOnModule { export * } } + explicit module CXX11 { + requires cplusplus11 + } + explicit module CXX14 { + requires cplusplus14 + } + explicit module CXX17 { + requires cplusplus17 + } + explicit module C99 { + requires c99 + } + explicit module C11 { + requires c11 + } + explicit module C17 { + requires c17 + } } diff --git a/test/Modules/Inputs/at-import-in-framework-header/A.framework/Headers/A.h b/test/Modules/Inputs/at-import-in-framework-header/A.framework/Headers/A.h new file mode 100644 index 0000000000000..6949a872fc99e --- /dev/null +++ b/test/Modules/Inputs/at-import-in-framework-header/A.framework/Headers/A.h @@ -0,0 +1,2 @@ +@import B; +int foo(); diff --git a/test/Modules/Inputs/at-import-in-framework-header/A.framework/Modules/module.modulemap b/test/Modules/Inputs/at-import-in-framework-header/A.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..126cf26ec9c78 --- /dev/null +++ b/test/Modules/Inputs/at-import-in-framework-header/A.framework/Modules/module.modulemap @@ -0,0 +1,4 @@ +// at-import-in-framework-header/A.framework/Modules/module.modulemap +framework module A { + header "A.h" +} diff --git a/test/Modules/Inputs/at-import-in-framework-header/module.modulemap b/test/Modules/Inputs/at-import-in-framework-header/module.modulemap new file mode 100644 index 0000000000000..a38d66863e957 --- /dev/null +++ b/test/Modules/Inputs/at-import-in-framework-header/module.modulemap @@ -0,0 +1,2 @@ +// at-import-in-framework-header/module.modulemap +module B {} diff --git a/test/Modules/Inputs/autoload-subdirectory/a.h b/test/Modules/Inputs/autoload-subdirectory/a.h new file mode 100644 index 0000000000000..8be94312e3ef7 --- /dev/null +++ b/test/Modules/Inputs/autoload-subdirectory/a.h @@ -0,0 +1,9 @@ +#include "b.h" + +class foo { + int x, y; + +public: + foo(){}; + ~foo(){}; +}; diff --git a/test/Modules/Inputs/autoload-subdirectory/b.h b/test/Modules/Inputs/autoload-subdirectory/b.h new file mode 100644 index 0000000000000..bfde5bf79f816 --- /dev/null +++ b/test/Modules/Inputs/autoload-subdirectory/b.h @@ -0,0 +1 @@ +class bar {}; diff --git a/test/Modules/Inputs/autoload-subdirectory/c.h b/test/Modules/Inputs/autoload-subdirectory/c.h new file mode 100644 index 0000000000000..e5a45250f9f81 --- /dev/null +++ b/test/Modules/Inputs/autoload-subdirectory/c.h @@ -0,0 +1,7 @@ +class nyan { + bool x, y; + +public: + nyan(){}; + ~nyan(){}; +}; diff --git a/test/Modules/Inputs/autoload-subdirectory/include/module.modulemap b/test/Modules/Inputs/autoload-subdirectory/include/module.modulemap new file mode 100644 index 0000000000000..880ae38b97a0a --- /dev/null +++ b/test/Modules/Inputs/autoload-subdirectory/include/module.modulemap @@ -0,0 +1,3 @@ +module a { header "a.h" } +module b { header "b.h" } +module c { header "c.h" } diff --git a/test/Modules/Inputs/autoload-subdirectory/module.modulemap b/test/Modules/Inputs/autoload-subdirectory/module.modulemap new file mode 100644 index 0000000000000..880ae38b97a0a --- /dev/null +++ b/test/Modules/Inputs/autoload-subdirectory/module.modulemap @@ -0,0 +1,3 @@ +module a { header "a.h" } +module b { header "b.h" } +module c { header "c.h" } diff --git a/test/Modules/Inputs/bad-private-include/Bad.framework/Headers/Bad.h b/test/Modules/Inputs/bad-private-include/Bad.framework/Headers/Bad.h new file mode 100644 index 0000000000000..eea054917048f --- /dev/null +++ b/test/Modules/Inputs/bad-private-include/Bad.framework/Headers/Bad.h @@ -0,0 +1 @@ +#import <Bad/Shared.h>
\ No newline at end of file diff --git a/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.modulemap b/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..11612dc8cb31b --- /dev/null +++ b/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.modulemap @@ -0,0 +1,5 @@ +framework module Bad { + umbrella header "Bad.h" + export * + module * { export * } +} diff --git a/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.private.modulemap b/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.private.modulemap new file mode 100644 index 0000000000000..043139dc55d1c --- /dev/null +++ b/test/Modules/Inputs/bad-private-include/Bad.framework/Modules/module.private.modulemap @@ -0,0 +1,5 @@ +framework module Bad_Private { + umbrella header "BadPrivate.h" + export * + module * { export * } +} diff --git a/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/BadPrivate.h b/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/BadPrivate.h new file mode 100644 index 0000000000000..eea054917048f --- /dev/null +++ b/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/BadPrivate.h @@ -0,0 +1 @@ +#import <Bad/Shared.h>
\ No newline at end of file diff --git a/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/Shared.h b/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/Shared.h new file mode 100644 index 0000000000000..4f1defddefbaa --- /dev/null +++ b/test/Modules/Inputs/bad-private-include/Bad.framework/PrivateHeaders/Shared.h @@ -0,0 +1,3 @@ +struct SomeDecl { + int x; +}; diff --git a/test/Modules/Inputs/class-extension/a-private.h b/test/Modules/Inputs/class-extension/a-private.h new file mode 100644 index 0000000000000..e35402ac18ad5 --- /dev/null +++ b/test/Modules/Inputs/class-extension/a-private.h @@ -0,0 +1,5 @@ +#import "a.h" +#import "a-proto.h" + +@interface A () <AProto> +@end diff --git a/test/Modules/Inputs/class-extension/a-proto.h b/test/Modules/Inputs/class-extension/a-proto.h new file mode 100644 index 0000000000000..32043ec2498f8 --- /dev/null +++ b/test/Modules/Inputs/class-extension/a-proto.h @@ -0,0 +1,7 @@ +@protocol NSObject +@end + +@protocol AProto <NSObject> +@property (nonatomic, readwrite, assign) int p0; +@property (nonatomic, readwrite, assign) int p1; +@end diff --git a/test/Modules/Inputs/class-extension/a.h b/test/Modules/Inputs/class-extension/a.h new file mode 100644 index 0000000000000..28c409c337748 --- /dev/null +++ b/test/Modules/Inputs/class-extension/a.h @@ -0,0 +1,5 @@ +@interface NSObject +@end + +@interface A : NSObject +@end diff --git a/test/Modules/Inputs/class-extension/module.modulemap b/test/Modules/Inputs/class-extension/module.modulemap new file mode 100644 index 0000000000000..5c30bc57e46c7 --- /dev/null +++ b/test/Modules/Inputs/class-extension/module.modulemap @@ -0,0 +1,11 @@ + +module A { + header "a.h" + header "a-proto.h" + export * +} + +module AP { + header "a-private.h" + export * +} diff --git a/test/Modules/Inputs/declare-use/h.h b/test/Modules/Inputs/declare-use/h.h index 379e50180ca19..8984727c565e7 100644 --- a/test/Modules/Inputs/declare-use/h.h +++ b/test/Modules/Inputs/declare-use/h.h @@ -1,7 +1,7 @@ #ifndef H_H #define H_H #include "c.h" -#include "d.h" // expected-error {{does not depend on a module exporting}} +#include "d.h" // expected-error {{module XH does not depend on a module exporting}} #include "h1.h" const int h1 = aux_h*c*7*d; #endif diff --git a/test/Modules/Inputs/diag_flags.h b/test/Modules/Inputs/diag_flags.h index 3b85c84c6cfd5..55eeab196a314 100644 --- a/test/Modules/Inputs/diag_flags.h +++ b/test/Modules/Inputs/diag_flags.h @@ -1 +1,4 @@ +#define pragma _Pragma("clang diagnostic push") _Pragma("clang diagnostic error \"-Wpadded\"") _Pragma("clang diagnostic pop") +pragma + struct Padded { char x; int y; }; diff --git a/test/Modules/Inputs/double-quotes/A.framework/Headers/A.h b/test/Modules/Inputs/double-quotes/A.framework/Headers/A.h new file mode 100644 index 0000000000000..17ceb83bb9ca8 --- /dev/null +++ b/test/Modules/Inputs/double-quotes/A.framework/Headers/A.h @@ -0,0 +1,6 @@ +#include "A0.h" +#include "B.h" + +#include "X.h" + +int foo(); diff --git a/test/Modules/Inputs/double-quotes/A.framework/Headers/A0.h b/test/Modules/Inputs/double-quotes/A.framework/Headers/A0.h new file mode 100644 index 0000000000000..79c6b8893ba41 --- /dev/null +++ b/test/Modules/Inputs/double-quotes/A.framework/Headers/A0.h @@ -0,0 +1 @@ +// double-quotes/A.framework/Headers/A0.h diff --git a/test/Modules/Inputs/double-quotes/A.framework/Modules/module.modulemap b/test/Modules/Inputs/double-quotes/A.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..09a887a8f489f --- /dev/null +++ b/test/Modules/Inputs/double-quotes/A.framework/Modules/module.modulemap @@ -0,0 +1,5 @@ +// double-quotes/A.framework/Modules/module.modulemap +framework module A { + header "A.h" + header "A0.h" +} diff --git a/test/Modules/Inputs/double-quotes/B.h b/test/Modules/Inputs/double-quotes/B.h new file mode 100644 index 0000000000000..724faaef807dc --- /dev/null +++ b/test/Modules/Inputs/double-quotes/B.h @@ -0,0 +1 @@ +// double-quotes/B.h diff --git a/test/Modules/Inputs/double-quotes/X.framework/Headers/X.h b/test/Modules/Inputs/double-quotes/X.framework/Headers/X.h new file mode 100644 index 0000000000000..0185751299c71 --- /dev/null +++ b/test/Modules/Inputs/double-quotes/X.framework/Headers/X.h @@ -0,0 +1 @@ +// double-quotes/X.framework/Headers/X.h diff --git a/test/Modules/Inputs/double-quotes/X.framework/Modules/module.modulemap b/test/Modules/Inputs/double-quotes/X.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..95524704c6839 --- /dev/null +++ b/test/Modules/Inputs/double-quotes/X.framework/Modules/module.modulemap @@ -0,0 +1,4 @@ +// double-quotes/X.framework/Modules/module.modulemap +framework module X { + header "X.h" +} diff --git a/test/Modules/Inputs/double-quotes/a.hmap.json b/test/Modules/Inputs/double-quotes/a.hmap.json new file mode 100644 index 0000000000000..bdd383ce41500 --- /dev/null +++ b/test/Modules/Inputs/double-quotes/a.hmap.json @@ -0,0 +1,6 @@ +{ + "mappings" : + { + "A.h" : "A/A.h" + } +} diff --git a/test/Modules/Inputs/double-quotes/flat-header-path/Z.h b/test/Modules/Inputs/double-quotes/flat-header-path/Z.h new file mode 100644 index 0000000000000..db96b64962c1d --- /dev/null +++ b/test/Modules/Inputs/double-quotes/flat-header-path/Z.h @@ -0,0 +1 @@ +#import "B.h" // Included from Z.h & A.h diff --git a/test/Modules/Inputs/double-quotes/flat-header-path/Z.modulemap b/test/Modules/Inputs/double-quotes/flat-header-path/Z.modulemap new file mode 100644 index 0000000000000..34441b07018cc --- /dev/null +++ b/test/Modules/Inputs/double-quotes/flat-header-path/Z.modulemap @@ -0,0 +1,4 @@ +// double-quotes/flat-header-path/Z.modulemap +framework module Z { + header "Z.h" +} diff --git a/test/Modules/Inputs/double-quotes/x.hmap.json b/test/Modules/Inputs/double-quotes/x.hmap.json new file mode 100644 index 0000000000000..2b6a05956469b --- /dev/null +++ b/test/Modules/Inputs/double-quotes/x.hmap.json @@ -0,0 +1,7 @@ + +{ + "mappings" : + { + "X.h" : "X/X.h" + } +} diff --git a/test/Modules/Inputs/double-quotes/z.yaml b/test/Modules/Inputs/double-quotes/z.yaml new file mode 100644 index 0000000000000..242f821346e69 --- /dev/null +++ b/test/Modules/Inputs/double-quotes/z.yaml @@ -0,0 +1,28 @@ +{ + 'version': 0, + 'case-sensitive': 'false', + 'roots': [ + { + 'type': 'directory', + 'name': "TEST_DIR/Z.framework/Headers", + 'contents': [ + { + 'type': 'file', + 'name': "Z.h", + 'external-contents': "TEST_DIR/flat-header-path/Z.h" + } + ] + }, + { + 'type': 'directory', + 'name': "TEST_DIR/Z.framework/Modules", + 'contents': [ + { + 'type': 'file', + 'name': "module.modulemap", + 'external-contents': "TEST_DIR/flat-header-path/Z.modulemap" + } + ] + } + ] +} diff --git a/test/Modules/Inputs/exportas-link/OtherKit.framework/Headers/OtherKit.h b/test/Modules/Inputs/exportas-link/OtherKit.framework/Headers/OtherKit.h new file mode 100644 index 0000000000000..f62c082d64dfb --- /dev/null +++ b/test/Modules/Inputs/exportas-link/OtherKit.framework/Headers/OtherKit.h @@ -0,0 +1,7 @@ +// Umbrella header for OtherKit. +#import <SomeKitCore/SomeKitCore.h> + +#ifdef F +#import <SomeKit/SomeKit.h> +#endif + diff --git a/test/Modules/Inputs/exportas-link/OtherKit.framework/Modules/module.modulemap b/test/Modules/Inputs/exportas-link/OtherKit.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..1ce7351218096 --- /dev/null +++ b/test/Modules/Inputs/exportas-link/OtherKit.framework/Modules/module.modulemap @@ -0,0 +1,5 @@ + +framework module OtherKit { + header "OtherKit.h" + export * +} diff --git a/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SKWidget.h b/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SKWidget.h new file mode 100644 index 0000000000000..60473720f91b3 --- /dev/null +++ b/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SKWidget.h @@ -0,0 +1,2 @@ +// Delegate to SomeKitCore. +#import <SomeKitCore/SKWidget.h> diff --git a/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SomeKit.h b/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SomeKit.h new file mode 100644 index 0000000000000..15e96a7554ccf --- /dev/null +++ b/test/Modules/Inputs/exportas-link/SomeKit.framework/Headers/SomeKit.h @@ -0,0 +1,6 @@ +// Umbrella header for SomeKit. +// +// Note that this file's content must not end up to coincidentally be identical +// to any other file in the test which can easily happen given the reduced +// test. +#import <SomeKit/SKWidget.h> diff --git a/test/Modules/Inputs/exportas-link/SomeKit.framework/Modules/module.modulemap b/test/Modules/Inputs/exportas-link/SomeKit.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..ae4b276d47b35 --- /dev/null +++ b/test/Modules/Inputs/exportas-link/SomeKit.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module SomeKit { + umbrella header "SomeKit.h" + module * { + export * + } +} diff --git a/test/Modules/Inputs/exportas-link/SomeKit.framework/SomeKit.tbd b/test/Modules/Inputs/exportas-link/SomeKit.framework/SomeKit.tbd new file mode 100644 index 0000000000000..ab95795b98e7d --- /dev/null +++ b/test/Modules/Inputs/exportas-link/SomeKit.framework/SomeKit.tbd @@ -0,0 +1 @@ +dummy tbd file diff --git a/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SKWidget.h b/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SKWidget.h new file mode 100644 index 0000000000000..1fb010cb39aa0 --- /dev/null +++ b/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SKWidget.h @@ -0,0 +1,4 @@ +@interface SKWidget +- (void)someObjCMethod; +@end + diff --git a/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SomeKitCore.h b/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SomeKitCore.h new file mode 100644 index 0000000000000..f18aa97d4218f --- /dev/null +++ b/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Headers/SomeKitCore.h @@ -0,0 +1,6 @@ +// Umbrella header for SomeKitCore. +// +// Note that this file's content must not end up to coincidentally be identical +// to any other file in the test which can easily happen given the reduced +// test. +#import <SomeKitCore/SKWidget.h> diff --git a/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Modules/module.modulemap b/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..30f9770c97c61 --- /dev/null +++ b/test/Modules/Inputs/exportas-link/SomeKitCore.framework/Modules/module.modulemap @@ -0,0 +1,7 @@ +framework module SomeKitCore { + umbrella header "SomeKitCore.h" + export_as SomeKit + module * { + export * + } +} diff --git a/test/Modules/Inputs/exportas-link/SomeKitCore.framework/SomeKitCore.tbd b/test/Modules/Inputs/exportas-link/SomeKitCore.framework/SomeKitCore.tbd new file mode 100644 index 0000000000000..ab95795b98e7d --- /dev/null +++ b/test/Modules/Inputs/exportas-link/SomeKitCore.framework/SomeKitCore.tbd @@ -0,0 +1 @@ +dummy tbd file diff --git a/test/Modules/Inputs/framework-public-includes-private/A.framework/Headers/A.h b/test/Modules/Inputs/framework-public-includes-private/A.framework/Headers/A.h new file mode 100644 index 0000000000000..03bd90b4945a4 --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/A.framework/Headers/A.h @@ -0,0 +1,4 @@ +#include <A/APriv.h> +#include "APriv2.h" +#include <Z/Z.h> +int foo(); diff --git a/test/Modules/Inputs/framework-public-includes-private/A.framework/Modules/module.modulemap b/test/Modules/Inputs/framework-public-includes-private/A.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..09639b2b50bb4 --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/A.framework/Modules/module.modulemap @@ -0,0 +1,4 @@ +// framework-public-includes-private/A.framework/Modules/module.modulemap +framework module A { + header "A.h" +} diff --git a/test/Modules/Inputs/framework-public-includes-private/A.framework/Modules/module.private.modulemap b/test/Modules/Inputs/framework-public-includes-private/A.framework/Modules/module.private.modulemap new file mode 100644 index 0000000000000..8ede0b0d6ee3a --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/A.framework/Modules/module.private.modulemap @@ -0,0 +1,4 @@ +// framework-public-includes-private/A.framework/Modules/module.private.modulemap +framework module A_Private { + header "APriv.h" +} diff --git a/test/Modules/Inputs/framework-public-includes-private/A.framework/PrivateHeaders/APriv.h b/test/Modules/Inputs/framework-public-includes-private/A.framework/PrivateHeaders/APriv.h new file mode 100644 index 0000000000000..34cc847512f51 --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/A.framework/PrivateHeaders/APriv.h @@ -0,0 +1 @@ +// framework-public-includes-private/A.framework/PrivateHeaders/APriv.h diff --git a/test/Modules/Inputs/framework-public-includes-private/A.framework/PrivateHeaders/APriv2.h b/test/Modules/Inputs/framework-public-includes-private/A.framework/PrivateHeaders/APriv2.h new file mode 100644 index 0000000000000..8ffeb41837401 --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/A.framework/PrivateHeaders/APriv2.h @@ -0,0 +1 @@ +// framework-public-includes-private/A.framework/PrivateHeaders/APriv2.h diff --git a/test/Modules/Inputs/framework-public-includes-private/a.hmap.json b/test/Modules/Inputs/framework-public-includes-private/a.hmap.json new file mode 100644 index 0000000000000..42aed4551c17a --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/a.hmap.json @@ -0,0 +1,8 @@ + +{ + "mappings" : + { + "A.h" : "A/A.h", + "APriv2.h" : "A/APriv2.h" + } +} diff --git a/test/Modules/Inputs/framework-public-includes-private/flat-header-path/Z.h b/test/Modules/Inputs/framework-public-includes-private/flat-header-path/Z.h new file mode 100644 index 0000000000000..157c6daa76eb0 --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/flat-header-path/Z.h @@ -0,0 +1,2 @@ +// framework-public-includes-private/flat-header-path/Z.h +#import "ZPriv.h" diff --git a/test/Modules/Inputs/framework-public-includes-private/flat-header-path/Z.modulemap b/test/Modules/Inputs/framework-public-includes-private/flat-header-path/Z.modulemap new file mode 100644 index 0000000000000..0a1a9710c4fa2 --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/flat-header-path/Z.modulemap @@ -0,0 +1,4 @@ +// framework-public-includes-private/flat-header-path/Z.modulemap +framework module Z { + header "Z.h" +} diff --git a/test/Modules/Inputs/framework-public-includes-private/flat-header-path/Z.private.modulemap b/test/Modules/Inputs/framework-public-includes-private/flat-header-path/Z.private.modulemap new file mode 100644 index 0000000000000..f409af8a15afd --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/flat-header-path/Z.private.modulemap @@ -0,0 +1,4 @@ +// framework-public-includes-private/flat-header-path/Z.private.modulemap +framework module Z_Private { + header "ZPriv.h" +} diff --git a/test/Modules/Inputs/framework-public-includes-private/flat-header-path/ZPriv.h b/test/Modules/Inputs/framework-public-includes-private/flat-header-path/ZPriv.h new file mode 100644 index 0000000000000..08532fedbfa42 --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/flat-header-path/ZPriv.h @@ -0,0 +1 @@ +// framework-public-includes-private/flat-header-path/ZPriv.h diff --git a/test/Modules/Inputs/framework-public-includes-private/z.hmap.json b/test/Modules/Inputs/framework-public-includes-private/z.hmap.json new file mode 100644 index 0000000000000..206b25ec738ec --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/z.hmap.json @@ -0,0 +1,7 @@ + +{ + "mappings" : + { + "ZPriv.h" : "Z/ZPriv.h" + } +} diff --git a/test/Modules/Inputs/framework-public-includes-private/z.yaml b/test/Modules/Inputs/framework-public-includes-private/z.yaml new file mode 100644 index 0000000000000..5793c1ff1f191 --- /dev/null +++ b/test/Modules/Inputs/framework-public-includes-private/z.yaml @@ -0,0 +1,45 @@ +{ + 'version': 0, + 'case-sensitive': 'false', + 'use-external-names' : 'false', + 'roots': [ + { + 'type': 'directory', + 'name': "TEST_DIR/Z.framework/Headers", + 'contents': [ + { + 'type': 'file', + 'name': "Z.h", + 'external-contents': "TEST_DIR/flat-header-path/Z.h" + } + ] + }, + { + 'type': 'directory', + 'name': "TEST_DIR/Z.framework/PrivateHeaders", + 'contents': [ + { + 'type': 'file', + 'name': "ZPriv.h", + 'external-contents': "TEST_DIR/flat-header-path/ZPriv.h" + } + ] + }, + { + 'type': 'directory', + 'name': "TEST_DIR/Z.framework/Modules", + 'contents': [ + { + 'type': 'file', + 'name': "module.modulemap", + 'external-contents': "TEST_DIR/flat-header-path/Z.modulemap" + }, + { + 'type': 'file', + 'name': "module.private.modulemap", + 'external-contents': "TEST_DIR/flat-header-path/Z.private.modulemap" + } + ] + } + ] +} diff --git a/test/Modules/Inputs/implicit-private-canonical/A.framework/Modules/module.modulemap b/test/Modules/Inputs/implicit-private-canonical/A.framework/Modules/module.modulemap index 95eabf90a9684..e8455fb730d1c 100644 --- a/test/Modules/Inputs/implicit-private-canonical/A.framework/Modules/module.modulemap +++ b/test/Modules/Inputs/implicit-private-canonical/A.framework/Modules/module.modulemap @@ -1,4 +1,7 @@ framework module A { header "a.h" + + module Pirate {} + export * } diff --git a/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.modulemap b/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.modulemap index 95eabf90a9684..73d5ab7a4bbe7 100644 --- a/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.modulemap +++ b/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.modulemap @@ -2,3 +2,9 @@ framework module A { header "a.h" export * } + +framework module B { +} + +framework module C { +} diff --git a/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap b/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap index 40182969f4c72..9acb489970219 100644 --- a/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap +++ b/test/Modules/Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap @@ -2,3 +2,9 @@ framework module A.Private { header "aprivate.h" export * } + +explicit module B.Private { +} + +explicit framework module C.Private { +} diff --git a/test/Modules/Inputs/incomplete-framework-module/Foo.framework/Headers/Foo.h b/test/Modules/Inputs/incomplete-framework-module/Foo.framework/Headers/Foo.h new file mode 100644 index 0000000000000..547f1bc6b086c --- /dev/null +++ b/test/Modules/Inputs/incomplete-framework-module/Foo.framework/Headers/Foo.h @@ -0,0 +1 @@ +// Inputs/incomplete-framework-module/Foo.framework/Headers/Foo.h diff --git a/test/Modules/Inputs/incomplete-framework-module/Foo.framework/Headers/FooB.h b/test/Modules/Inputs/incomplete-framework-module/Foo.framework/Headers/FooB.h new file mode 100644 index 0000000000000..eda7c17070001 --- /dev/null +++ b/test/Modules/Inputs/incomplete-framework-module/Foo.framework/Headers/FooB.h @@ -0,0 +1 @@ +// FooB.h diff --git a/test/Modules/Inputs/incomplete-framework-module/Foo.framework/Modules/module.modulemap b/test/Modules/Inputs/incomplete-framework-module/Foo.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..d928a53efcdff --- /dev/null +++ b/test/Modules/Inputs/incomplete-framework-module/Foo.framework/Modules/module.modulemap @@ -0,0 +1,4 @@ +module Foo { + umbrella header "Foo.h" + header "FooB.h" +} diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map index 4788daa431662..3f128c0bb0e0f 100644 --- a/test/Modules/Inputs/module.map +++ b/test/Modules/Inputs/module.map @@ -380,6 +380,11 @@ module TargetFeatures { module x86_32 { requires x86_32 } module x86_64 { requires x86_64 } } + module riscv { + requires riscv + module riscv32 { requires riscv32 } + module riscv64 { requires riscv64 } + } } module DebugSubmodules { @@ -460,3 +465,13 @@ module innerstructredef { header "innerstructredef.h" } } + +module template_nontrivial0 { + header "template-nontrivial0.h" + export * +} + +module template_nontrivial1 { + header "template-nontrivial1.h" + export * +} diff --git a/test/Modules/Inputs/non-ambiguous-enum/A.framework/Headers/a.h b/test/Modules/Inputs/non-ambiguous-enum/A.framework/Headers/a.h new file mode 100644 index 0000000000000..060bc4997385d --- /dev/null +++ b/test/Modules/Inputs/non-ambiguous-enum/A.framework/Headers/a.h @@ -0,0 +1 @@ +#include <A/a0.h> diff --git a/test/Modules/Inputs/non-ambiguous-enum/A.framework/Headers/a0.h b/test/Modules/Inputs/non-ambiguous-enum/A.framework/Headers/a0.h new file mode 100644 index 0000000000000..2e4d0912119e5 --- /dev/null +++ b/test/Modules/Inputs/non-ambiguous-enum/A.framework/Headers/a0.h @@ -0,0 +1 @@ +#include <B/b.h> diff --git a/test/Modules/Inputs/non-ambiguous-enum/A.framework/Modules/module.modulemap b/test/Modules/Inputs/non-ambiguous-enum/A.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..e14f8f02053a0 --- /dev/null +++ b/test/Modules/Inputs/non-ambiguous-enum/A.framework/Modules/module.modulemap @@ -0,0 +1,5 @@ + +framework module A { + header "a.h" + export * +} diff --git a/test/Modules/Inputs/non-ambiguous-enum/B.framework/Headers/b.h b/test/Modules/Inputs/non-ambiguous-enum/B.framework/Headers/b.h new file mode 100644 index 0000000000000..def44e3a6340d --- /dev/null +++ b/test/Modules/Inputs/non-ambiguous-enum/B.framework/Headers/b.h @@ -0,0 +1,6 @@ +typedef long NSInteger; +typedef enum __attribute__((flag_enum,enum_extensibility(open))) MyObjCEnum : NSInteger MyObjCEnum; + +enum MyObjCEnum : NSInteger { + MyEnumCst = 1, +} __attribute__((availability(ios,introduced=11.0))) __attribute__((availability(tvos,unavailable))) ; diff --git a/test/Modules/Inputs/odr_hash-Friend/Bad.h b/test/Modules/Inputs/odr_hash-Friend/Bad.h new file mode 100644 index 0000000000000..c0a6d1f9889fe --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Friend/Bad.h @@ -0,0 +1,17 @@ +template <class T> +struct iterator { + void Compare(const iterator &x) { return; } + friend void Check(iterator) { return; } +}; + +template <class T = int> struct Box { + iterator<T> I; + + void test() { + Check(I); + I.Compare(I); + } +}; + +// Force instantiation of Box<int> +Box<> B; diff --git a/test/Modules/Inputs/odr_hash-Friend/Box.h b/test/Modules/Inputs/odr_hash-Friend/Box.h new file mode 100644 index 0000000000000..01ab90d601c2d --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Friend/Box.h @@ -0,0 +1,14 @@ +template <class T> +struct iterator { + void Compare(const iterator &x) { } + friend void Check(iterator) {} +}; + +template <class T = int> struct Box { + iterator<T> I; + + void test() { + Check(I); + I.Compare(I); + } +}; diff --git a/test/Modules/Inputs/odr_hash-Friend/Good.h b/test/Modules/Inputs/odr_hash-Friend/Good.h new file mode 100644 index 0000000000000..4c38392eb6ed0 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Friend/Good.h @@ -0,0 +1,17 @@ +template <class T> +struct iterator { + void Compare(const iterator &x) { } + friend void Check(iterator) {} +}; + +template <class T = int> struct Box { + iterator<T> I; + + void test() { + Check(I); + I.Compare(I); + } +}; + +// Force instantiation of Box<int> +Box<> B; diff --git a/test/Modules/Inputs/odr_hash-Friend/M1.h b/test/Modules/Inputs/odr_hash-Friend/M1.h new file mode 100644 index 0000000000000..202ad06c3488c --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Friend/M1.h @@ -0,0 +1,6 @@ +#include "Box.h" + +void Peek() { + Box<> Gift; + Gift.test(); +} diff --git a/test/Modules/Inputs/odr_hash-Friend/M2.h b/test/Modules/Inputs/odr_hash-Friend/M2.h new file mode 100644 index 0000000000000..69f08a957ede8 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Friend/M2.h @@ -0,0 +1,5 @@ +#include "Box.h" +void x() { + Box<> Unused; + //Unused.test(); +} diff --git a/test/Modules/Inputs/odr_hash-Friend/M3.h b/test/Modules/Inputs/odr_hash-Friend/M3.h new file mode 100644 index 0000000000000..ab457e0c08f21 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Friend/M3.h @@ -0,0 +1,7 @@ +#include "Box.h" +#include "M2.h" + +void Party() { + Box<> Present; + Present.test(); +} diff --git a/test/Modules/Inputs/odr_hash-Friend/module.modulemap b/test/Modules/Inputs/odr_hash-Friend/module.modulemap new file mode 100644 index 0000000000000..449d51e7f7091 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Friend/module.modulemap @@ -0,0 +1,23 @@ +module Box { + header "Box.h" +} + +module Module1 { + header "M1.h" +} + +module Module2 { + header "M2.h" +} + +module Module3 { + header "M3.h" +} + +module Good { + header "Good.h" +} + +module Bad { + header "Bad.h" +} diff --git a/test/Modules/Inputs/odr_hash-Unresolved/Module2/include.h b/test/Modules/Inputs/odr_hash-Unresolved/Module2/include.h new file mode 100644 index 0000000000000..fa7c017228e71 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Unresolved/Module2/include.h @@ -0,0 +1,3 @@ +// include.h +#include "Sub1/Z.h" + diff --git a/test/Modules/Inputs/odr_hash-Unresolved/Module2/not-include.h b/test/Modules/Inputs/odr_hash-Unresolved/Module2/not-include.h new file mode 100644 index 0000000000000..98cd1ef26fcec --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Unresolved/Module2/not-include.h @@ -0,0 +1,5 @@ +// not-include.h + +#include "function.h" +#include "class.h" + diff --git a/test/Modules/Inputs/odr_hash-Unresolved/Sub1/X.h b/test/Modules/Inputs/odr_hash-Unresolved/Sub1/X.h new file mode 100644 index 0000000000000..f610e665e5cb7 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Unresolved/Sub1/X.h @@ -0,0 +1,3 @@ +// X.h +#include "Sub1/Z.h" + diff --git a/test/Modules/Inputs/odr_hash-Unresolved/Sub1/Y.h b/test/Modules/Inputs/odr_hash-Unresolved/Sub1/Y.h new file mode 100644 index 0000000000000..f41ddd639e762 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Unresolved/Sub1/Y.h @@ -0,0 +1,4 @@ +// Y.h +#include "Sub1/Z.h" +#include "class.h" + diff --git a/test/Modules/Inputs/odr_hash-Unresolved/Sub1/Z.h b/test/Modules/Inputs/odr_hash-Unresolved/Sub1/Z.h new file mode 100644 index 0000000000000..b6bdc140f9973 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Unresolved/Sub1/Z.h @@ -0,0 +1,4 @@ +// Z.h +#include "Sub2/A.h" +#include "Sub2/B.h" + diff --git a/test/Modules/Inputs/odr_hash-Unresolved/Sub2/A.h b/test/Modules/Inputs/odr_hash-Unresolved/Sub2/A.h new file mode 100644 index 0000000000000..a65b370beae3a --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Unresolved/Sub2/A.h @@ -0,0 +1,3 @@ +// A.h +#include "function.h" + diff --git a/test/Modules/Inputs/odr_hash-Unresolved/Sub2/B.h b/test/Modules/Inputs/odr_hash-Unresolved/Sub2/B.h new file mode 100644 index 0000000000000..fa89f216b6ce1 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Unresolved/Sub2/B.h @@ -0,0 +1,3 @@ +// B.h +#include "function.h" + diff --git a/test/Modules/Inputs/odr_hash-Unresolved/class.h b/test/Modules/Inputs/odr_hash-Unresolved/class.h new file mode 100644 index 0000000000000..fe3a7116f9bfc --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Unresolved/class.h @@ -0,0 +1,11 @@ +#ifndef Class +#define Class +template <class T> +class S { + int Field; + void run() { + int x; + A::Check(&Field, 1); + } +}; +#endif diff --git a/test/Modules/Inputs/odr_hash-Unresolved/function.h b/test/Modules/Inputs/odr_hash-Unresolved/function.h new file mode 100644 index 0000000000000..de75b2c92ef61 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Unresolved/function.h @@ -0,0 +1,6 @@ +#ifndef Function +#define Function +namespace A { +static void Check(int*, int) {} +} +#endif diff --git a/test/Modules/Inputs/odr_hash-Unresolved/module.modulemap b/test/Modules/Inputs/odr_hash-Unresolved/module.modulemap new file mode 100644 index 0000000000000..ac7fc43cae638 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-Unresolved/module.modulemap @@ -0,0 +1,21 @@ +module Module1 { + module Sub1 { + umbrella "Sub1" + module * { export * } + } + + module Sub2 { + umbrella "Sub2" + module * { export * } + } +} + +module Module2 { + umbrella "Module2" + module * { export * } +} + +module Other { + textual header "function.h" + textual header "class.h" +} diff --git a/test/Modules/Inputs/odr_hash-elaborated-types/first.h b/test/Modules/Inputs/odr_hash-elaborated-types/first.h new file mode 100644 index 0000000000000..d2c4a033a1613 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-elaborated-types/first.h @@ -0,0 +1,6 @@ +#ifndef FIRST +#define FIRST + +#include "textual_time.h" + +#endif diff --git a/test/Modules/Inputs/odr_hash-elaborated-types/module.modulemap b/test/Modules/Inputs/odr_hash-elaborated-types/module.modulemap new file mode 100644 index 0000000000000..94cb4c111918d --- /dev/null +++ b/test/Modules/Inputs/odr_hash-elaborated-types/module.modulemap @@ -0,0 +1,5 @@ +module M { + module first { header "first.h" export *} + module second { header "second.h" export *} + export * +} diff --git a/test/Modules/Inputs/odr_hash-elaborated-types/second.h b/test/Modules/Inputs/odr_hash-elaborated-types/second.h new file mode 100644 index 0000000000000..577cf1134579b --- /dev/null +++ b/test/Modules/Inputs/odr_hash-elaborated-types/second.h @@ -0,0 +1,6 @@ +#ifndef SECOND +#define SECOND + +#include "textual_stat.h" + +#endif diff --git a/test/Modules/Inputs/odr_hash-elaborated-types/textual_stat.h b/test/Modules/Inputs/odr_hash-elaborated-types/textual_stat.h new file mode 100644 index 0000000000000..5dad510f9eb93 --- /dev/null +++ b/test/Modules/Inputs/odr_hash-elaborated-types/textual_stat.h @@ -0,0 +1,11 @@ +#ifndef _SYS_STAT_H +#define _SYS_STAT_H + +#include "textual_time.h" + +struct stat { + struct timespec st_atim; + struct timespec st_mtim; +}; + +#endif diff --git a/test/Modules/Inputs/odr_hash-elaborated-types/textual_time.h b/test/Modules/Inputs/odr_hash-elaborated-types/textual_time.h new file mode 100644 index 0000000000000..2a2a89c5a7ebd --- /dev/null +++ b/test/Modules/Inputs/odr_hash-elaborated-types/textual_time.h @@ -0,0 +1,6 @@ +#ifndef _TIME_H +#define _TIME_H + +struct timespec { }; + +#endif diff --git a/test/Modules/Inputs/protocol-redefinition/Base.framework/Headers/Base.h b/test/Modules/Inputs/protocol-redefinition/Base.framework/Headers/Base.h new file mode 100644 index 0000000000000..e3fe33c1bdb91 --- /dev/null +++ b/test/Modules/Inputs/protocol-redefinition/Base.framework/Headers/Base.h @@ -0,0 +1,3 @@ +@protocol Foo +- (void)someMethodOnFoo; +@end diff --git a/test/Modules/Inputs/protocol-redefinition/Base.framework/Modules/module.modulemap b/test/Modules/Inputs/protocol-redefinition/Base.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..0366bb4f03903 --- /dev/null +++ b/test/Modules/Inputs/protocol-redefinition/Base.framework/Modules/module.modulemap @@ -0,0 +1,4 @@ +framework module Base { + header "Base.h" + export * +}
\ No newline at end of file diff --git a/test/Modules/Inputs/protocol-redefinition/Kit.framework/Headers/Kit.h b/test/Modules/Inputs/protocol-redefinition/Kit.framework/Headers/Kit.h new file mode 100644 index 0000000000000..93384c294f135 --- /dev/null +++ b/test/Modules/Inputs/protocol-redefinition/Kit.framework/Headers/Kit.h @@ -0,0 +1,6 @@ +#import <Base/Base.h> + +// REDECLARATION +@protocol Foo +- (void)someMethodOnFoo; +@end diff --git a/test/Modules/Inputs/protocol-redefinition/Kit.framework/Modules/module.modulemap b/test/Modules/Inputs/protocol-redefinition/Kit.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..2b790f4496549 --- /dev/null +++ b/test/Modules/Inputs/protocol-redefinition/Kit.framework/Modules/module.modulemap @@ -0,0 +1,4 @@ +framework module Kit { + header "Kit.h" + export * +}
\ No newline at end of file diff --git a/test/Modules/Inputs/self-referencing-lambda/a.h b/test/Modules/Inputs/self-referencing-lambda/a.h new file mode 100644 index 0000000000000..756fe18de6297 --- /dev/null +++ b/test/Modules/Inputs/self-referencing-lambda/a.h @@ -0,0 +1,4 @@ +void f() { + int x = 0; + auto q = [xm = x]{}; +} diff --git a/test/Modules/Inputs/self-referencing-lambda/module.modulemap b/test/Modules/Inputs/self-referencing-lambda/module.modulemap new file mode 100644 index 0000000000000..812ca9de82d3b --- /dev/null +++ b/test/Modules/Inputs/self-referencing-lambda/module.modulemap @@ -0,0 +1,4 @@ +module "a.h" { + header "a.h" + export * +} diff --git a/test/Modules/Inputs/shadow/A1/A.h b/test/Modules/Inputs/shadow/A1/A.h new file mode 100644 index 0000000000000..f07c681c2aa5c --- /dev/null +++ b/test/Modules/Inputs/shadow/A1/A.h @@ -0,0 +1 @@ +#define A1_A_h diff --git a/test/Modules/Inputs/shadow/A1/module.modulemap b/test/Modules/Inputs/shadow/A1/module.modulemap new file mode 100644 index 0000000000000..9439a431b1dbe --- /dev/null +++ b/test/Modules/Inputs/shadow/A1/module.modulemap @@ -0,0 +1,5 @@ +module A { + header "A.h" +} + +module A1 {} diff --git a/test/Modules/Inputs/shadow/A2/A.h b/test/Modules/Inputs/shadow/A2/A.h new file mode 100644 index 0000000000000..9880ed010f569 --- /dev/null +++ b/test/Modules/Inputs/shadow/A2/A.h @@ -0,0 +1 @@ +#define A2_A_h diff --git a/test/Modules/Inputs/shadow/A2/module.modulemap b/test/Modules/Inputs/shadow/A2/module.modulemap new file mode 100644 index 0000000000000..935d89bb425e0 --- /dev/null +++ b/test/Modules/Inputs/shadow/A2/module.modulemap @@ -0,0 +1,5 @@ +module A { + header "A.h" +} + +module A2 {} diff --git a/test/Modules/Inputs/shadowed-submodule/A1/Foo.h b/test/Modules/Inputs/shadowed-submodule/A1/Foo.h new file mode 100644 index 0000000000000..57775d1a29dd3 --- /dev/null +++ b/test/Modules/Inputs/shadowed-submodule/A1/Foo.h @@ -0,0 +1 @@ +#include <stdarg.h> // expected-error {{could not build module 'A'}} diff --git a/test/Modules/Inputs/shadowed-submodule/A1/module.modulemap b/test/Modules/Inputs/shadowed-submodule/A1/module.modulemap new file mode 100644 index 0000000000000..7afbc4713617b --- /dev/null +++ b/test/Modules/Inputs/shadowed-submodule/A1/module.modulemap @@ -0,0 +1,14 @@ +module A [system] { // expected-note {{previous definition is here}} + module sub { + header "sys/A.h" + } + module sub2 { + header "sys/A2.h" + } + module stdarg { + header "stdarg.h" + export * + } +} + +module A2 {} diff --git a/test/Modules/Inputs/shadowed-submodule/A1/sys/A.h b/test/Modules/Inputs/shadowed-submodule/A1/sys/A.h new file mode 100644 index 0000000000000..4fc3e8ea9e638 --- /dev/null +++ b/test/Modules/Inputs/shadowed-submodule/A1/sys/A.h @@ -0,0 +1 @@ +#include <sys/A2.h> diff --git a/test/Modules/Inputs/shadowed-submodule/A1/sys/A2.h b/test/Modules/Inputs/shadowed-submodule/A1/sys/A2.h new file mode 100644 index 0000000000000..e9b6a44cfe212 --- /dev/null +++ b/test/Modules/Inputs/shadowed-submodule/A1/sys/A2.h @@ -0,0 +1 @@ +// nothing diff --git a/test/Modules/Inputs/shadowed-submodule/A2/Foo.h b/test/Modules/Inputs/shadowed-submodule/A2/Foo.h new file mode 100644 index 0000000000000..38ade6d9f5051 --- /dev/null +++ b/test/Modules/Inputs/shadowed-submodule/A2/Foo.h @@ -0,0 +1 @@ +#include <stdarg.h> diff --git a/test/Modules/Inputs/shadowed-submodule/A2/module.modulemap b/test/Modules/Inputs/shadowed-submodule/A2/module.modulemap new file mode 100644 index 0000000000000..c4e44b074aa14 --- /dev/null +++ b/test/Modules/Inputs/shadowed-submodule/A2/module.modulemap @@ -0,0 +1,14 @@ +module A [system] { + module sub { + header "sys/A.h" + } + module sub2 { // expected-error {{build a shadowed submodule 'A.sub2'}} + header "sys/A2.h" + } + module stdarg { + header "stdarg.h" + export * + } +} + +module A2 {} diff --git a/test/Modules/Inputs/shadowed-submodule/A2/sys/A.h b/test/Modules/Inputs/shadowed-submodule/A2/sys/A.h new file mode 100644 index 0000000000000..4fc3e8ea9e638 --- /dev/null +++ b/test/Modules/Inputs/shadowed-submodule/A2/sys/A.h @@ -0,0 +1 @@ +#include <sys/A2.h> diff --git a/test/Modules/Inputs/shadowed-submodule/A2/sys/A2.h b/test/Modules/Inputs/shadowed-submodule/A2/sys/A2.h new file mode 100644 index 0000000000000..e9b6a44cfe212 --- /dev/null +++ b/test/Modules/Inputs/shadowed-submodule/A2/sys/A2.h @@ -0,0 +1 @@ +// nothing diff --git a/test/Modules/Inputs/shadowed-submodule/Foo/module.modulemap b/test/Modules/Inputs/shadowed-submodule/Foo/module.modulemap new file mode 100644 index 0000000000000..11db9cb05da2b --- /dev/null +++ b/test/Modules/Inputs/shadowed-submodule/Foo/module.modulemap @@ -0,0 +1,3 @@ +module Foo { + header "../A1/Foo.h" +} diff --git a/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Headers/A.h b/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Headers/A.h new file mode 100644 index 0000000000000..975f1f0437bb1 --- /dev/null +++ b/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Headers/A.h @@ -0,0 +1 @@ +// A.h diff --git a/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Headers/SomeSub.h b/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Headers/SomeSub.h new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Headers/SomeSub.h diff --git a/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Modules/module.modulemap b/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Modules/module.modulemap new file mode 100644 index 0000000000000..afa48392e94a2 --- /dev/null +++ b/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Modules/module.modulemap @@ -0,0 +1,3 @@ +framework module A { + header "A.h" +} diff --git a/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Modules/module.private.modulemap b/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Modules/module.private.modulemap new file mode 100644 index 0000000000000..1dbd9fb8096b5 --- /dev/null +++ b/test/Modules/Inputs/submodule-in-private-mmap/A.framework/Modules/module.private.modulemap @@ -0,0 +1,7 @@ +framework module A_Private { + header "APrivate.h" +} + +module A.SomeSub { + header "SomeSub.h" +} diff --git a/test/Modules/Inputs/submodule-in-private-mmap/A.framework/PrivateHeaders/APrivate.h b/test/Modules/Inputs/submodule-in-private-mmap/A.framework/PrivateHeaders/APrivate.h new file mode 100644 index 0000000000000..e69de29bb2d1d --- /dev/null +++ b/test/Modules/Inputs/submodule-in-private-mmap/A.framework/PrivateHeaders/APrivate.h diff --git a/test/Modules/Inputs/template-nontrivial0.h b/test/Modules/Inputs/template-nontrivial0.h new file mode 100644 index 0000000000000..cff080ee5cc28 --- /dev/null +++ b/test/Modules/Inputs/template-nontrivial0.h @@ -0,0 +1,13 @@ +template <class T> +struct Class0 { + Class0(); + Class0(const Class0<T> &); + ~Class0(); + T *p; +}; + +struct S0 { + id x; +}; + +Class0<S0> returnNonTrivial(); diff --git a/test/Modules/Inputs/template-nontrivial1.h b/test/Modules/Inputs/template-nontrivial1.h new file mode 100644 index 0000000000000..24136f0cae4eb --- /dev/null +++ b/test/Modules/Inputs/template-nontrivial1.h @@ -0,0 +1,6 @@ +@import template_nontrivial0; + +struct S1 { + S1(); + Class0<S0> a; +}; diff --git a/test/Modules/ModuleDebugInfo.cpp b/test/Modules/ModuleDebugInfo.cpp index 008b3e4f2bab9..116aa5fc3107b 100644 --- a/test/Modules/ModuleDebugInfo.cpp +++ b/test/Modules/ModuleDebugInfo.cpp @@ -5,12 +5,13 @@ // Modules: // RUN: rm -rf %t -// RUN: %clang_cc1 -triple %itanium_abi_triple -x objective-c++ -std=c++11 -debug-info-kind=limited -fmodules -fmodule-format=obj -fimplicit-module-maps -DMODULES -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t.ll -mllvm -debug-only=pchcontainer &>%t-mod.ll +// RUN: %clang_cc1 -triple %itanium_abi_triple -x objective-c++ -std=c++11 -debugger-tuning=lldb -debug-info-kind=limited -fmodules -fmodule-format=obj -fimplicit-module-maps -DMODULES -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t.ll -mllvm -debug-only=pchcontainer &>%t-mod.ll // RUN: cat %t-mod.ll | FileCheck %s // RUN: cat %t-mod.ll | FileCheck --check-prefix=CHECK-NEG %s +// RUN: cat %t-mod.ll | FileCheck --check-prefix=CHECK-MOD %s // PCH: -// RUN: %clang_cc1 -triple %itanium_abi_triple -x c++ -std=c++11 -emit-pch -fmodule-format=obj -I %S/Inputs -o %t.pch %S/Inputs/DebugCXX.h -mllvm -debug-only=pchcontainer &>%t-pch.ll +// RUN: %clang_cc1 -triple %itanium_abi_triple -x c++ -std=c++11 -debugger-tuning=lldb -emit-pch -fmodule-format=obj -I %S/Inputs -o %t.pch %S/Inputs/DebugCXX.h -mllvm -debug-only=pchcontainer &>%t-pch.ll // RUN: cat %t-pch.ll | FileCheck %s // RUN: cat %t-pch.ll | FileCheck --check-prefix=CHECK-NEG %s @@ -18,6 +19,9 @@ @import DebugCXX; #endif +// CHECK-MOD: distinct !DICompileUnit(language: DW_LANG_{{.*}}C_plus_plus, +// CHECK-MOD: distinct !DICompileUnit(language: DW_LANG_{{.*}}C_plus_plus, + // CHECK: distinct !DICompileUnit(language: DW_LANG_{{.*}}C_plus_plus, // CHECK-SAME: isOptimized: false, // CHECK-NOT: splitDebugFilename: @@ -27,6 +31,8 @@ // CHECK-SAME: identifier: "_ZTSN8DebugCXX4EnumE") // CHECK: !DINamespace(name: "DebugCXX" +// CHECK-MOD: ![[DEBUGCXX:.*]] = !DIModule(scope: null, name: "DebugCXX + // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, // CHECK-NOT: name: // CHECK-SAME: ) @@ -42,7 +48,7 @@ // CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, // CHECK-NOT: name: // CHECK-SAME: ) -// CHECK: !DIEnumerator(name: "e5", value: 5) +// CHECK: !DIEnumerator(name: "e5", value: 5, isUnsigned: true) // CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "B", // no mangled name here yet. @@ -150,4 +156,11 @@ // CHECK-SAME: name: "WithSpecializedBase<float>", // CHECK-SAME: flags: DIFlagFwdDecl, +// CHECK-MOD: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: ![[DEBUGCXX]], +// CHECK-MOD-SAME: entity: ![[DUMMY:[0-9]+]], +// CHECK-MOD-SAME: line: 3) +// CHECK-MOD: ![[DUMMY]] = !DIModule(scope: null, name: "dummy", +// CHECK-MOD: distinct !DICompileUnit(language: DW_LANG_ObjC_plus_plus, +// CHECK-MOD-SAME: splitDebugFilename: "{{.*}}dummy{{.*}}.pcm", + // CHECK-NEG-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "PureForwardDecl" diff --git a/test/Modules/at-import-in-framework-header.m b/test/Modules/at-import-in-framework-header.m new file mode 100644 index 0000000000000..fe3663812075d --- /dev/null +++ b/test/Modules/at-import-in-framework-header.m @@ -0,0 +1,17 @@ +// REQUIRES: shell + +// RUN: rm -rf %t +// RUN: mkdir %t + +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache \ +// RUN: -F%S/Inputs/at-import-in-framework-header -I%S/Inputs/at-import-in-framework-header \ +// RUN: -Watimport-in-framework-header -fsyntax-only %s \ +// RUN: 2>%t/stderr +// RUN: FileCheck --input-file=%t/stderr %s + +// CHECK: use of '@import' in framework header is discouraged + +#import <A/A.h> + +int bar() { return foo(); } + diff --git a/test/Modules/autoload-subdirectory.cpp b/test/Modules/autoload-subdirectory.cpp new file mode 100644 index 0000000000000..e76f7056abed0 --- /dev/null +++ b/test/Modules/autoload-subdirectory.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fmodules -fmodule-name=Foo -I %S/Inputs/autoload-subdirectory/ %s -verify +// expected-no-diagnostics + +#include "a.h" +#import "c.h" + +int main() { + foo neko; + return 0; +} diff --git a/test/Modules/bad-private-include.m b/test/Modules/bad-private-include.m new file mode 100644 index 0000000000000..e12b280be7efa --- /dev/null +++ b/test/Modules/bad-private-include.m @@ -0,0 +1,6 @@ +// RUN: rm -rf %t.cache +// RUN: %clang_cc1 -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps -F %S/Inputs/bad-private-include %s -verify + +// expected-no-diagnostics + +@import Bad; diff --git a/test/Modules/check-for-sanitizer-feature.cpp b/test/Modules/check-for-sanitizer-feature.cpp index 40ae46c646847..c015669071b7a 100644 --- a/test/Modules/check-for-sanitizer-feature.cpp +++ b/test/Modules/check-for-sanitizer-feature.cpp @@ -43,7 +43,7 @@ // // Import the PCH without ASan enabled (we expect an error). // RUN: not %clang_cc1 -x c -include-pch %t.asan_pch %s -verify 2>&1 | FileCheck %s --check-prefix=PCH_MISMATCH -// PCH_MISMATCH: AST file was compiled with the target feature'-fsanitize=address' but the current translation unit is not +// PCH_MISMATCH: AST file was compiled with the target feature '-fsanitize=address' but the current translation unit is not // // Emit a PCH with UBSan enabled. // RUN: %clang_cc1 -x c -fsanitize=null %S/Inputs/check-for-sanitizer-feature/check.h -emit-pch -o %t.ubsan_pch diff --git a/test/Modules/class-extension-protocol.m b/test/Modules/class-extension-protocol.m new file mode 100644 index 0000000000000..752e4e129d29c --- /dev/null +++ b/test/Modules/class-extension-protocol.m @@ -0,0 +1,9 @@ +// RUN: rm -rf %t.cache +// RUN: %clang_cc1 %s -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.cache -I%S/Inputs/class-extension -verify +// expected-no-diagnostics + +#import "a-private.h" + +int foo(A *X) { + return X.p0 + X.p1; +} diff --git a/test/Modules/codegen.test b/test/Modules/codegen.test index a919933da2d24..2d20b078a7533 100644 --- a/test/Modules/codegen.test +++ b/test/Modules/codegen.test @@ -6,6 +6,7 @@ RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -fmodules-debuginfo - 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 -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 included in the program if the module is used, even if the header containing diff --git a/test/Modules/crash-vfs-headermaps.m b/test/Modules/crash-vfs-headermaps.m index 4f88f3ba1197c..118537ba2a4fd 100644 --- a/test/Modules/crash-vfs-headermaps.m +++ b/test/Modules/crash-vfs-headermaps.m @@ -1,15 +1,9 @@ // REQUIRES: crash-recovery, shell, system-darwin -// This uses a headermap with this entry: -// Foo.h -> Foo/Foo.h - -// Copy out the headermap from test/Preprocessor/Inputs/headermap-rel and avoid -// adding another binary format to the repository. - // RUN: rm -rf %t -// RUN: mkdir -p %t/m -// RUN: cp -a %S/../Preprocessor/Inputs/headermap-rel %t/i +// RUN: mkdir -p %t/m %t/i/Foo.framework/Headers // RUN: echo '// Foo.h' > %t/i/Foo.framework/Headers/Foo.h +// RUN: %hmaptool write %S/../Preprocessor/Inputs/headermap-rel/foo.hmap.json %t/i/foo.hmap // RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \ // RUN: %clang -fsyntax-only -fmodules -fmodules-cache-path=%t/m %s \ diff --git a/test/Modules/crash-vfs-path-emptydir-entries.m b/test/Modules/crash-vfs-path-emptydir-entries.m index d96adbbf99ba2..a50ea869f4764 100644 --- a/test/Modules/crash-vfs-path-emptydir-entries.m +++ b/test/Modules/crash-vfs-path-emptydir-entries.m @@ -8,7 +8,7 @@ // RUN: rm -rf %t // RUN: mkdir -p %t/i %t/m %t %t/sysroot -// RUN: cp -a %S/Inputs/crash-recovery/usr %t/i/ +// RUN: cp -R %S/Inputs/crash-recovery/usr %t/i/ // RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \ // RUN: %clang -fsyntax-only %s -I %/t/i -isysroot %/t/sysroot/ \ diff --git a/test/Modules/crash-vfs-path-symlink-component.m b/test/Modules/crash-vfs-path-symlink-component.m index 4723a77c7e937..565a64fb5c239 100644 --- a/test/Modules/crash-vfs-path-symlink-component.m +++ b/test/Modules/crash-vfs-path-symlink-component.m @@ -8,7 +8,7 @@ // RUN: rm -rf %t // RUN: mkdir -p %t/i %t/m %t %t/sysroot -// RUN: cp -a %S/Inputs/crash-recovery/usr %t/i/ +// RUN: cp -R %S/Inputs/crash-recovery/usr %t/i/ // RUN: ln -s include/tcl-private %t/i/usr/x // RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \ diff --git a/test/Modules/crash-vfs-path-symlink-topheader.m b/test/Modules/crash-vfs-path-symlink-topheader.m index 8e0c2d4c9226d..fea1f01c02ae9 100644 --- a/test/Modules/crash-vfs-path-symlink-topheader.m +++ b/test/Modules/crash-vfs-path-symlink-topheader.m @@ -8,7 +8,7 @@ // RUN: rm -rf %t // RUN: mkdir -p %t/i %t/m %t %t/sysroot -// RUN: cp -a %S/Inputs/crash-recovery/usr %t/i/ +// RUN: cp -R %S/Inputs/crash-recovery/usr %t/i/ // RUN: rm -f %t/i/usr/include/pthread_impl.h // RUN: ln -s pthread/pthread_impl.h %t/i/usr/include/pthread_impl.h diff --git a/test/Modules/crash-vfs-umbrella-frameworks.m b/test/Modules/crash-vfs-umbrella-frameworks.m index 0c3981ddaa887..a18acf576ea3d 100644 --- a/test/Modules/crash-vfs-umbrella-frameworks.m +++ b/test/Modules/crash-vfs-umbrella-frameworks.m @@ -5,7 +5,7 @@ // RUN: rm -rf %t // RUN: mkdir -p %t/i %t/m %t -// RUN: cp -a %S/Inputs/crash-recovery/Frameworks %t/i/ +// RUN: cp -R %S/Inputs/crash-recovery/Frameworks %t/i/ // RUN: mkdir -p %t/i/Frameworks/A.framework/Frameworks // RUN: ln -s ../../B.framework %t/i/Frameworks/A.framework/Frameworks/B.framework diff --git a/test/Modules/cxx-dtor.cpp b/test/Modules/cxx-dtor.cpp index 63427ee0afda0..d685b69d511a3 100644 --- a/test/Modules/cxx-dtor.cpp +++ b/test/Modules/cxx-dtor.cpp @@ -1,3 +1,4 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs/cxx-dtor -emit-llvm-only %s +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -x c++ -std=c++11 -fmodules-cache-path=%t -I %S/Inputs/cxx-dtor -emit-llvm-only %s -triple i686-windows #include "b.h" diff --git a/test/Modules/cxx-irgen.cpp b/test/Modules/cxx-irgen.cpp index 6cc32adc52545..01e4384ac5961 100644 --- a/test/Modules/cxx-irgen.cpp +++ b/test/Modules/cxx-irgen.cpp @@ -12,15 +12,15 @@ CtorInit<int> x; // Keep these two namespace definitions separate; merging them hides the bug. namespace EmitInlineMethods { - // CHECK-DAG: define linkonce_odr [[CC:([0-9_a-z]*cc[ ]+)?]]void @_ZN17EmitInlineMethods1C1fEPNS_1AE( - // CHECK-DAG: declare [[CC]]void @_ZN17EmitInlineMethods1A1gEv( + // CHECK-DAG: define linkonce_odr {{(dso_local )?}}[[CC:([0-9_a-z]*cc[ ]+)?]]void @_ZN17EmitInlineMethods1C1fEPNS_1AE( + // CHECK-DAG: declare {{(dso_local )?}}[[CC]]void @_ZN17EmitInlineMethods1A1gEv( struct C { __attribute__((used)) void f(A *p) { p->g(); } }; } namespace EmitInlineMethods { - // CHECK-DAG: define linkonce_odr [[CC]]void @_ZN17EmitInlineMethods1D1fEPNS_1BE( - // CHECK-DAG: define linkonce_odr [[CC]]void @_ZN17EmitInlineMethods1B1gEv( + // CHECK-DAG: define linkonce_odr {{(dso_local )?}}[[CC]]void @_ZN17EmitInlineMethods1D1fEPNS_1BE( + // CHECK-DAG: define linkonce_odr {{(dso_local )?}}[[CC]]void @_ZN17EmitInlineMethods1B1gEv( struct D { __attribute__((used)) void f(B *p) { p->g(); } }; diff --git a/test/Modules/cxx17-exception-spec.cpp b/test/Modules/cxx17-exception-spec.cpp new file mode 100644 index 0000000000000..ba7be0e30d9c0 --- /dev/null +++ b/test/Modules/cxx17-exception-spec.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fno-modules-error-recovery -fno-spell-checking -verify -std=c++17 %s + +#pragma clang module build a +module a {} +#pragma clang module contents +#pragma clang module begin a +constexpr bool return_true() { return true; } +struct X { + static void f() noexcept(return_true()); +}; +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build b +module b {} +#pragma clang module contents +#pragma clang module begin b +#pragma clang module import a +using T = decltype(return_true() && noexcept(X::f())); +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module import a +#pragma clang module import b + +// Trigger import of return_true and then X::f in the same pass. This causes +// the type of X::f to be loaded while we have a pending body for return_true, +// which means evaluation of its exception specification at that point would +// fail. +T t; + +static_assert(noexcept(X().f())); + +// expected-no-diagnostics diff --git a/test/Modules/diag-flags.cpp b/test/Modules/diag-flags.cpp index ada90d24b7918..14067c63fe4f5 100644 --- a/test/Modules/diag-flags.cpp +++ b/test/Modules/diag-flags.cpp @@ -3,24 +3,24 @@ // For an implicit module, all that matters are the warning flags in the user. // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodules-cache-path=%t -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -fmodules-ts // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DWARNING -Wpadded -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DERROR -Wpadded -Werror -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DERROR -Werror=padded +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DWARNING -DLOCAL_WARNING -Wpadded +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DERROR -DLOCAL_ERROR -Wpadded -Werror +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DERROR -DLOCAL_ERROR -Werror=padded // // For an explicit module, all that matters are the warning flags in the module build. // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -fmodules-ts -o %t/nodiag.pcm -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -fmodule-file=%t/nodiag.pcm -Wpadded -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -fmodule-file=%t/nodiag.pcm -Werror -Wpadded +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -fmodule-file=%t/nodiag.pcm -Wpadded -DLOCAL_WARNING +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -fmodule-file=%t/nodiag.pcm -Werror -Wpadded -DLOCAL_ERROR // // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -fmodules-ts -o %t/warning.pcm -Wpadded // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DWARNING -fmodule-file=%t/warning.pcm -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DWARNING -fmodule-file=%t/warning.pcm -Werror=padded +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DWARNING -fmodule-file=%t/warning.pcm -Werror=padded -DLOCAL_ERROR // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DWARNING -fmodule-file=%t/warning.pcm -Werror // // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -fmodules-ts -o %t/werror-no-error.pcm -Werror -Wpadded -Wno-error=padded // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DWARNING -fmodule-file=%t/werror-no-error.pcm // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DWARNING -fmodule-file=%t/werror-no-error.pcm -Wno-padded -// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DWARNING -fmodule-file=%t/werror-no-error.pcm -Werror=padded +// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DWARNING -fmodule-file=%t/werror-no-error.pcm -Werror=padded -DLOCAL_ERROR // // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_flags -x c++ %S/Inputs/module.map -fmodules-ts -o %t/error.pcm -Werror=padded // RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DERROR -fmodule-file=%t/error.pcm -Wno-padded @@ -35,10 +35,22 @@ import diag_flags; // Diagnostic flags from the module user make no difference to diagnostics // emitted within the module when using an explicitly-loaded module. #if ERROR -// expected-error@diag_flags.h:14 {{padding struct}} +// expected-error@diag_flags.h:4 {{padding struct}} #elif WARNING -// expected-warning@diag_flags.h:14 {{padding struct}} -#else -// expected-no-diagnostics +// expected-warning@diag_flags.h:4 {{padding struct}} #endif int arr[sizeof(Padded)]; + +// Diagnostic flags from the module make no difference to diagnostics emitted +// in the module user. +#if LOCAL_ERROR +// expected-error@+4 {{padding struct}} +#elif LOCAL_WARNING +// expected-warning@+2 {{padding struct}} +#endif +struct Padded2 { char x; int y; }; +int arr2[sizeof(Padded2)]; + +#if !ERROR && !WARNING && !LOCAL_ERROR && !LOCAL_WARNING +// expected-no-diagnostics +#endif diff --git a/test/Modules/double-quotes.m b/test/Modules/double-quotes.m new file mode 100644 index 0000000000000..a21f12fa5e5ac --- /dev/null +++ b/test/Modules/double-quotes.m @@ -0,0 +1,39 @@ +// REQUIRES: shell + +// RUN: rm -rf %t +// RUN: mkdir %t + +// RUN: %hmaptool write %S/Inputs/double-quotes/a.hmap.json %t/a.hmap +// RUN: %hmaptool write %S/Inputs/double-quotes/x.hmap.json %t/x.hmap + +// RUN: sed -e "s:TEST_DIR:%S/Inputs/double-quotes:g" \ +// RUN: %S/Inputs/double-quotes/z.yaml > %t/z.yaml + +// The output with and without modules should be the same + +// RUN: %clang_cc1 \ +// RUN: -I %t/x.hmap -iquote %t/a.hmap -ivfsoverlay %t/z.yaml \ +// RUN: -F%S/Inputs/double-quotes -I%S/Inputs/double-quotes \ +// RUN: -Wquoted-include-in-framework-header -fsyntax-only %s -verify + +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache \ +// RUN: -I %t/x.hmap -iquote %t/a.hmap -ivfsoverlay %t/z.yaml \ +// RUN: -F%S/Inputs/double-quotes -I%S/Inputs/double-quotes \ +// RUN: -Wquoted-include-in-framework-header -fsyntax-only %s \ +// RUN: 2>%t/stderr + +// The same warnings show up when modules is on but -verify doesn't get it +// because they only show up under the module A building context. +// RUN: FileCheck --input-file=%t/stderr %s +// CHECK: double-quoted include "A0.h" in framework header, expected angle-bracketed instead +// CHECK: double-quoted include "B.h" in framework header, expected angle-bracketed instead +// CHECK: double-quoted include "B.h" in framework header, expected angle-bracketed instead + +#import "A.h" +#import <Z/Z.h> + +int bar() { return foo(); } + +// expected-warning@Inputs/double-quotes/A.framework/Headers/A.h:1{{double-quoted include "A0.h" in framework header, expected angle-bracketed instead}} +// expected-warning@Inputs/double-quotes/A.framework/Headers/A.h:2{{double-quoted include "B.h" in framework header, expected angle-bracketed instead}} +// expected-warning@Inputs/double-quotes/flat-header-path/Z.h:1{{double-quoted include "B.h" in framework header, expected angle-bracketed instead}} diff --git a/test/Modules/framework-public-includes-private.m b/test/Modules/framework-public-includes-private.m new file mode 100644 index 0000000000000..eb4d2877a1cdc --- /dev/null +++ b/test/Modules/framework-public-includes-private.m @@ -0,0 +1,37 @@ +// REQUIRES: shell + +// RUN: rm -rf %t +// RUN: mkdir %t + +// RUN: %hmaptool write %S/Inputs/framework-public-includes-private/a.hmap.json %t/a.hmap +// RUN: %hmaptool write %S/Inputs/framework-public-includes-private/z.hmap.json %t/z.hmap + +// RUN: sed -e "s:TEST_DIR:%S/Inputs/framework-public-includes-private:g" \ +// RUN: %S/Inputs/framework-public-includes-private/z.yaml > %t/z.yaml + +// The output with and without modules should be the same, without modules first. +// RUN: %clang_cc1 \ +// RUN: -iquote %t/z.hmap -iquote %t/a.hmap -ivfsoverlay %t/z.yaml \ +// RUN: -F%S/Inputs/framework-public-includes-private \ +// RUN: -fsyntax-only %s -verify + +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache \ +// RUN: -iquote %t/z.hmap -iquote %t/a.hmap -ivfsoverlay %t/z.yaml \ +// RUN: -F%S/Inputs/framework-public-includes-private \ +// RUN: -fsyntax-only %s \ +// RUN: 2>%t/stderr + +// The same warnings show up when modules is on but -verify doesn't get it +// because they only show up under the module A building context. +// RUN: FileCheck --input-file=%t/stderr %s +// CHECK: public framework header includes private framework header 'A/APriv.h' +// CHECK: public framework header includes private framework header 'A/APriv2.h' +// CHECK: public framework header includes private framework header 'Z/ZPriv.h' + +#import "A.h" + +int bar() { return foo(); } + +// expected-warning@Inputs/framework-public-includes-private/A.framework/Headers/A.h:1{{public framework header includes private framework header 'A/APriv.h'}} +// expected-warning@Inputs/framework-public-includes-private/A.framework/Headers/A.h:2{{public framework header includes private framework header 'A/APriv2.h'}} +// expected-warning@Inputs/framework-public-includes-private/flat-header-path/Z.h:2{{public framework header includes private framework header 'Z/ZPriv.h'}} diff --git a/test/Modules/friend-definition-2.cpp b/test/Modules/friend-definition-2.cpp new file mode 100644 index 0000000000000..b226b5c0d1e5d --- /dev/null +++ b/test/Modules/friend-definition-2.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fmodules %s -verify +// RUN: %clang_cc1 -fmodules %s -verify -triple i686-windows +// expected-no-diagnostics +#pragma clang module build A +module A {} +#pragma clang module contents +#pragma clang module begin A +template<typename T> struct ct { friend auto operator-(ct, ct) { struct X {}; return X(); } void x(); }; +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build B +module B {} +#pragma clang module contents +#pragma clang module begin B +template<typename T> struct ct { friend auto operator-(ct, ct) { struct X{}; return X(); } void x(); }; +inline auto f() { return ct<float>() - ct<float>(); } +#pragma clang module end +#pragma clang module endbuild + +// Force the definition of ct in module A to be the primary definition. +#pragma clang module import A +template<typename T> void ct<T>::x() {} + +// Attempt to cause the definition of operator- in the ct primary template in +// module B to be the primary definition of that function. If that happens, +// we'll be left with a class template ct that appears to not contain a +// definition of the inline friend function. +#pragma clang module import B +auto v = f(); + +ct<int> make(); +void h() { + make() - make(); +} diff --git a/test/Modules/friend-definition.cpp b/test/Modules/friend-definition.cpp new file mode 100644 index 0000000000000..8588cbd9c6f47 --- /dev/null +++ b/test/Modules/friend-definition.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -fmodules -std=c++14 %s -verify +// expected-no-diagnostics + +#pragma clang module build A +module A {} +#pragma clang module contents +#pragma clang module begin A +template<typename T> struct A { + friend A operator+(const A&, const A&) { return {}; } +}; +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build B +module B {} +#pragma clang module contents +#pragma clang module begin B +#pragma clang module import A +inline void f() { A<int> a; } +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build C +module C {} +#pragma clang module contents +#pragma clang module begin C +#pragma clang module import A +inline void g() { A<int> a; } +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module import A +#pragma clang module import B +#pragma clang module import C + +void h() { + A<int> a; + a + a; +} diff --git a/test/Modules/implicit-private-with-submodule.m b/test/Modules/implicit-private-with-submodule.m index 1779341a5f6bf..d5f23456bf886 100644 --- a/test/Modules/implicit-private-with-submodule.m +++ b/test/Modules/implicit-private-with-submodule.m @@ -13,7 +13,16 @@ // expected-warning@Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:1{{private submodule 'A.Private' in private module map, expected top-level module}} // expected-note@Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:1{{rename 'A.Private' to ensure it can be found by name}} -// CHECK: fix-it:"{{.*}}module.private.modulemap":{1:20-1:27}:"A_Private" + +// expected-warning@Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:6{{private submodule 'B.Private' in private module map, expected top-level module}} +// expected-note@Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:6{{rename 'B.Private' to ensure it can be found by name}} + +// expected-warning@Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:9{{private submodule 'C.Private' in private module map, expected top-level module}} +// expected-note@Inputs/implicit-private-with-submodule/A.framework/Modules/module.private.modulemap:9{{rename 'C.Private' to ensure it can be found by name}} + +// CHECK: fix-it:"{{.*}}module.private.modulemap":{1:1-1:27}:"framework module A_Private" +// CHECK: fix-it:"{{.*}}module.private.modulemap":{6:1-6:26}:"framework module B_Private" +// CHECK: fix-it:"{{.*}}module.private.modulemap":{9:1-9:36}:"framework module C_Private" #ifndef HEADER #define HEADER diff --git a/test/Modules/incomplete-framework-module.m b/test/Modules/incomplete-framework-module.m new file mode 100644 index 0000000000000..9034c1aab921f --- /dev/null +++ b/test/Modules/incomplete-framework-module.m @@ -0,0 +1,11 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \ +// RUN: -F%S/Inputs/incomplete-framework-module \ +// RUN: -fsyntax-only %s -verify + +#import <Foo/Foo.h> + +// expected-warning@Inputs/incomplete-framework-module/Foo.framework/Modules/module.modulemap:2{{skipping 'Foo.h' because module declaration}} +// expected-warning@Inputs/incomplete-framework-module/Foo.framework/Modules/module.modulemap:3{{skipping 'FooB.h' because module declaration}} +// expected-note@Inputs/incomplete-framework-module/Foo.framework/Modules/module.modulemap:1{{use 'framework module' to declare module 'Foo'}} +// expected-note@Inputs/incomplete-framework-module/Foo.framework/Modules/module.modulemap:1{{use 'framework module' to declare module 'Foo'}} diff --git a/test/Modules/local-visibility.cpp b/test/Modules/local-visibility.cpp new file mode 100644 index 0000000000000..fa2d20c433610 --- /dev/null +++ b/test/Modules/local-visibility.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -fmodules %s -verify +// RUN: %clang_cc1 -fsyntax-only %s -verify + +// expected-no-diagnostics +template <typename Var> +struct S { + template <unsigned N> + struct Inner { }; + + template <> + struct Inner<0> { }; +}; + +S<int>::Inner<1> I1; +S<int>::Inner<0> I0; diff --git a/test/Modules/merge-deduced-return.cpp b/test/Modules/merge-deduced-return.cpp new file mode 100644 index 0000000000000..0a4de7b975545 --- /dev/null +++ b/test/Modules/merge-deduced-return.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fmodules -std=c++17 -verify %s +// RUN: %clang_cc1 -fmodules -std=c++17 -verify %s -DLOCAL +// expected-no-diagnostics + +#pragma clang module build A +module A {} +#pragma clang module contents +#pragma clang module begin A +inline auto f() { struct X {}; return X(); } +inline auto a = f(); +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build B +module B {} +#pragma clang module contents +#pragma clang module begin B +inline auto f() { struct X {}; return X(); } +inline auto b = f(); +#pragma clang module end +#pragma clang module endbuild + +#ifdef LOCAL +inline auto f() { struct X {}; return X(); } +inline auto b = f(); +#else +#pragma clang module import B +#endif + +#pragma clang module import A + +using T = decltype(a); +using T = decltype(b); diff --git a/test/Modules/merge-lambdas.cpp b/test/Modules/merge-lambdas.cpp new file mode 100644 index 0000000000000..d14483aa3aa76 --- /dev/null +++ b/test/Modules/merge-lambdas.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -fmodules -verify %s +// expected-no-diagnostics + +#pragma clang module build A +module A {} +#pragma clang module contents +#pragma clang module begin A +template<typename T> auto f() { return []{}; } +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build B +module B {} +#pragma clang module contents +#pragma clang module begin B +#pragma clang module import A +inline auto x1() { return f<int>(); } +inline auto z() { return []{}; } +inline auto x2() { return z(); } +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build C +module C {} +#pragma clang module contents +#pragma clang module begin C +#pragma clang module import A +inline auto y1() { return f<int>(); } +inline auto z() { return []{}; } +inline auto y2() { return z(); } +inline auto q() { return []{}; } +inline auto y3() { return q(); } +#pragma clang module end +#pragma clang module endbuild + +inline auto q() { return []{}; } +inline auto x3() { return q(); } + +#pragma clang module import B +#pragma clang module import C +using T = decltype(x1); +using T = decltype(y1); + +using U = decltype(x2); +using U = decltype(y2); + +using V = decltype(x3); +using V = decltype(y3); diff --git a/test/Modules/merge-static-locals.cpp b/test/Modules/merge-static-locals.cpp new file mode 100644 index 0000000000000..37ae22ee38a38 --- /dev/null +++ b/test/Modules/merge-static-locals.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -std=c++17 -fmodules -verify %s +// expected-no-diagnostics + +#pragma clang module build A +module A {} +#pragma clang module contents +#pragma clang module begin A +template<int*> struct X {}; +auto get() { static int n; return X<&n>(); } +using A = decltype(get()); +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build B +module B {} +#pragma clang module contents +#pragma clang module begin B +template<int*> struct X {}; +auto get() { static int n; return X<&n>(); } +using B = decltype(get()); +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module import A +#pragma clang module import B +using T = A; +using T = B; diff --git a/test/Modules/merge-target-features.cpp b/test/Modules/merge-target-features.cpp index 9ca0539e6a22e..6a29c2db8a8d9 100644 --- a/test/Modules/merge-target-features.cpp +++ b/test/Modules/merge-target-features.cpp @@ -19,10 +19,9 @@ // RUN: -triple i386-unknown-unknown \ // RUN: -target-cpu i386 \ // RUN: -fsyntax-only merge-target-features.cpp 2>&1 \ -// RUN: | FileCheck --check-prefix=SUBSET %s -// SUBSET-NOT: error: +// RUN: | FileCheck --check-prefix=SUBSET --implicit-check-not=error: %s +// SUBSET: error: AST file was compiled with the target feature '+sse2' but the current translation unit is not // SUBSET: error: {{.*}} configuration mismatch -// SUBSET-NOT: error: // // RUN: %clang_cc1 -fmodules -x c++ -fmodules-cache-path=%t \ // RUN: -iquote Inputs/merge-target-features \ @@ -57,10 +56,10 @@ // RUN: -triple i386-unknown-unknown \ // RUN: -target-cpu i386 -target-feature +cx16 \ // RUN: -fsyntax-only merge-target-features.cpp 2>&1 \ -// RUN: | FileCheck --check-prefix=MISMATCH %s -// MISMATCH-NOT: error: +// RUN: | FileCheck --check-prefix=MISMATCH --implicit-check-not=error: %s +// MISMATCH: error: AST file was compiled with the target feature '+sse2' but the current translation unit is not +// MISMATCH: error: current translation unit is compiled with the target feature '+cx16' but the AST file was not // MISMATCH: error: {{.*}} configuration mismatch -// MISMATCH-NOT: error: #include "foo.h" diff --git a/test/Modules/modify-module.m b/test/Modules/modify-module.m index f9a70b25c8777..d59a4799104ff 100644 --- a/test/Modules/modify-module.m +++ b/test/Modules/modify-module.m @@ -3,9 +3,9 @@ // RUN: rm -rf %t // RUN: mkdir -p %t/include -// RUN: cp %S/Inputs/Modified/A.h %t/include -// RUN: cp %S/Inputs/Modified/B.h %t/include -// RUN: cp %S/Inputs/Modified/module.map %t/include +// RUN: cat %S/Inputs/Modified/A.h > %t/include/A.h +// RUN: cat %S/Inputs/Modified/B.h > %t/include/B.h +// RUN: cat %S/Inputs/Modified/module.map > %t/include/module.map // RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -fimplicit-module-maps -I %t/include %s -verify // RUN: echo '' >> %t/include/B.h // RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/cache -fmodules -fimplicit-module-maps -I %t/include %s -verify diff --git a/test/Modules/module-imported-by-pch-with-modulemap.m b/test/Modules/module-imported-by-pch-with-modulemap.m new file mode 100644 index 0000000000000..493034118ad0a --- /dev/null +++ b/test/Modules/module-imported-by-pch-with-modulemap.m @@ -0,0 +1,16 @@ +// 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/MyModule.modulemap + +// RUN: %clang_cc1 -emit-pch -o %t.dst/pch-folder/header.pch -fmodule-map-file=%t.dst/folder-with-modulemap/MyModule.modulemap -x objective-c-header -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps %t.dst/header.h +// RUN: %clang_cc1 -fsyntax-only -fmodule-map-file=%t.dst/folder-with-modulemap/MyModule.modulemap -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps %s -include-pch %t.dst/pch-folder/header.pch -verify + +// expected-no-diagnostics + +void test() { + (void)MyModuleVersion; // should be found by implicit import +} + diff --git a/test/Modules/module-name-private.m b/test/Modules/module-name-private.m new file mode 100644 index 0000000000000..33bd3c1075802 --- /dev/null +++ b/test/Modules/module-name-private.m @@ -0,0 +1,12 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -verify -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/implicit-private-canonical -fsyntax-only %s -Wprivate-module -fmodule-name=A -Rmodule-build + +// Because of -fmodule-name=A, no module (A or A_Private) is supposed to be +// built and -Rmodule-build should not produce any output. + +// expected-no-diagnostics + +#import <A/a.h> +#import <A/aprivate.h> + +int foo() { return APRIVATE; } diff --git a/test/Modules/module_file_info.m b/test/Modules/module_file_info.m index f2967be6f8ca4..05d401b9450a1 100644 --- a/test/Modules/module_file_info.m +++ b/test/Modules/module_file_info.m @@ -43,6 +43,16 @@ // CHECK: Predefined macros: // CHECK: -DBLARG // CHECK: -DWIBBLE=WOBBLE +// CHECK: Input file: {{.*}}DependsOnModulePrivate.h +// CHECK-NEXT: Input file: {{.*}}Other.h +// CHECK-NEXT: Input file: {{.*}}SubFramework.h +// CHECK-NEXT: Input file: {{.*}}not_coroutines.h +// CHECK-NEXT: Input file: {{.*}}not_cxx.h +// CHECK-NEXT: Input file: {{.*}}other.h +// CHECK-NEXT: Input file: {{.*}}module.map +// CHECK-NEXT: Input file: {{.*}}DependsOnModule.h +// CHECK-NEXT: Input file: {{.*}}module_private.map +// CHECK-NEXT: Input file: {{.*}}module.map // CHECK: Diagnostic options: // CHECK: IgnoreWarnings: Yes diff --git a/test/Modules/new-delete.cpp b/test/Modules/new-delete.cpp new file mode 100644 index 0000000000000..585a242b22474 --- /dev/null +++ b/test/Modules/new-delete.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fmodules -verify %s +// expected-no-diagnostics + +#pragma clang module build M +module M {} +#pragma clang module contents +#pragma clang module begin M +struct A { + A(); + ~A() { delete p; } // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'}} + int *p; +}; +inline A::A() : p(new int[32]) {} // expected-note {{allocated}} +struct B { + B(); + ~B() { delete p; } + int *p; +}; +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module import M +B::B() : p(new int[32]) {} diff --git a/test/Modules/non-ambiguous-enum.m b/test/Modules/non-ambiguous-enum.m new file mode 100644 index 0000000000000..3400b7aec3e62 --- /dev/null +++ b/test/Modules/non-ambiguous-enum.m @@ -0,0 +1,10 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F%S/Inputs/non-ambiguous-enum -fsyntax-only %s -verify +#import <B/b.h> +#import <A/a.h> + +// expected-no-diagnostics + +int foo() { + return MyEnumCst; +} diff --git a/test/Modules/odr_hash-Friend.cpp b/test/Modules/odr_hash-Friend.cpp new file mode 100644 index 0000000000000..8a2513e2f9cd0 --- /dev/null +++ b/test/Modules/odr_hash-Friend.cpp @@ -0,0 +1,90 @@ +// RUN: rm -rf %t + +// PR35939: MicrosoftMangle.cpp triggers an assertion failure on this test. +// UNSUPPORTED: system-windows + +// RUN: %clang_cc1 \ +// RUN: -I %S/Inputs/odr_hash-Friend \ +// RUN: -emit-obj -o /dev/null \ +// RUN: -fmodules \ +// RUN: -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t/modules.cache \ +// RUN: -std=c++11 -x c++ %s -verify -DTEST1 -fcolor-diagnostics + +// RUN: %clang_cc1 \ +// RUN: -I %S/Inputs/odr_hash-Friend \ +// RUN: -emit-obj -o /dev/null \ +// RUN: -fmodules \ +// RUN: -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t/modules.cache \ +// RUN: -std=c++11 -x c++ %s -verify -DTEST2 -fcolor-diagnostics + +// RUN: %clang_cc1 \ +// RUN: -I %S/Inputs/odr_hash-Friend \ +// RUN: -emit-obj -o /dev/null \ +// RUN: -fmodules \ +// RUN: -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t/modules.cache \ +// RUN: -std=c++11 -x c++ %s -verify -DTEST3 -fcolor-diagnostics + +// RUN: %clang_cc1 \ +// RUN: -I %S/Inputs/odr_hash-Friend \ +// RUN: -emit-obj -o /dev/null \ +// RUN: -fmodules \ +// RUN: -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t/modules.cache \ +// RUN: -std=c++11 -x c++ %s -verify -DTEST3 -fcolor-diagnostics + +// RUN: %clang_cc1 \ +// RUN: -I %S/Inputs/odr_hash-Friend \ +// RUN: -emit-obj -o /dev/null \ +// RUN: -fmodules \ +// RUN: -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t/modules.cache \ +// RUN: -std=c++11 -x c++ %s -verify -DTEST3 -fcolor-diagnostics + +#if defined(TEST1) +#include "Box.h" +#include "M1.h" +#include "M3.h" +// expected-no-diagnostics +#endif + +#if defined(TEST2) +#include "Box.h" +#include "M1.h" +#include "M3.h" +#include "Good.h" +// expected-no-diagnostics +#endif + +#if defined(TEST3) +#include "Good.h" +#include "Box.h" +#include "M1.h" +#include "M3.h" +// expected-no-diagnostics +#endif + +#if defined(TEST4) +#include "Box.h" +#include "M1.h" +#include "M3.h" +#include "Bad.h" +// expected-error@Bad.h:* {{'Check' has different definitions in different modules; definition in module 'Bad' first difference is function body}} +// expected-note@Box.h:* {{but in 'Box' found a different body}} +#endif + +#if defined(TEST5) +#include "Bad.h" +#include "Box.h" +#include "M1.h" +#include "M3.h" +// expected-error@Bad.h:* {{'Check' has different definitions in different modules; definition in module 'Bad' first difference is function body}} +// expected-note@Box.h:* {{but in 'Box' found a different body}} +#endif + + +void Run() { + Box<> Present; +} diff --git a/test/Modules/odr_hash-Unresolved.cpp b/test/Modules/odr_hash-Unresolved.cpp new file mode 100644 index 0000000000000..0c73b50f7085c --- /dev/null +++ b/test/Modules/odr_hash-Unresolved.cpp @@ -0,0 +1,14 @@ +// RUN: rm -rf %t + +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/modules.cache \ +// RUN: -I %S/Inputs/odr_hash-Unresolved \ +// RUN: -fmodules \ +// RUN: -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t/modules.cache \ +// RUN: -fmodules-local-submodule-visibility \ +// RUN: -std=c++11 -x c++ %s -fsyntax-only + +// Note: There is no -verify in the run line because some error messages are +// not captured from the module building stage. + +#include "Module2/include.h" diff --git a/test/Modules/odr_hash-blocks.cpp b/test/Modules/odr_hash-blocks.cpp new file mode 100644 index 0000000000000..07dfa4ce2ac88 --- /dev/null +++ b/test/Modules/odr_hash-blocks.cpp @@ -0,0 +1,119 @@ +// Clear and create directories +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: mkdir %t/cache +// RUN: mkdir %t/Inputs + +// Build first header file +// RUN: echo "#define FIRST" >> %t/Inputs/first.h +// RUN: cat %s >> %t/Inputs/first.h + +// Build second header file +// 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++11 -fblocks %t/Inputs/first.h +// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 -fblocks %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 +// RUN: echo "}" >> %t/Inputs/module.map +// RUN: echo "module SecondModule {" >> %t/Inputs/module.map +// RUN: echo " header \"second.h\"" >> %t/Inputs/module.map +// RUN: echo "}" >> %t/Inputs/module.map + +// Run test +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t/cache -x c++ -I%t/Inputs \ +// RUN: -verify %s -std=c++11 -fblocks + +#if !defined(FIRST) && !defined(SECOND) +#include "first.h" +#include "second.h" +#endif + +// Used for testing +#if defined(FIRST) +#define ACCESS public: +#elif defined(SECOND) +#define ACCESS private: +#endif + +// TODO: S1, S2, and S3 should generate errors. +namespace Blocks { +#if defined(FIRST) +struct S1 { + void (^block)(int x) = ^(int x) { }; +}; +#elif defined(SECOND) +struct S1 { + void (^block)(int x) = ^(int y) { }; +}; +#else +S1 s1; +#endif + +#if defined(FIRST) +struct S2 { + int (^block)(int x) = ^(int x) { return x + 1; }; +}; +#elif defined(SECOND) +struct S2 { + int (^block)(int x) = ^(int x) { return x; }; +}; +#else +S2 s2; +#endif + +#if defined(FIRST) +struct S3 { + void run(int (^block)(int x)); +}; +#elif defined(SECOND) +struct S3 { + void run(int (^block)(int x, int y)); +}; +#else +S3 s3; +#endif + +#define DECLS \ + int (^block)(int x) = ^(int x) { return x + x; }; \ + void run(int (^block)(int x, int y)); + +#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:* {{'Blocks::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 +} + +// Keep macros contained to one file. +#ifdef FIRST +#undef FIRST +#endif + +#ifdef SECOND +#undef SECOND +#endif + +#ifdef ACCESS +#undef ACCESS +#endif diff --git a/test/Modules/odr_hash-elaborated-types.cpp b/test/Modules/odr_hash-elaborated-types.cpp new file mode 100644 index 0000000000000..7dd11ac6d7f90 --- /dev/null +++ b/test/Modules/odr_hash-elaborated-types.cpp @@ -0,0 +1,12 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -std=c++1z -I%S/Inputs/odr_hash-elaborated-types -verify %s +// RUN: %clang_cc1 -std=c++1z -fmodules -fmodules-local-submodule-visibility -fmodule-map-file=%S/Inputs/odr_hash-elaborated-types/module.modulemap -fmodules-cache-path=%t -x c++ -I%S/Inputs/odr_hash-elaborated-types -verify %s + +#include "textual_stat.h" + +#include "first.h" +#include "second.h" + +void use() { struct stat value; } + +// expected-no-diagnostics diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp index 054e41a9eaea6..16ddfefa53c79 100644 --- a/test/Modules/odr_hash.cpp +++ b/test/Modules/odr_hash.cpp @@ -660,6 +660,202 @@ Invalid1* i1; #undef DECLS } // namespace Method +namespace MethodBody { +#if defined(FIRST) +struct S1 { + int A() { return 0; } +}; +#elif defined(SECOND) +struct S1 { + int A() { return 0; } +}; +#else +S1 s1; +#endif + +#if defined(FIRST) +struct S2 { + int BothBodies() { return 0; } +}; +#elif defined(SECOND) +struct S2 { + int BothBodies() { return 1; } +}; +#else +S2 s2; +// expected-error@first.h:* {{'MethodBody::S2' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'BothBodies' with body}} +// expected-note@second.h:* {{but in 'SecondModule' found method 'BothBodies' with different body}} +#endif + +#if defined(FIRST) +struct S3 { + int FirstBody() { return 0; } +}; +#elif defined(SECOND) +struct S3 { + int FirstBody(); +}; +#else +S3 s3; +// expected-error@first.h:* {{'MethodBody::S3' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'FirstBody' with body}} +// expected-note@second.h:* {{but in 'SecondModule' found method 'FirstBody' with no body}} +#endif + +#if defined(FIRST) +struct S4 { + int SecondBody(); +}; +#elif defined(SECOND) +struct S4 { + int SecondBody() { return 0; } +}; +#else +S4 s4; +// expected-error@first.h:* {{'MethodBody::S4' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'SecondBody' with no body}} +// expected-note@second.h:* {{but in 'SecondModule' found method 'SecondBody' with body}} +#endif + +#if defined(FIRST) +struct S5 { + int FirstBodySecondOutOfLine() { return 0; } +}; +#elif defined(SECOND) +struct S5 { + int FirstBodySecondOutOfLine(); +}; +int S5::FirstBodySecondOutOfLine() { return 0; } +#else +S5 s5; +// expected-error@second.h:* {{'MethodBody::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'FirstBodySecondOutOfLine' with no body}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'FirstBodySecondOutOfLine' with body}} +#endif + +#if defined(FIRST) +struct S6 { + int FirstOutOfLineSecondBody(); +}; +int S6::FirstOutOfLineSecondBody() { return 0; } +#elif defined(SECOND) +struct S6 { + int FirstOutOfLineSecondBody() { return 0; } +}; +#else +S6 s6; +// expected-error@first.h:* {{'MethodBody::S6' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'FirstOutOfLineSecondBody' with no body}} +// expected-note@second.h:* {{but in 'SecondModule' found method 'FirstOutOfLineSecondBody' with body}} +#endif + +#if defined(FIRST) +struct S7 { + int BothOutOfLine(); +}; +int S7::BothOutOfLine() { return 1; } +#elif defined(SECOND) +struct S7 { + int BothOutOfLine(); +}; +int S7::BothOutOfLine() { return 0; } +#else +S7 s7; +// expected-error@second.h:* {{'MethodBody::S7::BothOutOfLine' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} +// expected-note@first.h:* {{but in 'FirstModule' found a different body}} +#endif + +#if defined(FIRST) +struct S8 { + int FirstBodySecondOutOfLine() { return 0; } +}; +#elif defined(SECOND) +struct S8 { + int FirstBodySecondOutOfLine(); +}; +int S8::FirstBodySecondOutOfLine() { return 1; } +#else +S8 s8; +// expected-error@second.h:* {{'MethodBody::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'FirstBodySecondOutOfLine' with no body}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'FirstBodySecondOutOfLine' with body}} +#endif + +#if defined(FIRST) +struct S9 { + int FirstOutOfLineSecondBody(); +}; +int S9::FirstOutOfLineSecondBody() { return 1; } +#elif defined(SECOND) +struct S9 { + int FirstOutOfLineSecondBody() { return 0; } +}; +#else +S9 s9; +// expected-error@first.h:* {{'MethodBody::S9' has different definitions in different modules; first difference is definition in module 'FirstModule' found method 'FirstOutOfLineSecondBody' with no body}} +// expected-note@second.h:* {{but in 'SecondModule' found method 'FirstOutOfLineSecondBody' with body}} +#endif + +#if defined(FIRST) +struct S10 { + S10(int); + S10() = delete; +}; +#elif defined(SECOND) +struct S10 { + S10(int); + S10(); +}; +#else +S10 s10(10); +// expected-error@first.h:* {{'MethodBody::S10' has different definitions in different modules; first difference is definition in module 'FirstModule' found constructor is deleted}} +// expected-note@second.h:* {{but in 'SecondModule' found constructor is not deleted}} +#endif + +#if defined(FIRST) +struct S11 { + S11() = default; +}; +#elif defined(SECOND) +struct S11 { + S11(); +}; +#else +S11 s11; +// expected-error@first.h:* {{'MethodBody::S11' has different definitions in different modules; first difference is definition in module 'FirstModule' found constructor is defaulted}} +// expected-note@second.h:* {{but in 'SecondModule' found constructor is not defaulted}} +#endif + +#define DECLS(CLASSNAME) \ + CLASSNAME() = default; \ + ~CLASSNAME() = delete; \ + void A(); \ + void B() { return; }; \ + void C(); \ + void D(); + +#define OUTOFLINEDEFS(CLASSNAME) \ + void CLASSNAME::C() {} \ + void CLASSNAME::D() { return; } + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS(Valid1) +}; +OUTOFLINEDEFS(Valid1) +#else +Valid1* v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS(Invalid1) + ACCESS +}; +OUTOFLINEDEFS(Invalid1) +#else +Invalid1* i1; +// expected-error@first.h:* {{'MethodBody::Invalid1' has different definitions in different modules; first difference is definition in module 'FirstModule' found public access specifier}} +// expected-note@second.h:* {{but in 'SecondModule' found private access specifier}} +#endif +#undef DECLS +} // namespace MethodBody + namespace Constructor { #if defined(FIRST) struct S1 { @@ -1635,6 +1831,96 @@ S6 s6; // expected-note@first.h:* {{but in 'FirstModule' found field 'x'}} #endif +#if defined(FIRST) +struct S7 { + template<int> void run() {} + template<> void run<1>() {} +}; +#elif defined(SECOND) +struct S7 { + template<int> void run() {} + void run() {} +}; +#else +S7 s7; +// expected-error@second.h:* {{'TemplateArgument::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'run' with no template arguments}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'run' with template arguments}} +#endif + +#if defined(FIRST) +struct S8 { + static int a, b; + template<int&> void run() {} + template<int&, int&> void run() {} + template<> void run<a>() {} +}; +#elif defined(SECOND) +struct S8 { + static int a, b; + template<int&> void run() {} + template<int&, int&> void run() {} + template<> void run<a, b>() {} +}; +#else +S8 s8; +// expected-error@second.h:* {{'TemplateArgument::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'run' with 2 template arguments}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'run' with 1 template argument}} +#endif + +#if defined(FIRST) +struct S9 { + static int a, b; + template<int&> void run() {} + template<> void run<a>() {} +}; +#elif defined(SECOND) +struct S9 { + static int a, b; + template<int&> void run() {} + template<> void run<b>() {} +}; +#else +S9 s9; +// expected-error@second.h:* {{'TemplateArgument::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'run' with 'b' for 1st template argument}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'run' with 'a' for 1st template argument}} +#endif + +#if defined(FIRST) +struct S10 { + static int a, b; + template<int, int&...> void run() {} + template<> void run<1, a>() {} +}; +#elif defined(SECOND) +struct S10 { + static int a, b; + template<int, int&...> void run() {} + template<> void run<1, b>() {} +}; +#else +S10 s10; +// expected-error@second.h:* {{'TemplateArgument::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'run' with 'b' for 2nd template argument}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'run' with 'a' for 2nd template argument}} +#endif + +#if defined(FIRST) +struct S11 { + static int a, b; + template<int, int&...> void run() {} + template<> void run<1, a>() {} +}; +#elif defined(SECOND) +struct S11 { + static int a, b; + template<int, int&...> void run() {} + template<> void run<1, a, a>() {} +}; +#else +S11 s11; +// expected-error@second.h:* {{'TemplateArgument::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'run' with 3 template arguments}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'run' with 2 template arguments}} +#endif + #define DECLS \ OneClass<int> a; \ OneInt<1> b; \ @@ -1642,7 +1928,20 @@ S6 s6; using d = OneInt<2>; \ using e = OneInt<2 + 2>; \ OneTemplateClass<OneClass> f; \ - OneTemplateInt<OneInt> g; + OneTemplateInt<OneInt> g; \ + static int i1, i2; \ + template <int &> \ + void Function() {} \ + template <int &, int &> \ + void Function() {} \ + template <> \ + void Function<i1>() {} \ + template <> \ + void Function<i2>() {} \ + template <> \ + void Function<i1, i2>() {} \ + template <> \ + void Function<i2, i1>() {} #if defined(FIRST) || defined(SECOND) template <class> struct OneClass{}; @@ -2286,6 +2585,737 @@ Invalid1 i1; #undef DECLS } // namespace BaseClass +namespace PointersAndReferences { +#if defined(FIRST) || defined(SECOND) +template<typename> struct Wrapper{}; +#endif + +#if defined(FIRST) +struct S1 { + Wrapper<int*> x; +}; +#elif defined(SECOND) +struct S1 { + Wrapper<float*> x; +}; +#else +S1 s1; +// expected-error@first.h:* {{PointersAndReferences::S1::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif + +#if defined(FIRST) +struct S2 { + Wrapper<int &&> x; +}; +#elif defined(SECOND) +struct S2 { + Wrapper<float &&> x; +}; +#else +S2 s2; +// expected-error@first.h:* {{PointersAndReferences::S2::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S2' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif + +#if defined(FIRST) +struct S3 { + Wrapper<int *> x; +}; +#elif defined(SECOND) +struct S3 { + Wrapper<float *> x; +}; +#else +S3 s3; +// expected-error@first.h:* {{PointersAndReferences::S3::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S3' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif + +#if defined(FIRST) +struct S4 { + Wrapper<int &> x; +}; +#elif defined(SECOND) +struct S4 { + Wrapper<float &> x; +}; +#else +S4 s4; +// expected-error@first.h:* {{PointersAndReferences::S4::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S4' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif + +#if defined(FIRST) +struct S5 { + Wrapper<S5 *> x; +}; +#elif defined(SECOND) +struct S5 { + Wrapper<const S5 *> x; +}; +#else +S5 s5; +// expected-error@second.h:* {{'PointersAndReferences::S5::x' from module 'SecondModule' is not present in definition of 'PointersAndReferences::S5' in module 'FirstModule'}} +// expected-note@first.h:* {{declaration of 'x' does not match}} +#endif + +#if defined(FIRST) +struct S6 { + Wrapper<int &> x; +}; +#elif defined(SECOND) +struct S6 { + Wrapper<const int &> x; +}; +#else +S6 s6; +// expected-error@first.h:* {{PointersAndReferences::S6::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S6' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} +#endif + +#define DECLS \ + Wrapper<int *> x1; \ + Wrapper<float *> x2; \ + Wrapper<const float *> x3; \ + Wrapper<int &> x4; \ + Wrapper<int &&> x5; \ + Wrapper<const int &> x6; \ + Wrapper<S1 *> x7; \ + Wrapper<S1 &> x8; \ + Wrapper<S1 &&> x9; + +#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:* {{'PointersAndReferences::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 PointersAndReferences + +namespace FunctionTemplate { +#if defined(FIRST) +struct S1 { + template <int, int> void foo(); +}; +#elif defined(SECOND) +struct S1 { + template <int> void foo(); +}; +#else +S1 s1; +// expected-error@first.h:* {{'FunctionTemplate::S1::foo' from module 'FirstModule' is not present in definition of 'FunctionTemplate::S1' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'foo' does not match}} +#endif + +#if defined(FIRST) +struct S2 { + template <char> void foo(); +}; +#elif defined(SECOND) +struct S2 { + template <int> void foo(); +}; +#else +S2 s2; +// expected-error@first.h:* {{'FunctionTemplate::S2::foo' from module 'FirstModule' is not present in definition of 'FunctionTemplate::S2' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'foo' does not match}} +#endif + +#if defined(FIRST) +struct S3 { + template <int x> void foo(); +}; +#elif defined(SECOND) +struct S3 { + template <int y> void foo(); +}; +#else +S3 s3; +// expected-error@second.h:* {{'FunctionTemplate::S3' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter named 'y'}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter named 'x'}} +#endif + +#if defined(FIRST) +struct S4 { + template <int x> void foo(); +}; +#elif defined(SECOND) +struct S4 { + template <int x> void bar(); +}; +#else +S4 s4; +// expected-error@first.h:* {{'FunctionTemplate::S4::foo' from module 'FirstModule' is not present in definition of 'FunctionTemplate::S4' in module 'SecondModule'}} +// expected-note@second.h:* {{definition has no member 'foo'}} +#endif + +#if defined(FIRST) +struct S5 { + template <int x> void foo(); +}; +#elif defined(SECOND) +struct S5 { + public: + template <int x> void foo(); +}; +#else +S5 s5; +// expected-error@second.h:* {{'FunctionTemplate::S5' 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 function template}} +#endif + +#if defined(FIRST) +struct S6 { + template <typename x = int> void foo(); +}; +#elif defined(SECOND) +struct S6 { + template <typename x> void foo(); +}; +#else +S6 s6; +// expected-error@second.h:* {{'FunctionTemplate::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with no default argument}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument}} +#endif + +#if defined(FIRST) +struct S7 { + template <typename x = void> void foo(); +}; +#elif defined(SECOND) +struct S7 { + template <typename x = int> void foo(); +}; +#else +S7 s7; +// expected-error@second.h:* {{'FunctionTemplate::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument 'int'}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument 'void'}} +#endif + +#if defined(FIRST) +template <int> +struct U8 {}; +struct S8 { + template <template<int> class x = U8> void foo(); +}; +#elif defined(SECOND) +template <int> +struct T8 {}; +struct S8{ + template <template<int> class x = T8> void foo(); +}; +#else +S8 s8; +// expected-error@second.h:* {{'FunctionTemplate::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument 'T8'}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument 'U8'}} +#endif + +#if defined(FIRST) +template <int> +struct U9 {}; +struct S9 { S9(); + template <template<int> class x = U9> void foo(); +}; +#elif defined(SECOND) +struct S9 { S9(); + template <template<int> class x> void foo(); +}; +#else +S9 s9; +// expected-error@second.h:* {{'FunctionTemplate::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with no default argument}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument}} +#endif + +#if defined(FIRST) +struct S10 { + template <template<int> class x> void foo(); + template <template<typename> class x> void foo(); +}; +#elif defined(SECOND) +struct S10 { + template <template<typename> class x> void foo(); + template <template<int> class x> void foo(); +}; +#else +S10 s10; +// expected-error@second.h:* {{'FunctionTemplate::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with one type}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with different type}} +#endif + +#if defined(FIRST) +struct S11 { + template <template<int> class x> void foo(); +}; +#elif defined(SECOND) +struct S11 { + template <template<int> class> void foo(); +}; +#else +S11 s11; +// expected-error@second.h:* {{'FunctionTemplate::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with no name}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter named 'x'}} +#endif + +#if defined(FIRST) +struct S12 { + template <class> void foo(); + template <class, class> void foo(); +}; +#elif defined(SECOND) +struct S12 { + template <class, class> void foo(); + template <class> void foo(); +}; +#else +S12 s12; +// expected-error@second.h:* {{'FunctionTemplate::S12' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 2 template parameters}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1 template parameter}} +#endif + +#if defined(FIRST) +struct S13 { + template <class = int> void foo(); +}; +#elif defined(SECOND) +struct S13 { + template <class = void> void foo(); +}; +#else +S13 s13; +// expected-error@second.h:* {{'FunctionTemplate::S13' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument 'void'}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument 'int'}} +#endif + +#if defined(FIRST) +struct S14 { + template <class = void> void foo(); +}; +#elif defined(SECOND) +struct S14 { + template <class> void foo(); +}; +#else +S14 s14; +// expected-error@second.h:* {{'FunctionTemplate::S14' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with no default argument}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument}} +#endif + +#if defined(FIRST) +struct S15 { + template <class> void foo(); +}; +#elif defined(SECOND) +struct S15 { + template <class = void> void foo(); +}; +#else +S15 s15; +// expected-error@second.h:* {{'FunctionTemplate::S15' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with no default argument}} +#endif + +#if defined(FIRST) +struct S16 { + template <short> void foo(); +}; +#elif defined(SECOND) +struct S16 { + template <short = 1> void foo(); +}; +#else +S16 s16; +// expected-error@second.h:* {{'FunctionTemplate::S16' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with no default argument}} +#endif + +#if defined(FIRST) +struct S17 { + template <short = 2> void foo(); +}; +#elif defined(SECOND) +struct S17 { + template <short = 1 + 1> void foo(); +}; +#else +S17 s17; +// expected-error@second.h:* {{'FunctionTemplate::S17' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with default argument 1 + 1}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with default argument 2}} +#endif + +#if defined(FIRST) +struct S18 { + template <short> void foo(); + template <int> void foo(); +}; +#elif defined(SECOND) +struct S18 { + template <int> void foo(); + template <short> void foo(); +}; +#else +S18 s18; +// expected-error@second.h:* {{'FunctionTemplate::S18' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter with one type}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter with different type}} +#endif + +#if defined(FIRST) +struct S19 { + template <short> void foo(); + template <short...> void foo(); +}; +#elif defined(SECOND) +struct S19 { + template <short...> void foo(); + template <short> void foo(); +}; +#else +S19 s19; +// expected-error@second.h:* {{'FunctionTemplate::S19' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter being a template parameter pack}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter not being a template parameter pack}} +#endif + +#if defined(FIRST) +struct S20 { + template <class> void foo(); + template <class...> void foo(); +}; +#elif defined(SECOND) +struct S20 { + template <class...> void foo(); + template <class> void foo(); +}; +#else +S20 s20; +// expected-error@second.h:* {{'FunctionTemplate::S20' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter being a template parameter pack}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter not being a template parameter pack}} +#endif + +#if defined(FIRST) +struct S21 { + template <template<class> class...> void foo(); + template <template<class> class> void foo(); +}; +#elif defined(SECOND) +struct S21 { + template <template<class> class> void foo(); + template <template<class> class...> void foo(); +}; +#else +S21 s21; +// expected-error@second.h:* {{'FunctionTemplate::S21' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter not being a template parameter pack}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template parameter being a template parameter pack}} +#endif + +#if defined(FIRST) +struct S22 { + template <template<class> class> void foo(); + template <class> void foo(); + template <int> void foo(); +}; +#elif defined(SECOND) +struct S22 { + template <class> void foo(); + template <int> void foo(); + template <template<class> class> void foo(); +}; +#else +S22 s22; +// expected-error@second.h:* {{'FunctionTemplate::S22' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter being a type template parameter}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template paramter being a template template parameter}} +#endif + +#if defined(FIRST) +struct S23 { + template <class> void foo(); + template <int> void foo(); + template <template<class> class> void foo(); +}; +#elif defined(SECOND) +struct S23 { + template <int> void foo(); + template <template<class> class> void foo(); + template <class> void foo(); +}; +#else +S23 s23; +// expected-error@second.h:* {{'FunctionTemplate::S23' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter being a non-type template parameter}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template paramter being a type template parameter}} +#endif + +#if defined(FIRST) +struct S24 { + template <int> void foo(); + template <template<class> class> void foo(); + template <class> void foo(); +}; +#elif defined(SECOND) +struct S24 { + template <template<class> class> void foo(); + template <class> void foo(); + template <int> void foo(); +}; +#else +S24 s24; +// expected-error@second.h:* {{'FunctionTemplate::S24' has different definitions in different modules; first difference is definition in module 'SecondModule' found function template 'foo' with 1st template parameter being a template template parameter}} +// expected-note@first.h:* {{but in 'FirstModule' found function template 'foo' with 1st template paramter being a non-type template parameter}} +#endif + +#if defined(FIRST) +struct S25 { + template <int> void foo(); +}; +#elif defined(SECOND) +struct S25 { + public: + template <int> void foo(); +}; +#else +S25 s25; +// expected-error@second.h:* {{'FunctionTemplate::S25' 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 function template}} +#endif + +#define DECLS \ + template <int> \ + void nontype1(); \ + template <int x> \ + void nontype2(); \ + template <int, int> \ + void nontype3(); \ + template <int x = 5> \ + void nontype4(); \ + template <int... x> \ + void nontype5(); \ + \ + template <class> \ + void type1(); \ + template <class x> \ + void type2(); \ + template <class, class> \ + void type3(); \ + template <class x = int> \ + void type4(); \ + template <class... x> \ + void type5(); \ + \ + template <template <int> class> \ + void template1(); \ + template <template <int> class x> \ + void template2(); \ + template <template <int> class, template <int> class> \ + void template3(); \ + template <template <int> class x = U> \ + void template4(); \ + template <template <int> class... x> \ + void template5(); + +#if defined(FIRST) || defined(SECOND) +template<int> +struct U {}; +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'FunctionTemplate::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 Enums { +#if defined(FIRST) +enum E1 { x11 }; +#elif defined(SECOND) +enum E1 {}; +#else +E1 e1; +// expected-error@first.h:* {{'Enums::x11' from module 'FirstModule' is not present in definition of 'Enums::E1' in module 'SecondModule'}} +// expected-note@second.h:* {{definition has no member 'x11'}} +#endif + +#if defined(FIRST) +enum E2 {}; +#elif defined(SECOND) +enum E2 { x21 }; +#else +E2 e2; +// expected-error@second.h:* {{'Enums::E2' has different definitions in different modules; definition in module 'SecondModule' first difference is enum with 1 element}} +// expected-note@first.h:* {{but in 'FirstModule' found enum with 0 elements}} +#endif + +#if defined(FIRST) +enum E3 { x31 }; +#elif defined(SECOND) +enum E3 { x32 }; +#else +E3 e3; +// expected-error@first.h:* {{'Enums::x31' from module 'FirstModule' is not present in definition of 'Enums::E3' in module 'SecondModule'}} +// expected-note@second.h:* {{definition has no member 'x31'}} +#endif + +#if defined(FIRST) +enum E4 { x41 }; +#elif defined(SECOND) +enum E4 { x41, x42 }; +#else +E4 e4; +// expected-error@second.h:* {{'Enums::E4' has different definitions in different modules; definition in module 'SecondModule' first difference is enum with 2 elements}} +// expected-note@first.h:* {{but in 'FirstModule' found enum with 1 element}} +#endif + +#if defined(FIRST) +enum E5 { x51, x52 }; +#elif defined(SECOND) +enum E5 { x51 }; +#else +E5 e5; +// expected-error@first.h:* {{'Enums::x52' from module 'FirstModule' is not present in definition of 'Enums::E5' in module 'SecondModule'}} +// expected-note@second.h:* {{definition has no member 'x52'}} +#endif + +#if defined(FIRST) +enum E6 { x61, x62 }; +#elif defined(SECOND) +enum E6 { x62, x61 }; +#else +E6 e6; +// expected-error@second.h:* {{'Enums::E6' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st element has name 'x62'}} +// expected-note@first.h:* {{but in 'FirstModule' found 1st element has name 'x61'}} +#endif + +#if defined(FIRST) +enum E7 { x71 = 0 }; +#elif defined(SECOND) +enum E7 { x71 }; +#else +E7 e7; +// expected-error@second.h:* {{'Enums::E7' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st element 'x71' has an initilizer}} +// expected-note@first.h:* {{but in 'FirstModule' found 1st element 'x71' does not have an initializer}} +#endif + +#if defined(FIRST) +enum E8 { x81 }; +#elif defined(SECOND) +enum E8 { x81 = 0 }; +#else +E8 e8; +// expected-error@second.h:* {{'Enums::E8' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st element 'x81' does not have an initilizer}} +// expected-note@first.h:* {{but in 'FirstModule' found 1st element 'x81' has an initializer}} +#endif + +#if defined(FIRST) +enum E9 { x91 = 0, x92 = 1 }; +#elif defined(SECOND) +enum E9 { x91 = 0, x92 = 2 - 1 }; +#else +E9 e9; +// expected-error@second.h:* {{'Enums::E9' has different definitions in different modules; definition in module 'SecondModule' first difference is 2nd element 'x92' has an initializer}} +// expected-note@first.h:* {{but in 'FirstModule' found 2nd element 'x92' has different initializer}} +#endif + +#if defined(FIRST) +enum class E10 : int {}; +#elif defined(SECOND) +enum class E10 {}; +#else +E10 e10; +// expected-error@second.h:* {{'Enums::E10' has different definitions in different modules; definition in module 'SecondModule' first difference is enum without specified type}} +// expected-note@first.h:* {{but in 'FirstModule' found enum with specified type}} +#endif + +#if defined(FIRST) +enum E11 {}; +#elif defined(SECOND) +enum E11 : int {}; +#else +E11 e11; +// expected-error@second.h:* {{'Enums::E11' has different definitions in different modules; definition in module 'SecondModule' first difference is enum with specified type}} +// expected-note@first.h:* {{but in 'FirstModule' found enum without specified type}} +#endif + +#if defined(FIRST) +enum struct E12 : long {}; +#elif defined(SECOND) +enum struct E12 : int {}; +#else +E12 e12; +// expected-error@second.h:* {{'Enums::E12' has different definitions in different modules; definition in module 'SecondModule' first difference is enum with specified type 'int'}} +// expected-note@first.h:* {{but in 'FirstModule' found enum with specified type 'long'}} +#endif + +#if defined(FIRST) +enum struct E13 {}; +#elif defined(SECOND) +enum E13 {}; +#else +E13 e13; +// expected-error@second.h:* {{'Enums::E13' has different definitions in different modules; definition in module 'SecondModule' first difference is enum that is not scoped}} +// expected-note@first.h:* {{but in 'FirstModule' found enum that is scoped}} +#endif + +#if defined(FIRST) +enum E14 {}; +#elif defined(SECOND) +enum struct E14 {}; +#else +E14 e14; +// expected-error@second.h:* {{'Enums::E14' has different definitions in different modules; definition in module 'SecondModule' first difference is enum that is scoped}} +// expected-note@first.h:* {{but in 'FirstModule' found enum that is not scoped}} +#endif + +#if defined(FIRST) +enum class E15 {}; +#elif defined(SECOND) +enum struct E15 {}; +#else +E15 e15; +// expected-error@second.h:* {{'Enums::E15' has different definitions in different modules; definition in module 'SecondModule' first difference is enum scoped with keyword struct}} +// expected-note@first.h:* {{but in 'FirstModule' found enum scoped with keyword class}} +#endif + +#if defined(FIRST) +enum struct E16 {}; +#elif defined(SECOND) +enum class E16 {}; +#else +E16 e16; +// expected-error@second.h:* {{'Enums::E16' has different definitions in different modules; definition in module 'SecondModule' first difference is enum scoped with keyword class}} +// expected-note@first.h:* {{but in 'FirstModule' found enum scoped with keyword struct}} +#endif + +#if defined(FIRST) +enum Valid { v1 = (struct S*)0 == (struct S*)0 }; +#elif defined(SECOND) +struct S {}; +enum Valid { v1 = (struct S*)0 == (struct S*)0 }; +#else +Valid V; +#endif +} // namespace Enums // Collection of interesting cases below. @@ -2744,6 +3774,38 @@ struct S3 { #else S3 s3; #endif + +#if defined(FIRST) +using A4 = int; +using B4 = A4; +struct S4 { + B4 x; +}; +#elif defined(SECOND) +using A4 = int; +using B4 = ::MultipleTypedefs::A4; +struct S4 { + B4 x; +}; +#else +S4 s4; +#endif + +#if defined(FIRST) +using A5 = int; +using B5 = MultipleTypedefs::A5; +struct S5 { + B5 x; +}; +#elif defined(SECOND) +using A5 = int; +using B5 = ::MultipleTypedefs::A5; +struct S5 { + B5 x; +}; +#else +S5 s5; +#endif } // MultipleTypedefs namespace DefaultArguments { @@ -2922,8 +3984,63 @@ int I10 = F10(); #endif // expected-error@second.h:* {{'FunctionDecl::F10' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} // expected-note@first.h:* {{but in 'FirstModule' found a different body}} + +#if defined(FIRST) +struct S11 { + template <int> void foo(); +}; +#elif defined(SECOND) +struct S11 { + template <int> void foo(); +}; +template <int> void S11::foo() {} +#else +S11 s11; +#endif + +#if defined(FIRST) +struct S12 { + void foo(int x); +}; +#elif defined(SECOND) +struct S12 { + void foo(int x); +}; +void S12::foo(int y) {} +#else +S12 s12; +#endif + +#if defined(FIRST) +struct S13 { + void foo(int x); +}; +void S13::foo(int y) {} +#elif defined(SECOND) +struct S13 { + void foo(int x); +}; +void S13::foo(int y) {} +#else +S13 s13; +#endif } // namespace FunctionDecl +namespace DeclTemplateArguments { +#if defined(FIRST) +int foo() { return 1; } +int bar() { return foo(); } +#elif defined(SECOND) +template <class T = int> +int foo() { return 2; } +int bar() { return foo<>(); } +#else +int num = bar(); +// expected-error@second.h:* {{'DeclTemplateArguments::bar' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}} +// expected-note@first.h:* {{but in 'FirstModule' found a different body}} +#endif +} + // Keep macros contained to one file. #ifdef FIRST #undef FIRST diff --git a/test/Modules/pr27401.cpp b/test/Modules/pr27401.cpp index 7d5479cb92434..8db3bbb0094af 100644 --- a/test/Modules/pr27401.cpp +++ b/test/Modules/pr27401.cpp @@ -1,6 +1,7 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR27401 -verify %s // RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR27401/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR27401 -verify %s +// RUN: %clang_cc1 -std=c++11 -fmodules -fmodule-map-file=%S/Inputs/PR27401/module.modulemap -fmodules-cache-path=%t -I%S/Inputs/PR27401 -verify %s -triple i686-windows #include "a.h" #define _LIBCPP_VECTOR diff --git a/test/Modules/protocol-redefinition.m b/test/Modules/protocol-redefinition.m new file mode 100644 index 0000000000000..85a957bbfd70a --- /dev/null +++ b/test/Modules/protocol-redefinition.m @@ -0,0 +1,6 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F%S/Inputs/protocol-redefinition -fsyntax-only %s -Wno-private-module -verify + +// expected-no-diagnostics + +@import Kit; diff --git a/test/Modules/requires.m b/test/Modules/requires.m index 4a83d0c2b0ec1..d8f54b495089c 100644 --- a/test/Modules/requires.m +++ b/test/Modules/requires.m @@ -1,6 +1,7 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -I %S/Inputs %s -verify -fmodule-feature custom_req1 - +// RUN: %clang_cc1 -Wauto-import -Wno-private-module -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs -I %S/Inputs %s -verify -std=c89 -DTEST_C_FEATURES +#ifndef TEST_C_FEATURES // expected-error@DependsOnModule.framework/module.map:7 {{module 'DependsOnModule.CXX' requires feature 'cplusplus'}} @import DependsOnModule.CXX; // expected-note {{module imported here}} @import DependsOnModule.NotCXX; @@ -15,3 +16,17 @@ @import RequiresWithMissingHeader.HeaderBefore; // expected-note {{module imported here}} // expected-error@module.map:* {{module 'RequiresWithMissingHeader.HeaderAfter' requires feature 'missing'}} @import RequiresWithMissingHeader.HeaderAfter; // expected-note {{module imported here}} +// expected-error@DependsOnModule.framework/module.map:40 {{module 'DependsOnModule.CXX11' requires feature 'cplusplus11'}} +@import DependsOnModule.CXX11; // expected-note {{module imported here}} +// expected-error@DependsOnModule.framework/module.map:43 {{module 'DependsOnModule.CXX14' requires feature 'cplusplus14'}} +@import DependsOnModule.CXX14; // expected-note {{module imported here}} +// expected-error@DependsOnModule.framework/module.map:46 {{module 'DependsOnModule.CXX17' requires feature 'cplusplus17'}} +@import DependsOnModule.CXX17; // expected-note {{module imported here}} +#else +// expected-error@DependsOnModule.framework/module.map:49 {{module 'DependsOnModule.C99' requires feature 'c99'}} +@import DependsOnModule.C99; // expected-note {{module imported here}} +// expected-error@DependsOnModule.framework/module.map:52 {{module 'DependsOnModule.C11' requires feature 'c11'}} +@import DependsOnModule.C11; // expected-note {{module imported here}} +// expected-error@DependsOnModule.framework/module.map:55 {{module 'DependsOnModule.C17' requires feature 'c17'}} +@import DependsOnModule.C17; // expected-note {{module imported here}} +#endif diff --git a/test/Modules/self-referencing-lambda.cpp b/test/Modules/self-referencing-lambda.cpp new file mode 100644 index 0000000000000..1e75d446ebb54 --- /dev/null +++ b/test/Modules/self-referencing-lambda.cpp @@ -0,0 +1,5 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/self-referencing-lambda %s -verify -emit-obj -std=c++14 -o %t2.o +// expected-no-diagnostics + +#include "a.h" diff --git a/test/Modules/shadow.m b/test/Modules/shadow.m new file mode 100644 index 0000000000000..44320af2b0c66 --- /dev/null +++ b/test/Modules/shadow.m @@ -0,0 +1,21 @@ +// RUN: rm -rf %t +// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/shadow/A1 -I %S/Inputs/shadow/A2 %s -fsyntax-only 2>&1 | FileCheck %s -check-prefix=REDEFINITION +// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap -fmodule-map-file=%S/Inputs/shadow/A2/module.modulemap %s -fsyntax-only 2>&1 | FileCheck %s -check-prefix=REDEFINITION +// REDEFINITION: error: redefinition of module 'A' +// REDEFINITION: note: previously defined + +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap -I %S/Inputs/shadow %s -verify + +@import A1; +@import A2; +@import A; + +#import "A2/A.h" // expected-note {{implicitly imported}} +// expected-error@A2/module.modulemap:1 {{import of shadowed module 'A'}} +// expected-note@A1/module.modulemap:1 {{previous definition}} + +#if defined(A2_A_h) +#error got the wrong definition of module A +#elif !defined(A1_A_h) +#error missing definition from A1 +#endif diff --git a/test/Modules/shadowed-submodule.m b/test/Modules/shadowed-submodule.m new file mode 100644 index 0000000000000..c9c77bd13a1ca --- /dev/null +++ b/test/Modules/shadowed-submodule.m @@ -0,0 +1,5 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/shadowed-submodule/Foo -I %S/Inputs/shadowed-submodule/A2 %s -verify + +@import Foo; // expected-error {{module 'A' was built in directory}} + // expected-note@shadowed-submodule.m:4 {{imported by module 'Foo'}} diff --git a/test/Modules/submodule-in-private-mmap.m b/test/Modules/submodule-in-private-mmap.m new file mode 100644 index 0000000000000..50e50108757f1 --- /dev/null +++ b/test/Modules/submodule-in-private-mmap.m @@ -0,0 +1,7 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F%S/Inputs/submodule-in-private-mmap -fsyntax-only %s -Wno-private-module -verify + +// expected-no-diagnostics + +@import A.Private; +@import A.SomeSub; diff --git a/test/Modules/target-features.m b/test/Modules/target-features.m index b4524835f5341..b2597960cbd03 100644 --- a/test/Modules/target-features.m +++ b/test/Modules/target-features.m @@ -1,6 +1,7 @@ // REQUIRES: x86-registered-target // REQUIRES: arm-registered-target // REQUIRES: aarch64-registered-target +// REQUIRES: riscv-registered-target // RUN: rm -rf %t @@ -17,6 +18,10 @@ // RUN: FileCheck %s -check-prefix=X86_32 < %t.x86_32 // RUN: not %clang_cc1 -triple x86_64-unknown-unknown -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs -fsyntax-only %s 2> %t.x86_64 // RUN: FileCheck %s -check-prefix=X86_64 < %t.x86_64 +// RUN: not %clang_cc1 -triple riscv32-unknown-unknown -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs -fsyntax-only %s 2> %t.riscv32 +// RUN: FileCheck %s -check-prefix=RISCV32 < %t.riscv32 +// RUN: not %clang_cc1 -triple riscv64-unknown-unknown -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I %S/Inputs -fsyntax-only %s 2> %t.riscv64 +// RUN: FileCheck %s -check-prefix=RISCV64 < %t.riscv64 #ifndef SANITY_CHECK @import TargetFeatures; @@ -24,16 +29,22 @@ // AARCH64-NOT: module 'TargetFeatures' requires // X86_32-NOT: module 'TargetFeatures' requires // X86_64-NOT: module 'TargetFeatures' requires +// RISCV32-NOT: module 'TargetFeatures' requires +// RISCV64-NOT: module 'TargetFeatures' requires @import TargetFeatures.arm; // AARCH32-NOT: module 'TargetFeatures.arm' requires // AARCH64-NOT: module 'TargetFeatures.arm' requires // X86_32: module 'TargetFeatures.arm' requires feature 'arm' // X86_64: module 'TargetFeatures.arm' requires feature 'arm' +// RISCV32: module 'TargetFeatures.arm' requires +// RISCV64: module 'TargetFeatures.arm' requires @import TargetFeatures.arm.aarch32; // AARCH32-NOT: module 'TargetFeatures.arm.aarch32' requires // AARCH64: module 'TargetFeatures.arm.aarch32' requires feature 'aarch32' // X86_32: module 'TargetFeatures.arm.aarch32' requires feature // X86_64: module 'TargetFeatures.arm.aarch32' requires feature +// RISCV32: module 'TargetFeatures.arm.aarch32' requires feature +// RISCV64: module 'TargetFeatures.arm.aarch32' requires feature #endif @import TargetFeatures.arm.aarch64; @@ -41,6 +52,8 @@ // AARCH64-NOT: module 'TargetFeatures.arm.aarch64' requires // X86_32: module 'TargetFeatures.arm.aarch64' requires feature // X86_64: module 'TargetFeatures.arm.aarch64' requires feature +// RISCV32: module 'TargetFeatures.arm.aarch64' requires feature +// RISCV64: module 'TargetFeatures.arm.aarch64' requires feature #ifndef SANITY_CHECK @import TargetFeatures.x86; @@ -48,14 +61,41 @@ // AARCH64: module 'TargetFeatures.x86' requires feature 'x86' // X86_32-NOT: module 'TargetFeatures.x86' requires // X86_64-NOT: module 'TargetFeatures.x86' requires +// RISCV32: module 'TargetFeatures.x86' requires feature 'x86' +// RISCV64: module 'TargetFeatures.x86' requires feature 'x86' @import TargetFeatures.x86.x86_32; // AARCH32: module 'TargetFeatures.x86.x86_32' requires feature // AARCH64: module 'TargetFeatures.x86.x86_32' requires feature // X86_32-NOT: module 'TargetFeatures.x86.x86_32' requires // X86_64: module 'TargetFeatures.x86.x86_32' requires feature 'x86_32' +// RISCV32: module 'TargetFeatures.x86.x86_32' requires feature +// RISCV64: module 'TargetFeatures.x86.x86_32' requires feature @import TargetFeatures.x86.x86_64; // AARCH32: module 'TargetFeatures.x86.x86_64' requires feature // AARCH64: module 'TargetFeatures.x86.x86_64' requires feature // X86_32: module 'TargetFeatures.x86.x86_64' requires feature 'x86_64' // X86_64-NOT: module 'TargetFeatures.x86.x86_64' requires +// RISCV32: module 'TargetFeatures.x86.x86_64' requires feature +// RISCV64: module 'TargetFeatures.x86.x86_64' requires feature +@import TargetFeatures.riscv; +// AARCH32: module 'TargetFeatures.riscv' requires feature +// AARCH64: module 'TargetFeatures.riscv' requires feature +// X86_32: module 'TargetFeatures.riscv' requires feature +// X86_64: module 'TargetFeatures.riscv' requires feature +// RISCV32-NOT: module 'TargetFeatures.riscv' requires feature +// RISCV64-NOT: module 'TargetFeatures.riscv' requires feature +@import TargetFeatures.riscv.riscv32; +// AARCH32: module 'TargetFeatures.riscv.riscv32' requires feature +// AARCH64: module 'TargetFeatures.riscv.riscv32' requires feature +// X86_32: module 'TargetFeatures.riscv.riscv32' requires feature +// X86_64: module 'TargetFeatures.riscv.riscv32' requires feature +// RISCV32-NOT: module 'TargetFeatures.riscv.riscv32' requires feature +// RISCV64: module 'TargetFeatures.riscv.riscv32' requires feature 'riscv32' +@import TargetFeatures.riscv.riscv64; +// AARCH32: module 'TargetFeatures.riscv.riscv64' requires feature +// AARCH64: module 'TargetFeatures.riscv.riscv64' requires feature +// X86_32: module 'TargetFeatures.riscv.riscv64' requires feature +// X86_64: module 'TargetFeatures.riscv.riscv64' requires feature +// RISCV32: module 'TargetFeatures.riscv.riscv64' requires feature 'riscv64' +// RISCV64-NOT: module 'TargetFeatures.riscv.riscv64' requires feature #endif diff --git a/test/Modules/templates.mm b/test/Modules/templates.mm index 79e975a1ad129..95e7a9caea55c 100644 --- a/test/Modules/templates.mm +++ b/test/Modules/templates.mm @@ -77,10 +77,10 @@ unsigned testMixedStruct() { // CHECK: %[[l:.*]] = alloca %[[ListInt:[^ ]*]], align 8 // CHECK: %[[r:.*]] = alloca %[[ListInt]], align 8 - // CHECK: call {{.*}}memcpy{{.*}}(i8* %{{.*}}, i8* bitcast ({{.*}}* @_ZZ15testMixedStructvE1l to i8*), i64 16, + // CHECK: call {{.*}}memcpy{{.*}}(i8* align {{[0-9]+}} %{{.*}}, i8* align {{[0-9]+}} bitcast ({{.*}}* @_ZZ15testMixedStructvE1l to i8*), i64 16, ListInt_left l{0, 1}; - // CHECK: call {{.*}}memcpy{{.*}}(i8* %{{.*}}, i8* bitcast ({{.*}}* @_ZZ15testMixedStructvE1r to i8*), i64 16, + // CHECK: call {{.*}}memcpy{{.*}}(i8* align {{[0-9]+}} %{{.*}}, i8* align {{[0-9]+}} bitcast ({{.*}}* @_ZZ15testMixedStructvE1r to i8*), i64 16, ListInt_right r{0, 2}; // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* dereferenceable({{[0-9]+}}) %[[l]]) @@ -122,3 +122,13 @@ void testWithAttributes() { static_assert(alignof(decltype(a)) == 2, ""); static_assert(alignof(decltype(b)) == 2, ""); } + +// Check that returnNonTrivial doesn't return Class0<S0> directly in registers. + +// CHECK: declare void @_Z16returnNonTrivialv(%struct.Class0* sret) + +@import template_nontrivial0; +@import template_nontrivial1; + +S1::S1() : a(returnNonTrivial()) { +} diff --git a/test/Modules/use-exportas-for-link.m b/test/Modules/use-exportas-for-link.m new file mode 100644 index 0000000000000..69773e6039f6a --- /dev/null +++ b/test/Modules/use-exportas-for-link.m @@ -0,0 +1,44 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DA -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_A %s +// CHECK_A: !llvm.linker.options = !{![[MODULE:[0-9]+]]} +// CHECK_A: ![[MODULE]] = !{!"-framework", !"SomeKit"} +#ifdef A +@import SomeKitCore; +@import SomeKit; +#endif + +// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DB -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_B %s +// CHECK_B: !llvm.linker.options = !{![[MODULE:[0-9]+]]} +// CHECK_B: ![[MODULE]] = !{!"-framework", !"SomeKit"} +#ifdef B +@import SomeKit; +@import SomeKitCore; +#endif + +// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DC -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_C %s +// CHECK_C: !llvm.linker.options = !{![[MODULE:[0-9]+]]} +// CHECK_C: ![[MODULE]] = !{!"-framework", !"SomeKitCore"} +#ifdef C +@import SomeKitCore; +#endif + +// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DD -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_D %s +// CHECK_D: !llvm.linker.options = !{![[MODULE:[0-9]+]]} +// CHECK_D: ![[MODULE]] = !{!"-framework", !"SomeKit"} +#ifdef D +@import SomeKit; +#endif + +// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DE -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_E %s +// CHECK_E: !llvm.linker.options = !{![[MODULE:[0-9]+]]} +// CHECK_E: ![[MODULE]] = !{!"-framework", !"SomeKitCore"} +#ifdef E +@import OtherKit; +#endif + +// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -DF -fmodules -fimplicit-module-maps -F %S/Inputs/exportas-link %s | FileCheck --check-prefix=CHECK_F %s +// CHECK_F: !llvm.linker.options = !{![[MODULE:[0-9]+]]} +// CHECK_F: ![[MODULE]] = !{!"-framework", !"SomeKit"} +#ifdef F +@import OtherKit; +#endif diff --git a/test/Modules/using-decl-friend-2.cpp b/test/Modules/using-decl-friend-2.cpp new file mode 100644 index 0000000000000..0c71c37765f3b --- /dev/null +++ b/test/Modules/using-decl-friend-2.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -fmodules %s -verify +// expected-no-diagnostics + +#pragma clang module build A +module A {} +#pragma clang module contents +#pragma clang module begin A +namespace N { class X; } +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build B +module B {} +#pragma clang module contents +#pragma clang module begin B +namespace N { class Friendly { friend class X; }; } +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build C +module C {} +#pragma clang module contents +#pragma clang module begin C +#pragma clang module import A +void use_X(N::X *p); +#pragma clang module import B +// UsingShadowDecl names the friend declaration +using N::X; +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module import B +namespace N { class AlsoFriendly { friend class X; }; } +#pragma clang module import A +#pragma clang module import C +// The friend declaration from N::Friendly is now the first in the redecl +// chain, so is not ordinarily visible. We need the IDNS of the UsingShadowDecl +// to still consider it to be visible, though. +X *p; diff --git a/test/Modules/using-decl-friend.cpp b/test/Modules/using-decl-friend.cpp new file mode 100644 index 0000000000000..f11d0021a8ad6 --- /dev/null +++ b/test/Modules/using-decl-friend.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -fmodules %s -verify +// expected-no-diagnostics + +#pragma clang module build A +module A {} +#pragma clang module contents +#pragma clang module begin A +namespace N { + class X; +} +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module build B +module B { + module X {} + module Y {} +} +#pragma clang module contents +#pragma clang module begin B.X +namespace N { + class Friendly { + friend class X; + }; +} +#pragma clang module end +#pragma clang module begin B.Y +namespace N { + class X; +} +#pragma clang module end +#pragma clang module endbuild + +#pragma clang module import A +#pragma clang module import B.X +using N::X; +X *p; |
