"%0 differs in PCH file vs. current file">;
def err_pch_diagopt_mismatch : Error<"%0 is currently enabled, but was not in "
"the PCH file">;
+def err_pch_modulecache_mismatch : Error<"PCH was compiled with module cache "
+ "path '%0', but the path is currently '%1'">;
def err_pch_version_too_old : Error<
"PCH file uses an older PCH format that is no longer supported">;
/// and replace any existing one with it.
void createPreprocessor(TranslationUnitKind TUKind);
+ std::string getSpecificModuleCachePath();
+
/// Create the AST context.
void createASTContext();
/// \returns true to indicate the header search options are invalid, or false
/// otherwise.
virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+ StringRef SpecificModuleCachePath,
bool Complain) {
return false;
}
bool Complain) override;
bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+ StringRef SpecificModuleCachePath,
bool Complain) override;
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
bool Complain,
bool Complain) override;
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
std::string &SuggestedPredefines) override;
+ bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+ StringRef SpecificModuleCachePath,
+ bool Complain) override;
void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
private:
FileManager &FileMgr,
const LangOptions &LangOpts,
const TargetOptions &TargetOpts,
- const PreprocessorOptions &PPOpts);
+ const PreprocessorOptions &PPOpts,
+ std::string ExistingModuleCachePath);
/// \brief Returns the suggested contents of the predefines buffer,
/// which contains a (typically-empty) subset of the predefines
PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP);
- // Set up the module path, including the hash for the
- // module-creation options.
- SmallString<256> SpecificModuleCache(
- getHeaderSearchOpts().ModuleCachePath);
- if (!getHeaderSearchOpts().DisableModuleHash)
- llvm::sys::path::append(SpecificModuleCache,
- getInvocation().getModuleHash());
- PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache);
+ PP->getHeaderSearchInfo().setModuleCachePath(getSpecificModuleCachePath());
// Handle generating dependencies, if requested.
const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
}
}
+std::string CompilerInstance::getSpecificModuleCachePath() {
+ // Set up the module path, including the hash for the
+ // module-creation options.
+ SmallString<256> SpecificModuleCache(
+ getHeaderSearchOpts().ModuleCachePath);
+ if (!getHeaderSearchOpts().DisableModuleHash)
+ llvm::sys::path::append(SpecificModuleCache,
+ getInvocation().getModuleHash());
+ return SpecificModuleCache.str();
+}
+
// ASTContext
void CompilerInstance::createASTContext() {
FileManager &FileMgr = CI.getFileManager();
PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
+ std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) {
std::error_code EC;
SmallString<128> DirNative;
if (ASTReader::isAcceptableASTFile(Dir->path(), FileMgr,
CI.getLangOpts(),
CI.getTargetOpts(),
- CI.getPreprocessorOpts())) {
+ CI.getPreprocessorOpts(),
+ SpecificModuleCachePath)) {
PPOpts.ImplicitPCHInclude = Dir->path();
Found = true;
break;
}
bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+ StringRef SpecificModuleCachePath,
bool Complain) override {
Out.indent(2) << "Header search options:\n";
Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
+ Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
DUMP_BOOLEAN(HSOpts.UseBuiltinIncludes,
"Use builtin include directories [-nobuiltininc]");
DUMP_BOOLEAN(HSOpts.UseStandardSystemIncludes,
}
bool ChainedASTReaderListener::ReadHeaderSearchOptions(
- const HeaderSearchOptions &HSOpts, bool Complain) {
- return First->ReadHeaderSearchOptions(HSOpts, Complain) ||
- Second->ReadHeaderSearchOptions(HSOpts, Complain);
+ const HeaderSearchOptions &HSOpts, StringRef SpecificModuleCachePath,
+ bool Complain) {
+ return First->ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
+ Complain) ||
+ Second->ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
+ Complain);
}
bool ChainedASTReaderListener::ReadPreprocessorOptions(
const PreprocessorOptions &PPOpts, bool Complain,
Macros[MacroName] = std::make_pair(MacroBody, false);
}
}
-
+
/// \brief Check the preprocessor options deserialized from the control block
/// against the preprocessor options in an existing preprocessor.
///
PP.getLangOpts());
}
+/// Check the header search options deserialized from the control block
+/// against the header search options in an existing preprocessor.
+///
+/// \param Diags If non-null, produce diagnostics for any mismatches incurred.
+static bool checkHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+ StringRef SpecificModuleCachePath,
+ StringRef ExistingModuleCachePath,
+ DiagnosticsEngine *Diags,
+ const LangOptions &LangOpts) {
+ if (LangOpts.Modules) {
+ if (SpecificModuleCachePath != ExistingModuleCachePath) {
+ if (Diags)
+ Diags->Report(diag::err_pch_modulecache_mismatch)
+ << SpecificModuleCachePath << ExistingModuleCachePath;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool PCHValidator::ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+ StringRef SpecificModuleCachePath,
+ bool Complain) {
+ return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
+ PP.getHeaderSearchInfo().getModuleCachePath(),
+ Complain ? &Reader.Diags : nullptr,
+ PP.getLangOpts());
+}
+
void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) {
PP.setCounterValue(Value);
}
const LangOptions &ExistingLangOpts;
const TargetOptions &ExistingTargetOpts;
const PreprocessorOptions &ExistingPPOpts;
+ std::string ExistingModuleCachePath;
FileManager &FileMgr;
-
+
public:
SimplePCHValidator(const LangOptions &ExistingLangOpts,
const TargetOptions &ExistingTargetOpts,
const PreprocessorOptions &ExistingPPOpts,
+ StringRef ExistingModuleCachePath,
FileManager &FileMgr)
: ExistingLangOpts(ExistingLangOpts),
ExistingTargetOpts(ExistingTargetOpts),
ExistingPPOpts(ExistingPPOpts),
+ ExistingModuleCachePath(ExistingModuleCachePath),
FileMgr(FileMgr)
{
}
bool Complain) override {
return checkTargetOptions(ExistingTargetOpts, TargetOpts, nullptr);
}
+ bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+ StringRef SpecificModuleCachePath,
+ bool Complain) override {
+ return checkHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
+ ExistingModuleCachePath,
+ nullptr, ExistingLangOpts);
+ }
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
bool Complain,
std::string &SuggestedPredefines) override {
FileManager &FileMgr,
const LangOptions &LangOpts,
const TargetOptions &TargetOpts,
- const PreprocessorOptions &PPOpts) {
- SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts, FileMgr);
+ const PreprocessorOptions &PPOpts,
+ std::string ExistingModuleCachePath) {
+ SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts,
+ ExistingModuleCachePath, FileMgr);
return !readASTFileControlBlock(Filename, FileMgr, validator);
}
HSOpts.UseStandardSystemIncludes = Record[Idx++];
HSOpts.UseStandardCXXIncludes = Record[Idx++];
HSOpts.UseLibcxx = Record[Idx++];
+ std::string SpecificModuleCachePath = ReadString(Record, Idx);
- return Listener.ReadHeaderSearchOptions(HSOpts, Complain);
+ return Listener.ReadHeaderSearchOptions(HSOpts, SpecificModuleCachePath,
+ Complain);
}
bool ASTReader::ParsePreprocessorOptions(const RecordData &Record,
Record.push_back(HSOpts.UseStandardSystemIncludes);
Record.push_back(HSOpts.UseStandardCXXIncludes);
Record.push_back(HSOpts.UseLibcxx);
+ // Write out the specific module cache path that contains the module files.
+ AddString(PP.getHeaderSearchInfo().getModuleCachePath(), Record);
Stream.EmitRecord(HEADER_SEARCH_OPTIONS, Record);
// Preprocessor options.
// RUN: %clang_cc1 -fmodules-cache-path=%t.modules -fmodules -I %S/Inputs -emit-pch -o %t.pch -x objective-c-header %s -verify
// RUN: not %clang_cc1 -fmodules-cache-path=%t.modules -DIGNORED=1 -fmodules -I %S/Inputs -include-pch %t.pch %s > %t.err 2>&1
// RUN: FileCheck -check-prefix=CHECK-CONFLICT %s < %t.err
-// CHECK-CONFLICT: module 'ignored_macros' found in both
+// CHECK-CONFLICT: PCH was compiled with module cache path
// Third trial: pass -DIGNORED=1 only to the second invocation, but
// make it ignored. There should be no failure, IGNORED is defined in
// RUN: %clang_cc1 -x objective-c-header -fmodules -fmodules-cache-path=%t -w -Werror=auto-import %s -I %S/Inputs \
// RUN: -fmodule-implementation-of category_right -emit-pch -o %t.pch
// RUN: %clang_cc1 -x objective-c-header -fmodules -fmodules-cache-path=%t -w -Werror=auto-import %s -I %S/Inputs \
-// RUN: -DWITH_PREFIX -include-pch %t.pch -fmodule-implementation-of category_right
+// RUN: -DWITH_PREFIX -fmodules-ignore-macro=WITH_PREFIX -include-pch %t.pch -fmodule-implementation-of category_right
#ifndef WITH_PREFIX
--- /dev/null
+void make_foo(void);
--- /dev/null
+module Foo {
+ header "Foo.h"
+}
// Test with modules.
// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -x c++-header -emit-pch -o %t %S/cxx-templates.h
// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t -verify %s -ast-dump -o -
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS -fmodules-ignore-macro=NO_ERRORS | FileCheck %s
// Test with pch and delayed template parsing.
// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
--- /dev/null
+// RUN: rm -rf %t.mcp
+// RUN: rm -rf %t.err
+// RUN: %clang_cc1 -emit-pch -o %t.pch %s -I %S/Inputs/modules -fmodules -fmodules-cache-path=%t.mcp
+// RUN: not %clang_cc1 -fsyntax-only -include-pch %t.pch %s -I %S/Inputs/modules -fmodules -fmodules-cache-path=%t.mcp -fdisable-module-hash 2> %t.err
+// RUN: FileCheck -input-file=%t.err %s
+
+// CHECK: error: PCH was compiled with module cache path {{.*}}, but the path is currently {{.*}}
+@import Foo;