summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2014-02-05 22:21:15 +0000
committerBen Langmuir <blangmuir@apple.com>2014-02-05 22:21:15 +0000
commit2cb4a78f9394359e3bb74060774e2245bcb9f4b7 (patch)
tree712d0ddca4e53867a288b5597be5efec6029a1bf /clang
parent87769713cf385f373f3bc1c28913045f49277d7f (diff)
downloadbcm5719-llvm-2cb4a78f9394359e3bb74060774e2245bcb9f4b7.tar.gz
bcm5719-llvm-2cb4a78f9394359e3bb74060774e2245bcb9f4b7.zip
Add a CC1 option -verify-pch
This option will: - load the given pch file - verify it is not out of date by stat'ing dependencies, and - return 0 on success and non-zero on error llvm-svn: 200884
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Driver/Options.td2
-rw-r--r--clang/include/clang/Frontend/CompilerInstance.h2
-rw-r--r--clang/include/clang/Frontend/FrontendActions.h11
-rw-r--r--clang/include/clang/Frontend/FrontendOptions.h1
-rw-r--r--clang/include/clang/Serialization/ASTReader.h8
-rw-r--r--clang/lib/Driver/Driver.cpp3
-rw-r--r--clang/lib/Driver/Tools.cpp28
-rw-r--r--clang/lib/Driver/Types.cpp2
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp9
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--clang/lib/Frontend/FrontendAction.cpp1
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp13
-rw-r--r--clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp1
-rw-r--r--clang/lib/Serialization/ASTReader.cpp17
-rw-r--r--clang/test/Driver/verify_pch.m12
-rw-r--r--clang/test/PCH/verify_pch.m15
16 files changed, 114 insertions, 14 deletions
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 6b7e198d0bf..731bb0406b3 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -927,6 +927,8 @@ def include_pch : Separate<["-"], "include-pch">, Group<clang_i_Group>, Flags<[C
HelpText<"Include precompiled header file">, MetaVarName<"<file>">;
def relocatable_pch : Flag<["-", "--"], "relocatable-pch">, Flags<[CC1Option]>,
HelpText<"Whether to build a relocatable precompiled header">;
+def verify_pch : Flag<["-"], "verify-pch">, Group<Action_Group>, Flags<[CC1Option]>,
+ HelpText<"Load and verify that a pre-compiled header file is not stale">;
def init : Separate<["-"], "init">;
def install__name : Separate<["-"], "install_name">;
def integrated_as : Flag<["-"], "integrated-as">, Flags<[DriverOption]>;
diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h
index fa20ae48e4f..64de7a5b197 100644
--- a/clang/include/clang/Frontend/CompilerInstance.h
+++ b/clang/include/clang/Frontend/CompilerInstance.h
@@ -545,6 +545,7 @@ public:
void createPCHExternalASTSource(StringRef Path,
bool DisablePCHValidation,
bool AllowPCHWithCompilerErrors,
+ bool AllowConfigurationMismatch,
void *DeserializationListener);
/// Create an external AST source to read a PCH file.
@@ -554,6 +555,7 @@ public:
createPCHExternalASTSource(StringRef Path, const std::string &Sysroot,
bool DisablePCHValidation,
bool AllowPCHWithCompilerErrors,
+ bool AllowConfigurationMismatch,
Preprocessor &PP, ASTContext &Context,
void *DeserializationListener, bool Preamble,
bool UseGlobalModuleIndex);
diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h
index f3d12769f14..f5557888ad6 100644
--- a/clang/include/clang/Frontend/FrontendActions.h
+++ b/clang/include/clang/Frontend/FrontendActions.h
@@ -146,6 +146,17 @@ public:
virtual bool hasCodeCompletionSupport() const { return false; }
};
+class VerifyPCHAction : public ASTFrontendAction {
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile);
+
+ virtual void ExecuteAction();
+
+public:
+ virtual bool hasCodeCompletionSupport() const { return false; }
+};
+
/**
* \brief Frontend action adaptor that merges ASTs together.
*
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index 818427a4ef6..fc13b193936 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -43,6 +43,7 @@ namespace frontend {
GeneratePTH, ///< Generate pre-tokenized header.
InitOnly, ///< Only execute frontend initialization.
ModuleFileInfo, ///< Dump information about a module file.
+ VerifyPCH, ///< Load and verify that a PCH file is usable.
ParseSyntaxOnly, ///< Parse and perform semantic analysis.
PluginAction, ///< Run a plugin action, \see ActionName.
PrintDeclContext, ///< Print DeclContext and their Decls.
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 3cfd17ca027..00ab7f04926 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -733,6 +733,10 @@ private:
/// \brief Whether to accept an AST file with compiler errors.
bool AllowASTWithCompilerErrors;
+ /// \brief Whether to accept an AST file that has a different configuration
+ /// from the current compiler instance.
+ bool AllowConfigurationMismatch;
+
/// \brief Whether we are allowed to use the global module index.
bool UseGlobalIndex;
@@ -1174,11 +1178,15 @@ public:
/// AST file the was created out of an AST with compiler errors,
/// otherwise it will reject it.
///
+ /// \param AllowConfigurationMismatch If true, the AST reader will not check
+ /// for configuration differences between the AST file and the invocation.
+ ///
/// \param UseGlobalIndex If true, the AST reader will try to load and use
/// the global module index.
ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "",
bool DisableValidation = false,
bool AllowASTWithCompilerErrors = false,
+ bool AllowConfigurationMismatch = false,
bool UseGlobalIndex = true);
~ASTReader();
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index bd43fbeec19..270c3a701b0 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -169,6 +169,7 @@ const {
// -{fsyntax-only,-analyze,emit-ast,S} only run up to the compiler.
} else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
(PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
+ (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
(PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
(PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
(PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
@@ -1316,6 +1317,8 @@ Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
return new CompileJobAction(Input, types::TY_AST);
} else if (Args.hasArg(options::OPT_module_file_info)) {
return new CompileJobAction(Input, types::TY_ModuleFile);
+ } else if (Args.hasArg(options::OPT_verify_pch)) {
+ return new CompileJobAction(Input, types::TY_Nothing);
} else if (IsUsingLTO(Args)) {
types::ID Output =
Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 3a8a2877579..af8696c42a7 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -1995,6 +1995,21 @@ static bool shouldEnableVectorizerAtOLevel(const ArgList &Args) {
return false;
}
+/// Add -x lang to \p CmdArgs for \p Input.
+static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
+ ArgStringList &CmdArgs) {
+ // When using -verify-pch, we don't want to provide the type
+ // 'precompiled-header' if it was inferred from the file extension
+ if (Args.hasArg(options::OPT_verify_pch) && Input.getType() == types::TY_PCH)
+ return;
+
+ CmdArgs.push_back("-x");
+ if (Args.hasArg(options::OPT_rewrite_objc))
+ CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
+ else
+ CmdArgs.push_back(types::getTypeName(Input.getType()));
+}
+
void Clang::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -2055,7 +2070,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
if (JA.getType() == types::TY_Nothing) {
- CmdArgs.push_back("-fsyntax-only");
+ if (Args.hasArg(options::OPT_verify_pch))
+ CmdArgs.push_back("-verify-pch");
+ else
+ CmdArgs.push_back("-fsyntax-only");
} else if (JA.getType() == types::TY_LLVM_IR ||
JA.getType() == types::TY_LTO_IR) {
CmdArgs.push_back("-emit-llvm");
@@ -3742,11 +3760,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
for (InputInfoList::const_iterator
it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
const InputInfo &II = *it;
- CmdArgs.push_back("-x");
- if (Args.hasArg(options::OPT_rewrite_objc))
- CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
- else
- CmdArgs.push_back(types::getTypeName(II.getType()));
+
+ addDashXForInput(Args, II, CmdArgs);
+
if (II.isFilename())
CmdArgs.push_back(II.getFilename());
else
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index d947ae7c03d..3538dbc2c0e 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -174,6 +174,8 @@ types::ID types::lookupTypeForExtension(const char *Ext) {
.Case("F95", TY_Fortran)
.Case("mii", TY_PP_ObjCXX)
.Case("pcm", TY_ModuleFile)
+ .Case("pch", TY_PCH)
+ .Case("gch", TY_PCH)
.Default(TY_INVALID);
}
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 0d2af334d79..d8381a824c7 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -292,12 +292,14 @@ void CompilerInstance::createASTContext() {
void CompilerInstance::createPCHExternalASTSource(StringRef Path,
bool DisablePCHValidation,
bool AllowPCHWithCompilerErrors,
+ bool AllowConfigurationMismatch,
void *DeserializationListener){
OwningPtr<ExternalASTSource> Source;
bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot,
DisablePCHValidation,
AllowPCHWithCompilerErrors,
+ AllowConfigurationMismatch,
getPreprocessor(), getASTContext(),
DeserializationListener,
Preamble,
@@ -311,6 +313,7 @@ CompilerInstance::createPCHExternalASTSource(StringRef Path,
const std::string &Sysroot,
bool DisablePCHValidation,
bool AllowPCHWithCompilerErrors,
+ bool AllowConfigurationMismatch,
Preprocessor &PP,
ASTContext &Context,
void *DeserializationListener,
@@ -321,6 +324,7 @@ CompilerInstance::createPCHExternalASTSource(StringRef Path,
Sysroot.empty() ? "" : Sysroot.c_str(),
DisablePCHValidation,
AllowPCHWithCompilerErrors,
+ AllowConfigurationMismatch,
UseGlobalModuleIndex));
Reader->setDeserializationListener(
@@ -329,7 +333,9 @@ CompilerInstance::createPCHExternalASTSource(StringRef Path,
Preamble ? serialization::MK_Preamble
: serialization::MK_PCH,
SourceLocation(),
- ASTReader::ARR_None)) {
+ AllowConfigurationMismatch
+ ? ASTReader::ARR_ConfigurationMismatch
+ : ASTReader::ARR_None)) {
case ASTReader::Success:
// Set the predefines buffer as suggested by the PCH reader. Typically, the
// predefines buffer will be empty.
@@ -1158,6 +1164,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
Sysroot.empty() ? "" : Sysroot.c_str(),
PPOpts.DisablePCHValidation,
/*AllowASTWithCompilerErrors=*/false,
+ /*AllowConfigurationMismatch=*/false,
getFrontendOpts().UseGlobalModuleIndex);
if (hasASTConsumer()) {
ModuleManager->setDeserializationListener(
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 92202b7ee20..da58a0386e6 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -700,6 +700,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.ProgramAction = frontend::ParseSyntaxOnly; break;
case OPT_module_file_info:
Opts.ProgramAction = frontend::ModuleFileInfo; break;
+ case OPT_verify_pch:
+ Opts.ProgramAction = frontend::VerifyPCH; break;
case OPT_print_decl_contexts:
Opts.ProgramAction = frontend::PrintDeclContext; break;
case OPT_print_preamble:
@@ -1585,6 +1587,7 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
case frontend::GeneratePTH:
case frontend::ParseSyntaxOnly:
case frontend::ModuleFileInfo:
+ case frontend::VerifyPCH:
case frontend::PluginAction:
case frontend::PrintDeclContext:
case frontend::RewriteObjC:
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index 0baf3e5e1fb..13a0787e427 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -314,6 +314,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
CI.getPreprocessorOpts().ImplicitPCHInclude,
CI.getPreprocessorOpts().DisablePCHValidation,
CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
+ /*AllowConfigurationMismatch*/false,
DeserialListener);
if (!CI.getASTContext().getExternalSource())
goto failure;
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 0d78bf032e3..8b174605ffd 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -320,6 +320,19 @@ ASTConsumer *DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI,
return new ASTConsumer();
}
+ASTConsumer *VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) {
+ return new ASTConsumer();
+}
+
+void VerifyPCHAction::ExecuteAction() {
+ getCompilerInstance().
+ createPCHExternalASTSource(getCurrentFile(), /*DisablePCHValidation*/false,
+ /*AllowPCHWithCompilerErrors*/false,
+ /*AllowConfigurationMismatch*/true,
+ /*DeserializationListener*/0);
+}
+
namespace {
/// \brief AST reader listener that dumps module information for a module
/// file.
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index e14fb2340e6..4c2ec441b3f 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -65,6 +65,7 @@ static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
case InitOnly: return new InitOnlyAction();
case ParseSyntaxOnly: return new SyntaxOnlyAction();
case ModuleFileInfo: return new DumpModuleInfoAction();
+ case VerifyPCH: return new VerifyPCHAction();
case PluginAction: {
for (FrontendPluginRegistry::iterator it =
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 3a93804eab7..4d2a4008888 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -1935,7 +1935,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
if (Listener && &F == *ModuleMgr.begin() &&
ParseLanguageOptions(Record, Complain, *Listener) &&
- !DisableValidation)
+ !DisableValidation && !AllowConfigurationMismatch)
return ConfigurationMismatch;
break;
}
@@ -1944,7 +1944,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
if (Listener && &F == *ModuleMgr.begin() &&
ParseTargetOptions(Record, Complain, *Listener) &&
- !DisableValidation)
+ !DisableValidation && !AllowConfigurationMismatch)
return ConfigurationMismatch;
break;
}
@@ -1953,7 +1953,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
if (Listener && &F == *ModuleMgr.begin() &&
ParseDiagnosticOptions(Record, Complain, *Listener) &&
- !DisableValidation)
+ !DisableValidation && !AllowConfigurationMismatch)
return ConfigurationMismatch;
break;
}
@@ -1962,7 +1962,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
if (Listener && &F == *ModuleMgr.begin() &&
ParseFileSystemOptions(Record, Complain, *Listener) &&
- !DisableValidation)
+ !DisableValidation && !AllowConfigurationMismatch)
return ConfigurationMismatch;
break;
}
@@ -1971,7 +1971,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
if (Listener && &F == *ModuleMgr.begin() &&
ParseHeaderSearchOptions(Record, Complain, *Listener) &&
- !DisableValidation)
+ !DisableValidation && !AllowConfigurationMismatch)
return ConfigurationMismatch;
break;
}
@@ -1981,7 +1981,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
if (Listener && &F == *ModuleMgr.begin() &&
ParsePreprocessorOptions(Record, Complain, *Listener,
SuggestedPredefines) &&
- !DisableValidation)
+ !DisableValidation && !AllowConfigurationMismatch)
return ConfigurationMismatch;
break;
}
@@ -7618,13 +7618,16 @@ void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, bool DisableValidation,
- bool AllowASTWithCompilerErrors, bool UseGlobalIndex)
+ bool AllowASTWithCompilerErrors,
+ bool AllowConfigurationMismatch,
+ bool UseGlobalIndex)
: Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
Diags(PP.getDiagnostics()), SemaObj(0), PP(PP), Context(Context),
Consumer(0), ModuleMgr(PP.getFileManager()),
isysroot(isysroot), DisableValidation(DisableValidation),
AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
+ AllowConfigurationMismatch(AllowConfigurationMismatch),
UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(false),
CurrentGeneration(0), CurrSwitchCaseStmts(&SwitchCaseStmts),
NumSLocEntriesRead(0), TotalNumSLocEntries(0),
diff --git a/clang/test/Driver/verify_pch.m b/clang/test/Driver/verify_pch.m
new file mode 100644
index 00000000000..c6eca4268bd
--- /dev/null
+++ b/clang/test/Driver/verify_pch.m
@@ -0,0 +1,12 @@
+// RUN: touch %t.pch
+// RUN: %clang -### -verify-pch %t.pch 2> %t.log.1
+// RUN: FileCheck %s < %t.log.1
+// CHECK: -verify-pch
+
+// Also ensure that the language setting is not affected by the .pch extension
+// CHECK-NOT: "-x" "precompiled-header"
+
+// RUN: %clang -### -verify-pch -x objective-c %t.pch 2> %t.log.2
+// RUN: FileCheck -check-prefix=CHECK2 %s < %t.log.2
+// CHECK2: "-x" "objective-c"
+// CHECK2-NOT: "-x" "precompiled-header"
diff --git a/clang/test/PCH/verify_pch.m b/clang/test/PCH/verify_pch.m
new file mode 100644
index 00000000000..9870231d7c8
--- /dev/null
+++ b/clang/test/PCH/verify_pch.m
@@ -0,0 +1,15 @@
+// Precompile
+// RUN: cp %s %t.h
+// RUN: %clang_cc1 -x objective-c-header -emit-pch -o %t.pch %t.h
+
+// Verify successfully
+// RUN: %clang_cc1 -x objective-c -verify-pch %t.pch
+
+// Incompatible lang options ignored
+// RUN: %clang_cc1 -x objective-c -fno-builtin -verify-pch %t.pch
+
+// Stale dependency
+// RUN: echo ' ' >> %t.h
+// RUN: not %clang_cc1 -x objective-c -verify-pch %t.pch 2> %t.log.2
+// RUN: FileCheck -check-prefix=CHECK-STALE-DEP %s < %t.log.2
+// CHECK-STALE-DEP: file '{{.*}}.h' has been modified since the precompiled header '{{.*}}.pch' was built
OpenPOWER on IntegriCloud