From: Ben Langmuir Date: Thu, 12 Feb 2015 21:51:31 +0000 (+0000) Subject: Mangle the IsSystem bit into the .pcm file name X-Git-Tag: llvmorg-3.7.0-rc1~12326 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=18dd78a8fd7077398e6c89cc0bee6c144e936408;p=platform%2Fupstream%2Fllvm.git 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 --- diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td index a685db0..fe5fd00 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; diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h index 158f67d..2daba20 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 701ef02..e7ecb29 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 d6b255f..f76d851 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 aa1cdc0..fe5c71f 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(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 aad4305..2526c63 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 d362f75..3c5f88b 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