Close https://github.com/llvm/llvm-project/issues/60824 The form -fmodule-file=<path-to-BMI> will load modules eagerly and the form -fmodule-file=<module-name>=<path-to-BMI> will load modules lazily. The inconsistency adds many additional burdens to the implementations. And the inconsistency looks not helpful and necessary neither. So I want to deprecate the form -fmodule-file=<path-to-BMI> for named modules. This is pretty helpful for us (the developers). Does this change make any regression from the perspective of the users? To be honest, yes. But I think such regression is acceptable. Here is the example: ``` // M.cppm export module M; export int m = 5; // N.cpp // import M; // woops, we forgot to import M. int n = m; ``` In the original version, the compiler can diagnose the users to import `M` since the compiler have already imported M. But in the later style, the compiler can only say "unknown identifier `m`". But I think such regression doesn't make a deal since it only works if the user put `-fmodule-file=M.pcm` in the command line. But how can the user put `-fmodule-file=M.pcm` in the command line without `import M;`? Especially currently such options are generated by build systems. And the build systems will only generate the command line from the source file. So I think this change is pretty pretty helpful for developers and almost innocent for users and we should accept this one. I'll add the release notes and edit the document after we land this. Differential Revision: https://reviews.llvm.org/D144707
89 lines
2.7 KiB
C++
89 lines
2.7 KiB
C++
// RUN: rm -rf %t
|
|
// RUN: mkdir -p %t
|
|
// RUN: echo '#ifndef FOO_H' > %t/foo.h
|
|
// RUN: echo '#define FOO_H' >> %t/foo.h
|
|
// RUN: echo 'extern int in_header;' >> %t/foo.h
|
|
// RUN: echo '#endif' >> %t/foo.h
|
|
// RUN: %clang_cc1 -std=c++2a -I%t -emit-module-interface -DINTERFACE %s -o %t.pcm
|
|
// RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=A=%t.pcm -DIMPLEMENTATION %s -verify -fno-modules-error-recovery
|
|
// RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=A=%t.pcm %s -verify -fno-modules-error-recovery
|
|
|
|
#ifdef INTERFACE
|
|
module;
|
|
#include "foo.h"
|
|
// FIXME: The following need to be moved to a header file. The global module
|
|
// fragment is only permitted to contain preprocessor directives.
|
|
int global_module_fragment;
|
|
export module A;
|
|
export int exported;
|
|
int not_exported;
|
|
static int internal;
|
|
|
|
module :private;
|
|
int not_exported_private;
|
|
static int internal_private;
|
|
#else
|
|
|
|
#ifdef IMPLEMENTATION
|
|
module;
|
|
#endif
|
|
|
|
void test_early() {
|
|
in_header = 1; // expected-error {{use of undeclared identifier 'in_header'}}
|
|
// expected-note@* {{not visible}}
|
|
|
|
global_module_fragment = 1; // expected-error {{use of undeclared identifier 'global_module_fragment'}}
|
|
|
|
exported = 1; // expected-error {{use of undeclared identifier 'exported'}}
|
|
|
|
not_exported = 1; // expected-error {{use of undeclared identifier 'not_exported'}}
|
|
|
|
// FIXME: We need better diagnostic message for static variable.
|
|
internal = 1; // expected-error {{use of undeclared identifier 'internal'}}
|
|
|
|
not_exported_private = 1; // expected-error {{undeclared identifier}}
|
|
|
|
internal_private = 1; // expected-error {{undeclared identifier}}
|
|
}
|
|
|
|
#ifdef IMPLEMENTATION
|
|
module A;
|
|
#else
|
|
import A;
|
|
#endif
|
|
|
|
void test_late() {
|
|
in_header = 1; // expected-error {{missing '#include "foo.h"'; 'in_header' must be declared before it is used}}
|
|
// expected-note@* {{not visible}}
|
|
|
|
global_module_fragment = 1; // expected-error {{missing '#include'; 'global_module_fragment' must be declared before it is used}}
|
|
|
|
exported = 1;
|
|
|
|
not_exported = 1;
|
|
#ifndef IMPLEMENTATION
|
|
// expected-error@-2 {{declaration of 'not_exported' must be imported from module 'A' before it is required}}
|
|
// expected-note@p2.cpp:19 {{declaration here is not visible}}
|
|
#endif
|
|
|
|
internal = 1;
|
|
#ifndef IMPLEMENTATION
|
|
// expected-error@-2 {{declaration of 'internal' must be imported from module 'A' before it is required}}
|
|
// expected-note@p2.cpp:20 {{declaration here is not visible}}
|
|
#endif
|
|
|
|
not_exported_private = 1;
|
|
#ifndef IMPLEMENTATION
|
|
// FIXME: should not be visible here
|
|
// expected-error@-3 {{undeclared identifier}}
|
|
#endif
|
|
|
|
internal_private = 1;
|
|
#ifndef IMPLEMENTATION
|
|
// FIXME: should not be visible here
|
|
// expected-error@-3 {{undeclared identifier}}
|
|
#endif
|
|
}
|
|
|
|
#endif
|