[clang] 5834996 - [Frontend] Add flag to allow PCM generation despite compiler errors
Argyrios Kyrtzidis via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 17 17:30:13 PST 2020
Author: Ben Barham
Date: 2020-11-17T17:27:50-08:00
New Revision: 5834996fefc937d6211dc8c8a5b200068753391a
URL: https://github.com/llvm/llvm-project/commit/5834996fefc937d6211dc8c8a5b200068753391a
DIFF: https://github.com/llvm/llvm-project/commit/5834996fefc937d6211dc8c8a5b200068753391a.diff
LOG: [Frontend] Add flag to allow PCM generation despite compiler errors
As with precompiled headers, it's useful for indexers to be able to
continue through compiler errors in dependent modules.
Resolves rdar://69816264
Reviewed By: akyrtzi
Differential Revision: https://reviews.llvm.org/D91580
Added:
clang/test/Modules/Inputs/error.h
clang/test/Modules/load-module-with-errors.m
Modified:
clang/include/clang/Driver/Options.td
clang/include/clang/Frontend/ASTUnit.h
clang/include/clang/Frontend/FrontendActions.h
clang/include/clang/Frontend/FrontendOptions.h
clang/lib/Frontend/ASTUnit.cpp
clang/lib/Frontend/CompilerInstance.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/Frontend/FrontendActions.cpp
clang/test/Modules/Inputs/module.map
clang/tools/c-index-test/core_main.cpp
clang/tools/libclang/CIndex.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0168d7000737..feae81317047 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4356,6 +4356,8 @@ def fno_validate_pch : Flag<["-"], "fno-validate-pch">,
HelpText<"Disable validation of precompiled headers">;
def fallow_pch_with_errors : Flag<["-"], "fallow-pch-with-compiler-errors">,
HelpText<"Accept a PCH file that was created with compiler errors">;
+def fallow_pcm_with_errors : Flag<["-"], "fallow-pcm-with-compiler-errors">,
+ HelpText<"Accept a PCM file that was created with compiler errors">;
def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">,
HelpText<"Dump declarations that are deserialized from PCH, for testing">;
def error_on_deserialized_pch_decl : Separate<["-"], "error-on-deserialized-decl">,
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index 5595b8c7bcae..5bee57042ca6 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -694,7 +694,7 @@ class ASTUnit {
const FileSystemOptions &FileSystemOpts, bool UseDebugInfo = false,
bool OnlyLocalDecls = false, ArrayRef<RemappedFile> RemappedFiles = None,
CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
- bool AllowPCHWithCompilerErrors = false,
+ bool AllowASTWithCompilerErrors = false,
bool UserFilesAreVolatile = false);
private:
diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h
index 9ca2bfda2138..25ca95980806 100644
--- a/clang/include/clang/Frontend/FrontendActions.h
+++ b/clang/include/clang/Frontend/FrontendActions.h
@@ -117,6 +117,8 @@ class GenerateModuleAction : public ASTFrontendAction {
}
bool hasASTFileSupport() const override { return false; }
+
+ bool shouldEraseOutputFiles() override;
};
class GenerateInterfaceStubsAction : public ASTFrontendAction {
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index 51dc3a0dc7f1..b06ad5203e75 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -303,6 +303,9 @@ class FrontendOptions {
/// When using -emit-module, treat the modulemap as a system module.
unsigned IsSystemModule : 1;
+ /// Output (and read) PCM files regardless of compiler errors.
+ unsigned AllowPCMWithCompilerErrors : 1;
+
CodeCompleteOptions CodeCompleteOpts;
/// Specifies the output format of the AST.
@@ -457,7 +460,8 @@ class FrontendOptions {
UseGlobalModuleIndex(true), GenerateGlobalModuleIndex(true),
ASTDumpDecls(false), ASTDumpLookups(false),
BuildingImplicitModule(false), ModulesEmbedAllFiles(false),
- IncludeTimestamps(true), UseTemporary(true), TimeTraceGranularity(500) {}
+ IncludeTimestamps(true), UseTemporary(true),
+ AllowPCMWithCompilerErrors(false), TimeTraceGranularity(500) {}
/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return Language::C.
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index a112117d1c06..c2aba4102361 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -759,7 +759,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
const FileSystemOptions &FileSystemOpts, bool UseDebugInfo,
bool OnlyLocalDecls, ArrayRef<RemappedFile> RemappedFiles,
- CaptureDiagsKind CaptureDiagnostics, bool AllowPCHWithCompilerErrors,
+ CaptureDiagsKind CaptureDiagnostics, bool AllowASTWithCompilerErrors,
bool UserFilesAreVolatile) {
std::unique_ptr<ASTUnit> AST(new ASTUnit(true));
@@ -819,7 +819,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
AST->Reader = new ASTReader(
PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {},
/*isysroot=*/"",
- /*DisableValidation=*/disableValid, AllowPCHWithCompilerErrors);
+ /*DisableValidation=*/disableValid, AllowASTWithCompilerErrors);
AST->Reader->setListener(std::make_unique<ASTInfoCollector>(
*AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index f4b00df1e486..5c82878d8e21 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1523,7 +1523,9 @@ void CompilerInstance::createASTReader() {
HeaderSearchOptions &HSOpts = getHeaderSearchOpts();
std::string Sysroot = HSOpts.Sysroot;
const PreprocessorOptions &PPOpts = getPreprocessorOpts();
+ const FrontendOptions &FEOpts = getFrontendOpts();
std::unique_ptr<llvm::Timer> ReadTimer;
+
if (FrontendTimerGroup)
ReadTimer = std::make_unique<llvm::Timer>("reading_modules",
"Reading modules",
@@ -1532,7 +1534,7 @@ void CompilerInstance::createASTReader() {
getPreprocessor(), getModuleCache(), &getASTContext(),
getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions,
Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation,
- /*AllowASTWithCompilerErrors=*/false,
+ /*AllowASTWithCompilerErrors=*/FEOpts.AllowPCMWithCompilerErrors,
/*AllowConfigurationMismatch=*/false, HSOpts.ModulesValidateSystemHeaders,
HSOpts.ValidateASTInputFilesContent,
getFrontendOpts().UseGlobalModuleIndex, std::move(ReadTimer));
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 506423057476..a9bc48fd23a5 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2027,6 +2027,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.IncludeTimestamps = !Args.hasArg(OPT_fno_pch_timestamp);
Opts.UseTemporary = !Args.hasArg(OPT_fno_temp_file);
Opts.IsSystemModule = Args.hasArg(OPT_fsystem_module);
+ Opts.AllowPCMWithCompilerErrors = Args.hasArg(OPT_fallow_pcm_with_errors);
if (Opts.ProgramAction != frontend::GenerateModule && Opts.IsSystemModule)
Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module"
@@ -3611,7 +3612,8 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
Opts.UsePredefines = !Args.hasArg(OPT_undef);
Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record);
Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch);
- Opts.AllowPCHWithCompilerErrors = Args.hasArg(OPT_fallow_pch_with_errors);
+ Opts.AllowPCHWithCompilerErrors =
+ Args.hasArg(OPT_fallow_pch_with_errors, OPT_fallow_pcm_with_errors);
Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls);
for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index f38da54cebcc..cb2b89e4a571 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -177,7 +177,8 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
Consumers.push_back(std::make_unique<PCHGenerator>(
CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
CI.getFrontendOpts().ModuleFileExtensions,
- /*AllowASTWithErrors=*/false,
+ /*AllowASTWithErrors=*/
+ +CI.getFrontendOpts().AllowPCMWithCompilerErrors,
/*IncludeTimestamps=*/
+CI.getFrontendOpts().BuildingImplicitModule,
/*ShouldCacheASTInMemory=*/
@@ -187,6 +188,11 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
return std::make_unique<MultiplexConsumer>(std::move(Consumers));
}
+bool GenerateModuleAction::shouldEraseOutputFiles() {
+ return !getCompilerInstance().getFrontendOpts().AllowPCMWithCompilerErrors &&
+ ASTFrontendAction::shouldEraseOutputFiles();
+}
+
bool GenerateModuleFromModuleMapAction::BeginSourceFileAction(
CompilerInstance &CI) {
if (!CI.getLangOpts().Modules) {
@@ -339,7 +345,7 @@ void VerifyPCHAction::ExecuteAction() {
CI.getPCHContainerReader(), CI.getFrontendOpts().ModuleFileExtensions,
Sysroot.empty() ? "" : Sysroot.c_str(),
/*DisableValidation*/ false,
- /*AllowPCHWithCompilerErrors*/ false,
+ /*AllowASTWithCompilerErrors*/ false,
/*AllowConfigurationMismatch*/ true,
/*ValidateSystemInputs*/ true));
diff --git a/clang/test/Modules/Inputs/error.h b/clang/test/Modules/Inputs/error.h
new file mode 100644
index 000000000000..7201003d28c3
--- /dev/null
+++ b/clang/test/Modules/Inputs/error.h
@@ -0,0 +1,8 @@
+ at import undefined
+
+ at interface Error
+- (int)method;
+undefined
+ at end
+
+undefined
diff --git a/clang/test/Modules/Inputs/module.map b/clang/test/Modules/Inputs/module.map
index e7cb4b27bc08..2aa0733537bc 100644
--- a/clang/test/Modules/Inputs/module.map
+++ b/clang/test/Modules/Inputs/module.map
@@ -483,3 +483,4 @@ module template_nontrivial1 {
header "template-nontrivial1.h"
export *
}
+module error { header "error.h" }
diff --git a/clang/test/Modules/load-module-with-errors.m b/clang/test/Modules/load-module-with-errors.m
new file mode 100644
index 000000000000..64575482d091
--- /dev/null
+++ b/clang/test/Modules/load-module-with-errors.m
@@ -0,0 +1,25 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+
+// Write out a module with errors make sure it can be read
+// RUN: %clang_cc1 -fmodules -fallow-pcm-with-compiler-errors \
+// RUN: -fmodules-cache-path=%t -x objective-c -emit-module \
+// RUN: -fmodule-name=error %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -fallow-pcm-with-compiler-errors \
+// RUN: -fmodules-cache-path=%t -x objective-c -I %S/Inputs \
+// RUN: -fimplicit-module-maps -ast-print %s | FileCheck %s
+
+// allow-pcm-with-compiler-errors should also allow errors in PCH
+// RUN: %clang_cc1 -fallow-pcm-with-compiler-errors -x c++ -emit-pch \
+// RUN: -o %t/check.pch %S/Inputs/error.h
+
+ at import error;
+
+void test(id x) {
+ [x method];
+}
+
+// CHECK: @interface Error
+// CHECK-NEXT: - (int)method;
+// CHECK-NEXT: @end
+// CHECK: void test(id x)
diff --git a/clang/tools/c-index-test/core_main.cpp b/clang/tools/c-index-test/core_main.cpp
index b03783b7e043..c6d59d703d17 100644
--- a/clang/tools/c-index-test/core_main.cpp
+++ b/clang/tools/c-index-test/core_main.cpp
@@ -263,7 +263,7 @@ static bool printSourceSymbolsFromModule(StringRef modulePath,
std::string(modulePath), *pchRdr, ASTUnit::LoadASTOnly, Diags,
FileSystemOpts, /*UseDebugInfo=*/false,
/*OnlyLocalDecls=*/true, None, CaptureDiagsKind::None,
- /*AllowPCHWithCompilerErrors=*/true,
+ /*AllowASTWithCompilerErrors=*/true,
/*UserFilesAreVolatile=*/false);
if (!AU) {
errs() << "failed to create TU for: " << modulePath << '\n';
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 273b579754ae..95ff9aa35bfa 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -3476,7 +3476,7 @@ enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
CXXIdx->getOnlyLocalDecls(), None, CaptureDiagsKind::All,
- /*AllowPCHWithCompilerErrors=*/true,
+ /*AllowASTWithCompilerErrors=*/true,
/*UserFilesAreVolatile=*/true);
*out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
return *out_TU ? CXError_Success : CXError_Failure;
More information about the cfe-commits
mailing list