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 @@ +@import undefined + +@interface Error +- (int)method; +undefined +@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 + +@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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits