diff options
author | Jan Svoboda <jan_svoboda@apple.com> | 2025-05-01 07:31:30 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-01 07:31:30 -0700 |
commit | b69dcb873476cd8e7d3f6f9ffd5b6d0bbe1a3a17 (patch) | |
tree | 91fa427a131edc9cd16c9bef896a64083442218e /clang/lib/Frontend | |
parent | 0009a1783490a8ff69251a0ec7df1891a427cfb0 (diff) | |
download | llvm-b69dcb873476cd8e7d3f6f9ffd5b6d0bbe1a3a17.zip llvm-b69dcb873476cd8e7d3f6f9ffd5b6d0bbe1a3a17.tar.gz llvm-b69dcb873476cd8e7d3f6f9ffd5b6d0bbe1a3a17.tar.bz2 |
[clang][frontend] Require invocation to construct `CompilerInstance` (#137668)
This PR makes it so that `CompilerInvocation` needs to be provided to
`CompilerInstance` on construction. There are a couple of benefits in my
view:
* Making it impossible to mis-use some `CompilerInstance` APIs. For
example there are cases, where `createDiagnostics()` was called before
`setInvocation()`, causing the `DiagnosticEngine` to use the
default-constructed `DiagnosticOptions` instead of the intended ones.
* This shrinks `CompilerInstance`'s state space.
* This makes it possible to access **the** invocation in
`CompilerInstance`'s constructor (to be used in a follow-up).
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 19 | ||||
-rw-r--r-- | clang/lib/Frontend/ChainedIncludesSource.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Frontend/PrecompiledPreamble.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Frontend/Rewrite/FrontendActions.cpp | 7 |
5 files changed, 21 insertions, 32 deletions
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index e05385d..35f823e 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -1162,9 +1162,8 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, } // Create the compiler instance to use for building the AST. - std::unique_ptr<CompilerInstance> Clang( - new CompilerInstance(std::move(PCHContainerOps))); - Clang->setInvocation(CCInvocation); + auto Clang = std::make_unique<CompilerInstance>(CCInvocation, + std::move(PCHContainerOps)); // Clean up on error, disengage it if the function returns successfully. auto CleanOnError = llvm::make_scope_exit([&]() { @@ -1487,7 +1486,6 @@ void ASTUnit::RealizeTopLevelDeclsFromPreamble() { void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) { // Steal the created target, context, and preprocessor if they have been // created. - assert(CI.hasInvocation() && "missing invocation"); LangOpts = std::make_unique<LangOptions>(CI.getInvocation().getLangOpts()); TheSema = CI.takeSema(); Consumer = CI.takeASTConsumer(); @@ -1601,14 +1599,13 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction( AST->getFileManager().getVirtualFileSystem()); // Create the compiler instance to use for building the AST. - std::unique_ptr<CompilerInstance> Clang( - new CompilerInstance(std::move(PCHContainerOps))); + auto Clang = std::make_unique<CompilerInstance>(std::move(CI), + std::move(PCHContainerOps)); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> CICleanup(Clang.get()); - Clang->setInvocation(std::move(CI)); AST->OriginalSourceFile = std::string(Clang->getFrontendOpts().Inputs[0].getFile()); @@ -2232,15 +2229,14 @@ void ASTUnit::CodeComplete( LangOpts.SpellChecking = false; CCInvocation->getDiagnosticOpts().IgnoreWarnings = true; - std::unique_ptr<CompilerInstance> Clang( - new CompilerInstance(PCHContainerOps)); + auto Clang = std::make_unique<CompilerInstance>(std::move(CCInvocation), + PCHContainerOps); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> CICleanup(Clang.get()); - auto &Inv = *CCInvocation; - Clang->setInvocation(std::move(CCInvocation)); + auto &Inv = Clang->getInvocation(); OriginalSourceFile = std::string(Clang->getFrontendOpts().Inputs[0].getFile()); @@ -2254,7 +2250,6 @@ void ASTUnit::CodeComplete( // Create the target instance. if (!Clang->createTarget()) { - Clang->setInvocation(nullptr); return; } diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp index 4cad1b8..95b0ed2 100644 --- a/clang/lib/Frontend/ChainedIncludesSource.cpp +++ b/clang/lib/Frontend/ChainedIncludesSource.cpp @@ -122,9 +122,8 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource( IntrusiveRefCntPtr<DiagnosticsEngine> Diags( new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(), DiagClient)); - std::unique_ptr<CompilerInstance> Clang( - new CompilerInstance(CI.getPCHContainerOperations())); - Clang->setInvocation(std::move(CInvok)); + auto Clang = std::make_unique<CompilerInstance>( + std::move(CInvok), CI.getPCHContainerOperations()); Clang->setDiagnostics(Diags.get()); Clang->setTarget(TargetInfo::CreateTargetInfo( Clang->getDiagnostics(), Clang->getInvocation().getTargetOpts())); diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index fc69987..9b4147f 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -67,22 +67,20 @@ using namespace clang; CompilerInstance::CompilerInstance( + std::shared_ptr<CompilerInvocation> Invocation, std::shared_ptr<PCHContainerOperations> PCHContainerOps, ModuleCache *ModCache) : ModuleLoader(/*BuildingModule=*/ModCache), - Invocation(new CompilerInvocation()), + Invocation(std::move(Invocation)), ModCache(ModCache ? ModCache : createCrossProcessModuleCache()), - ThePCHContainerOperations(std::move(PCHContainerOps)) {} + ThePCHContainerOperations(std::move(PCHContainerOps)) { + assert(this->Invocation && "Invocation must not be null"); +} CompilerInstance::~CompilerInstance() { assert(OutputFiles.empty() && "Still output files in flight?"); } -void CompilerInstance::setInvocation( - std::shared_ptr<CompilerInvocation> Value) { - Invocation = std::move(Value); -} - bool CompilerInstance::shouldBuildGlobalModuleIndex() const { return (BuildGlobalModuleIndex || (TheASTReader && TheASTReader->isGlobalIndexUnavailable() && @@ -1210,11 +1208,10 @@ std::unique_ptr<CompilerInstance> CompilerInstance::cloneForModuleCompileImpl( // CompilerInstance::CompilerInstance is responsible for finalizing the // buffers to prevent use-after-frees. auto InstancePtr = std::make_unique<CompilerInstance>( - getPCHContainerOperations(), &getModuleCache()); + std::move(Invocation), getPCHContainerOperations(), &getModuleCache()); auto &Instance = *InstancePtr; - auto &Inv = *Invocation; - Instance.setInvocation(std::move(Invocation)); + auto &Inv = Instance.getInvocation(); if (ThreadSafeConfig) { Instance.createFileManager(ThreadSafeConfig->getVFS()); diff --git a/clang/lib/Frontend/PrecompiledPreamble.cpp b/clang/lib/Frontend/PrecompiledPreamble.cpp index 49fa2e9..70f9b66 100644 --- a/clang/lib/Frontend/PrecompiledPreamble.cpp +++ b/clang/lib/Frontend/PrecompiledPreamble.cpp @@ -454,14 +454,13 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build( PreprocessorOpts.GeneratePreamble = true; // Create the compiler instance to use for building the precompiled preamble. - std::unique_ptr<CompilerInstance> Clang( - new CompilerInstance(std::move(PCHContainerOps))); + auto Clang = std::make_unique<CompilerInstance>(std::move(PreambleInvocation), + std::move(PCHContainerOps)); // Recover resources if we crash before exiting this method. llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance> CICleanup( Clang.get()); - Clang->setInvocation(std::move(PreambleInvocation)); Clang->setDiagnostics(&Diagnostics); // Create the target instance. diff --git a/clang/lib/Frontend/Rewrite/FrontendActions.cpp b/clang/lib/Frontend/Rewrite/FrontendActions.cpp index 5d2e1d7..f955845 100644 --- a/clang/lib/Frontend/Rewrite/FrontendActions.cpp +++ b/clang/lib/Frontend/Rewrite/FrontendActions.cpp @@ -242,10 +242,9 @@ public: (*OS) << '\n'; // Rewrite the contents of the module in a separate compiler instance. - CompilerInstance Instance(CI.getPCHContainerOperations(), - &CI.getModuleCache()); - Instance.setInvocation( - std::make_shared<CompilerInvocation>(CI.getInvocation())); + CompilerInstance Instance( + std::make_shared<CompilerInvocation>(CI.getInvocation()), + CI.getPCHContainerOperations(), &CI.getModuleCache()); Instance.createDiagnostics( CI.getVirtualFileSystem(), new ForwardingDiagnosticConsumer(CI.getDiagnosticClient()), |