aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend
diff options
context:
space:
mode:
authorJan Svoboda <jan_svoboda@apple.com>2025-05-01 07:31:30 -0700
committerGitHub <noreply@github.com>2025-05-01 07:31:30 -0700
commitb69dcb873476cd8e7d3f6f9ffd5b6d0bbe1a3a17 (patch)
tree91fa427a131edc9cd16c9bef896a64083442218e /clang/lib/Frontend
parent0009a1783490a8ff69251a0ec7df1891a427cfb0 (diff)
downloadllvm-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.cpp19
-rw-r--r--clang/lib/Frontend/ChainedIncludesSource.cpp5
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp17
-rw-r--r--clang/lib/Frontend/PrecompiledPreamble.cpp5
-rw-r--r--clang/lib/Frontend/Rewrite/FrontendActions.cpp7
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()),