summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2015-06-23 18:20:18 +0000
committerBen Langmuir <blangmuir@apple.com>2015-06-23 18:20:18 +0000
commitcd98cb731288722bf44204feb2f570caaec6617c (patch)
treeb479486484ae89a997628da14f56b261d048be68 /clang
parentc78c2bcb2a005266d7c6982ed57accd394028153 (diff)
downloadbcm5719-llvm-cd98cb731288722bf44204feb2f570caaec6617c.tar.gz
bcm5719-llvm-cd98cb731288722bf44204feb2f570caaec6617c.zip
[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. llvm-svn: 240433
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/LangOptions.h2
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp4
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp7
-rw-r--r--clang/lib/Serialization/ASTReader.cpp9
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp4
-rw-r--r--clang/test/Modules/module-feature.m14
-rw-r--r--clang/test/Modules/module_file_info.m4
7 files changed, 43 insertions, 1 deletions
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 84836eb4e5c..3c9d23efe63 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -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.
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 250c992cbde..dd664ca652f 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -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,
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 6f202a15483..49977646881 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -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;
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 7242793be22..6bdca057bad 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -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);
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 5bb0bec4f56..d6267767cf4 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -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);
diff --git a/clang/test/Modules/module-feature.m b/clang/test/Modules/module-feature.m
new file mode 100644
index 00000000000..4926d26515f
--- /dev/null
+++ b/clang/test/Modules/module-feature.m
@@ -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}}
diff --git a/clang/test/Modules/module_file_info.m b/clang/test/Modules/module_file_info.m
index 01d5073650b..8693d2b8949 100644
--- a/clang/test/Modules/module_file_info.m
+++ b/clang/test/Modules/module_file_info.m
@@ -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:
OpenPOWER on IntegriCloud