mirror of https://github.com/microsoft/clang.git
[Modules] Consider -fmodule-feature in module hash and when loading
Any extra features from -fmodule-feature are part of the module hash and need to get validated on load. Also print them with -module-file-info. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240433 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a0e0967f2d
commit
2f8b4cb2d3
|
@ -102,6 +102,8 @@ public:
|
|||
|
||||
/// \brief The names of any features to enable in module 'requires' decls
|
||||
/// in addition to the hard-coded list in Module.cpp and the target features.
|
||||
///
|
||||
/// This list is sorted.
|
||||
std::vector<std::string> ModuleFeatures;
|
||||
|
||||
/// \brief Options for parsing comments.
|
||||
|
|
|
@ -1588,6 +1588,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
|
|||
Opts.ImplementationOfModule =
|
||||
Args.getLastArgValue(OPT_fmodule_implementation_of);
|
||||
Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature);
|
||||
std::sort(Opts.ModuleFeatures.begin(), Opts.ModuleFeatures.end());
|
||||
Opts.NativeHalfType |= Args.hasArg(OPT_fnative_half_type);
|
||||
Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns);
|
||||
Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
|
||||
|
@ -1967,6 +1968,9 @@ std::string CompilerInvocation::getModuleHash() const {
|
|||
#define BENIGN_LANGOPT(Name, Bits, Default, Description)
|
||||
#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
|
||||
#include "clang/Basic/LangOptions.def"
|
||||
|
||||
for (StringRef Feature : LangOpts->ModuleFeatures)
|
||||
code = hash_combine(code, Feature);
|
||||
|
||||
// Extend the signature with the target options.
|
||||
code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU,
|
||||
|
|
|
@ -470,6 +470,13 @@ namespace {
|
|||
#define BENIGN_LANGOPT(Name, Bits, Default, Description)
|
||||
#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
|
||||
#include "clang/Basic/LangOptions.def"
|
||||
|
||||
if (!LangOpts.ModuleFeatures.empty()) {
|
||||
Out.indent(4) << "Module features:\n";
|
||||
for (StringRef Feature : LangOpts.ModuleFeatures)
|
||||
Out.indent(6) << Feature << "\n";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -209,6 +209,12 @@ static bool checkLanguageOptions(const LangOptions &LangOpts,
|
|||
#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
|
||||
#include "clang/Basic/LangOptions.def"
|
||||
|
||||
if (ExistingLangOpts.ModuleFeatures != LangOpts.ModuleFeatures) {
|
||||
if (Diags)
|
||||
Diags->Report(diag::err_pch_langopt_value_mismatch) << "module features";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ExistingLangOpts.ObjCRuntime != LangOpts.ObjCRuntime) {
|
||||
if (Diags)
|
||||
Diags->Report(diag::err_pch_langopt_value_mismatch)
|
||||
|
@ -4437,6 +4443,9 @@ bool ASTReader::ParseLanguageOptions(const RecordData &Record,
|
|||
LangOpts.Sanitize.set(SanitizerKind::ID, Record[Idx++]);
|
||||
#include "clang/Basic/Sanitizers.def"
|
||||
|
||||
for (unsigned N = Record[Idx++]; N; --N)
|
||||
LangOpts.ModuleFeatures.push_back(ReadString(Record, Idx));
|
||||
|
||||
ObjCRuntime::Kind runtimeKind = (ObjCRuntime::Kind) Record[Idx++];
|
||||
VersionTuple runtimeVersion = ReadVersionTuple(Record, Idx);
|
||||
LangOpts.ObjCRuntime = ObjCRuntime(runtimeKind, runtimeVersion);
|
||||
|
|
|
@ -1266,6 +1266,10 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
|
|||
Record.push_back(LangOpts.Sanitize.has(SanitizerKind::ID));
|
||||
#include "clang/Basic/Sanitizers.def"
|
||||
|
||||
Record.push_back(LangOpts.ModuleFeatures.size());
|
||||
for (StringRef Feature : LangOpts.ModuleFeatures)
|
||||
AddString(Feature, Record);
|
||||
|
||||
Record.push_back((unsigned) LangOpts.ObjCRuntime.getKind());
|
||||
AddVersionTuple(LangOpts.ObjCRuntime.getVersion(), Record);
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// RUN: rm -rf %t %t.nohash
|
||||
|
||||
// Each set of features gets its own cache.
|
||||
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -fmodule-feature f1 -fmodule-feature f2 -F %S/Inputs %s -verify -Rmodule-build
|
||||
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -fmodule-feature f2 -F %S/Inputs %s -verify -Rmodule-build
|
||||
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -fmodule-feature f2 -fmodule-feature f1 -F %S/Inputs %s -Rmodule-build 2>&1 | FileCheck %s -allow-empty -check-prefix=ALREADY_BUILT
|
||||
// ALREADY_BUILT-NOT: building module
|
||||
|
||||
// Errors if we try to force the load.
|
||||
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t.nohash -fimplicit-module-maps -fdisable-module-hash -fmodule-feature f1 -fmodule-feature f2 -F %S/Inputs %s -verify -Rmodule-build
|
||||
// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t.nohash -fimplicit-module-maps -fdisable-module-hash -fmodule-feature f2 -F %S/Inputs %s 2>&1 | FileCheck %s -check-prefix=DIFFERS
|
||||
// DIFFERS: error: module features differs
|
||||
|
||||
@import Module; // expected-remark {{building module 'Module'}} expected-remark {{finished}}
|
|
@ -2,7 +2,7 @@
|
|||
@import DependsOnModule;
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -w -Wunused -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t -F %S/Inputs -DBLARG -DWIBBLE=WOBBLE %s
|
||||
// RUN: %clang_cc1 -w -Wunused -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t -F %S/Inputs -DBLARG -DWIBBLE=WOBBLE -fmodule-feature myfeature %s
|
||||
// RUN: %clang_cc1 -module-file-info %t/DependsOnModule.pcm | FileCheck %s
|
||||
|
||||
// CHECK: Generated by this Clang:
|
||||
|
@ -14,6 +14,8 @@
|
|||
// CHECK: C99: Yes
|
||||
// CHECK: Objective-C 1: Yes
|
||||
// CHECK: modules extension to C: Yes
|
||||
// CHECK: Module features:
|
||||
// CHECK: myfeature
|
||||
|
||||
// CHECK: Target options:
|
||||
// CHECK: Triple:
|
||||
|
|
Loading…
Reference in New Issue