summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2015-02-12 21:51:31 +0000
committerBen Langmuir <blangmuir@apple.com>2015-02-12 21:51:31 +0000
commit18dd78a8fd7077398e6c89cc0bee6c144e936408 (patch)
tree754f7f0585fff5cdc6a3dfe50d811153c2ea4a5a /clang
parent39e988c63cf1cb8f68cb6d7e9c70e13e4b6050bc (diff)
downloadbcm5719-llvm-18dd78a8fd7077398e6c89cc0bee6c144e936408.tar.gz
bcm5719-llvm-18dd78a8fd7077398e6c89cc0bee6c144e936408.zip
Mangle the IsSystem bit into the .pcm file name
When mangling the module map path into a .pcm file name, also mangle the IsSystem bit, which can also depend on the header search paths. For example, the user may change from -I to -isystem. This can affect diagnostics in the importing TU. llvm-svn: 228966
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticSerializationKinds.td3
-rw-r--r--clang/include/clang/Lex/HeaderSearch.h8
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp2
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp10
-rw-r--r--clang/lib/Serialization/ASTReader.cpp7
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp1
-rw-r--r--clang/test/Modules/modules-with-same-name.m8
7 files changed, 34 insertions, 5 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index a685db0137f..fe5fd00d737 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -64,6 +64,9 @@ def err_imported_module_relocated : Error<
def err_module_different_modmap : Error<
"module '%0' %select{uses|does not use}1 additional module map '%2'"
"%select{| not}1 used when the module was built">;
+def err_module_system_change : Error<
+ "module '%0' %select{is|is not}1 a 'system' module, but "
+ "%select{was not|was}1 when the module was built">;
def warn_module_conflict : Warning<
"module '%0' conflicts with already-imported module '%1': %2">,
InGroup<ModuleConflict>;
diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h
index 158f67d40b4..2daba20a8ce 100644
--- a/clang/include/clang/Lex/HeaderSearch.h
+++ b/clang/include/clang/Lex/HeaderSearch.h
@@ -496,11 +496,15 @@ public:
/// \param ModuleName The module whose module file name will be returned.
///
/// \param ModuleMapPath A path that when combined with \c ModuleName
- /// uniquely identifies this module. See Module::ModuleMap.
+ /// and \p IsSystem uniquely identifies this module. See Module::ModuleMap.
+ ///
+ /// \param IsSystem Whether the \p ModuleName is a system module, which may
+ /// depend on how header search paths were specified.
///
/// \returns The name of the module file that corresponds to this module,
/// or an empty string if this module does not correspond to any module file.
- std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath);
+ std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath,
+ bool IsSystem);
/// \brief Lookup a module Search for a module with the given name.
///
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 701ef026d49..e7ecb2952ac 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -366,7 +366,7 @@ bool GenerateModuleAction::ComputeASTConsumerArguments(CompilerInstance &CI,
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
CI.getFrontendOpts().OutputFile =
HS.getModuleFileName(CI.getLangOpts().CurrentModule,
- ModuleMapForUniquing->getName());
+ ModuleMapForUniquing->getName(), IsSystem);
}
// We use createOutputFile here because this is exposed via libclang, and we
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index d6b255fb014..f76d851ac6c 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -115,11 +115,13 @@ const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
std::string HeaderSearch::getModuleFileName(Module *Module) {
const FileEntry *ModuleMap =
getModuleMap().getModuleMapFileForUniquing(Module);
- return getModuleFileName(Module->Name, ModuleMap->getName());
+ return getModuleFileName(Module->Name, ModuleMap->getName(),
+ Module->IsSystem);
}
std::string HeaderSearch::getModuleFileName(StringRef ModuleName,
- StringRef ModuleMapPath) {
+ StringRef ModuleMapPath,
+ bool IsSystem) {
// If we don't have a module cache path, we can't do anything.
if (ModuleCachePath.empty())
return std::string();
@@ -147,6 +149,10 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName,
llvm::hash_code Hash =
llvm::hash_combine(DirName.lower(), FileName.lower());
+ // Hash the IsSystem bit, since changing search paths can change whether a
+ // module is considered 'system' or not.
+ Hash = llvm::hash_combine(Hash, IsSystem);
+
SmallString<128> HashStr;
llvm::APInt(64, size_t(Hash)).toStringUnsigned(HashStr, /*Radix*/36);
llvm::sys::path::append(Result, ModuleName + "-" + HashStr.str() + ".pcm");
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index aa1cdc080ee..fe5c71fafc8 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -3435,6 +3435,13 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
<< F.ModuleName << /*not new*/1 << ModMap->getName();
return OutOfDate;
}
+
+ // Check whether the 'IsSystem' bit changed.
+ if (M->IsSystem != static_cast<bool>(Record[Idx])) {
+ if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
+ Diag(diag::err_module_system_change) << F.ModuleName << M->IsSystem;
+ return OutOfDate;
+ }
}
if (Listener)
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index aad4305d8c5..2526c638d30 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -1215,6 +1215,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
Record.push_back(0);
}
+ Record.push_back(WritingModule->IsSystem);
Stream.EmitRecord(MODULE_MAP_FILE, Record);
}
diff --git a/clang/test/Modules/modules-with-same-name.m b/clang/test/Modules/modules-with-same-name.m
index d362f756a60..3c5f88b18ac 100644
--- a/clang/test/Modules/modules-with-same-name.m
+++ b/clang/test/Modules/modules-with-same-name.m
@@ -21,6 +21,14 @@
// Confirm that we still have three pcm files, since DependsOnA will be rebuilt
// RUN: find %t -name "*.pcm" | count 3
+// DependsOnA, using A from path 2, as a system path
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-ignore-macro=EXPECTED_PATH -fmodules-ignore-macro=DIRECT -fsyntax-only %s -I %S/Inputs/modules-with-same-name/DependsOnA -isystem %S/Inputs/modules-with-same-name/path2/A -DEXPECTED_PATH=2 -Rmodule-build 2> %t.log
+// Confirm that we built a new module for A
+// RUN: FileCheck %s < %t.log
+// CHECK: building module 'DependsOnA'
+// CHECK: building module 'A'
+// RUN: find %t -name "*.pcm" | count 4
+
#ifdef DIRECT
@import A;
#else
OpenPOWER on IntegriCloud