[clang] [clang-tools-extra] [clang] Hide the `TargetOptions` pointer from `CompilerInvocation` (PR #106271)
Jan Svoboda via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 11 10:59:29 PDT 2025
https://github.com/jansvoboda11 updated https://github.com/llvm/llvm-project/pull/106271
>From e4c1f9254257c92789a924c70b06399c0ea794bd Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Tue, 27 Aug 2024 09:34:01 -0700
Subject: [PATCH 1/6] [clang] `TargetInfo` does not own `TargetOptions`
---
clang-tools-extra/clangd/SystemIncludeExtractor.cpp | 2 +-
clang-tools-extra/modularize/ModularizeUtilities.cpp | 2 +-
clang/include/clang/Basic/TargetInfo.h | 7 +++----
clang/include/clang/Frontend/CompilerInstance.h | 3 +++
clang/lib/Basic/Targets.cpp | 7 ++++---
clang/lib/Frontend/ASTUnit.cpp | 2 +-
clang/lib/Frontend/ChainedIncludesSource.cpp | 2 +-
clang/lib/Frontend/CompilerInstance.cpp | 6 +++---
clang/lib/Interpreter/Interpreter.cpp | 2 +-
clang/tools/clang-import-test/clang-import-test.cpp | 2 +-
clang/unittests/Analysis/MacroExpansionContextTest.cpp | 2 +-
clang/unittests/Basic/SourceManagerTest.cpp | 2 +-
clang/unittests/CodeGen/TestCompiler.h | 3 +--
clang/unittests/Frontend/UtilsTest.cpp | 2 +-
clang/unittests/Lex/HeaderSearchTest.cpp | 2 +-
clang/unittests/Lex/LexerTest.cpp | 2 +-
clang/unittests/Lex/ModuleDeclStateTest.cpp | 2 +-
clang/unittests/Lex/PPCallbacksTest.cpp | 2 +-
clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp | 2 +-
clang/unittests/Lex/PPDependencyDirectivesTest.cpp | 2 +-
clang/unittests/Lex/PPMemoryAllocationsTest.cpp | 2 +-
21 files changed, 30 insertions(+), 28 deletions(-)
diff --git a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
index 9399b910025b6..4fa0c78f3196f 100644
--- a/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
+++ b/clang-tools-extra/clangd/SystemIncludeExtractor.cpp
@@ -257,7 +257,7 @@ bool isValidTarget(llvm::StringRef Triple) {
DiagnosticsEngine Diags(new DiagnosticIDs, new DiagnosticOptions,
new IgnoringDiagConsumer);
llvm::IntrusiveRefCntPtr<TargetInfo> Target =
- TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+ TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
return bool(Target);
}
diff --git a/clang-tools-extra/modularize/ModularizeUtilities.cpp b/clang-tools-extra/modularize/ModularizeUtilities.cpp
index 476e13770a94f..e9e100811a402 100644
--- a/clang-tools-extra/modularize/ModularizeUtilities.cpp
+++ b/clang-tools-extra/modularize/ModularizeUtilities.cpp
@@ -53,7 +53,7 @@ ModularizeUtilities::ModularizeUtilities(std::vector<std::string> &InputPaths,
Diagnostics(
new DiagnosticsEngine(DiagIDs, DiagnosticOpts.get(), &DC, false)),
TargetOpts(new ModuleMapTargetOptions()),
- Target(TargetInfo::CreateTargetInfo(*Diagnostics, TargetOpts)),
+ Target(TargetInfo::CreateTargetInfo(*Diagnostics, *TargetOpts)),
FileMgr(new FileManager(FileSystemOpts)),
SourceMgr(new SourceManager(*Diagnostics, *FileMgr, false)),
HeaderInfo(new HeaderSearch(std::make_shared<HeaderSearchOptions>(),
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index d136b459e9cd4..4fb87428be8a0 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -224,7 +224,7 @@ enum OpenCLTypeKind : uint8_t {
///
class TargetInfo : public TransferrableTargetInfo,
public RefCountedBase<TargetInfo> {
- std::shared_ptr<TargetOptions> TargetOpts;
+ TargetOptions *TargetOpts;
llvm::Triple Triple;
protected:
// Target values set by the ctor of the actual target implementation. Default
@@ -311,9 +311,8 @@ class TargetInfo : public TransferrableTargetInfo,
/// \param Opts - The options to use to initialize the target. The target may
/// modify the options to canonicalize the target feature information to match
/// what the backend expects.
- static TargetInfo *
- CreateTargetInfo(DiagnosticsEngine &Diags,
- const std::shared_ptr<TargetOptions> &Opts);
+ static TargetInfo *CreateTargetInfo(DiagnosticsEngine &Diags,
+ TargetOptions &Opts);
virtual ~TargetInfo();
diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h
index 8b539dfc92960..fb2d30c73e4ce 100644
--- a/clang/include/clang/Frontend/CompilerInstance.h
+++ b/clang/include/clang/Frontend/CompilerInstance.h
@@ -87,6 +87,9 @@ class CompilerInstance : public ModuleLoader {
/// The target being compiled for.
IntrusiveRefCntPtr<TargetInfo> Target;
+ /// Options for the auxiliary target.
+ std::unique_ptr<TargetOptions> AuxTargetOpts;
+
/// Auxiliary Target info.
IntrusiveRefCntPtr<TargetInfo> AuxTarget;
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index c6d228fe98100..9889141ad2085 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -774,9 +774,10 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
using namespace clang::targets;
/// CreateTargetInfo - Return the target info object for the specified target
/// options.
-TargetInfo *
-TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
- const std::shared_ptr<TargetOptions> &Opts) {
+TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
+ TargetOptions &OptsRef) {
+ TargetOptions *Opts = &OptsRef;
+
llvm::Triple Triple(llvm::Triple::normalize(Opts->Triple));
// Construct the target
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 8df5465ad990d..cce2a2be3957e 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -615,7 +615,7 @@ class ASTInfoCollector : public ASTReaderListener {
this->TargetOpts = std::make_shared<TargetOptions>(TargetOpts);
Target =
- TargetInfo::CreateTargetInfo(PP.getDiagnostics(), this->TargetOpts);
+ TargetInfo::CreateTargetInfo(PP.getDiagnostics(), *this->TargetOpts);
updated();
return false;
diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp
index a7096e27796a0..4cad1b886c8cf 100644
--- a/clang/lib/Frontend/ChainedIncludesSource.cpp
+++ b/clang/lib/Frontend/ChainedIncludesSource.cpp
@@ -127,7 +127,7 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
Clang->setInvocation(std::move(CInvok));
Clang->setDiagnostics(Diags.get());
Clang->setTarget(TargetInfo::CreateTargetInfo(
- Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
+ Clang->getDiagnostics(), Clang->getInvocation().getTargetOpts()));
Clang->createFileManager();
Clang->createSourceManager(Clang->getFileManager());
Clang->createPreprocessor(TU_Prefix);
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 6098e2e30af9d..c1a86a6baf890 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -109,7 +109,7 @@ void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }
bool CompilerInstance::createTarget() {
// Create the target instance.
setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(),
- getInvocation().TargetOpts));
+ getInvocation().getTargetOpts()));
if (!hasTarget())
return false;
@@ -119,14 +119,14 @@ bool CompilerInstance::createTarget() {
(getLangOpts().CUDA || getLangOpts().OpenMPIsTargetDevice ||
getLangOpts().SYCLIsDevice) &&
!getFrontendOpts().AuxTriple.empty()) {
- auto TO = std::make_shared<TargetOptions>();
+ auto &TO = AuxTargetOpts = std::make_unique<TargetOptions>();
TO->Triple = llvm::Triple::normalize(getFrontendOpts().AuxTriple);
if (getFrontendOpts().AuxTargetCPU)
TO->CPU = *getFrontendOpts().AuxTargetCPU;
if (getFrontendOpts().AuxTargetFeatures)
TO->FeaturesAsWritten = *getFrontendOpts().AuxTargetFeatures;
TO->HostTriple = getTarget().getTriple().str();
- setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO));
+ setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), *TO));
}
if (!getTarget().hasStrictFP() && !getLangOpts().ExpStrictFP) {
diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp
index fa4c1439c9261..557d8cab2d09b 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -124,7 +124,7 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
Clang->getPreprocessorOpts().addRemappedFile("<<< inputs >>>", MB);
Clang->setTarget(TargetInfo::CreateTargetInfo(
- Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
+ Clang->getDiagnostics(), Clang->getInvocation().getTargetOpts()));
if (!Clang->hasTarget())
return llvm::createStringError(llvm::errc::not_supported,
"Initialization failed. "
diff --git a/clang/tools/clang-import-test/clang-import-test.cpp b/clang/tools/clang-import-test/clang-import-test.cpp
index 41a8a63a2e22b..ce3d0f6c503b2 100644
--- a/clang/tools/clang-import-test/clang-import-test.cpp
+++ b/clang/tools/clang-import-test/clang-import-test.cpp
@@ -208,7 +208,7 @@ std::unique_ptr<CompilerInstance> BuildCompilerInstance() {
Ins->setInvocation(std::move(Inv));
TargetInfo *TI = TargetInfo::CreateTargetInfo(
- Ins->getDiagnostics(), Ins->getInvocation().TargetOpts);
+ Ins->getDiagnostics(), Ins->getInvocation().getTargetOpts());
Ins->setTarget(TI);
Ins->getTarget().adjust(Ins->getDiagnostics(), Ins->getLangOpts());
Ins->createFileManager();
diff --git a/clang/unittests/Analysis/MacroExpansionContextTest.cpp b/clang/unittests/Analysis/MacroExpansionContextTest.cpp
index 54b209e7b28c1..0a555f36a0937 100644
--- a/clang/unittests/Analysis/MacroExpansionContextTest.cpp
+++ b/clang/unittests/Analysis/MacroExpansionContextTest.cpp
@@ -39,7 +39,7 @@ class MacroExpansionContextTest : public ::testing::Test {
Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions()) {
TargetOpts->Triple = "x86_64-pc-linux-unknown";
- Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+ Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
LangOpts.CPlusPlus20 = 1; // For __VA_OPT__
}
diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp
index 2b3fce9128ba9..a8c63f99bb36c 100644
--- a/clang/unittests/Basic/SourceManagerTest.cpp
+++ b/clang/unittests/Basic/SourceManagerTest.cpp
@@ -46,7 +46,7 @@ class SourceManagerTest : public ::testing::Test {
SourceMgr(Diags, FileMgr),
TargetOpts(new TargetOptions) {
TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
- Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+ Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
}
FileSystemOptions FileMgrOpts;
diff --git a/clang/unittests/CodeGen/TestCompiler.h b/clang/unittests/CodeGen/TestCompiler.h
index 931c75effbf75..a6fec7fb0945d 100644
--- a/clang/unittests/CodeGen/TestCompiler.h
+++ b/clang/unittests/CodeGen/TestCompiler.h
@@ -45,8 +45,7 @@ struct TestCompiler {
Tr.setEnvironment(Triple::EnvironmentType::UnknownEnvironment);
compiler.getTargetOpts().Triple = Tr.getTriple();
compiler.setTarget(clang::TargetInfo::CreateTargetInfo(
- compiler.getDiagnostics(),
- std::make_shared<clang::TargetOptions>(compiler.getTargetOpts())));
+ compiler.getDiagnostics(), compiler.getTargetOpts()));
const clang::TargetInfo &TInfo = compiler.getTarget();
PtrSize = TInfo.getPointerWidth(clang::LangAS::Default) / 8;
diff --git a/clang/unittests/Frontend/UtilsTest.cpp b/clang/unittests/Frontend/UtilsTest.cpp
index 304fbe2a8e69f..47ca3210ab596 100644
--- a/clang/unittests/Frontend/UtilsTest.cpp
+++ b/clang/unittests/Frontend/UtilsTest.cpp
@@ -33,7 +33,7 @@ TEST(BuildCompilerInvocationTest, RecoverMultipleJobs) {
*Opts.VFS, new DiagnosticOptions, &D, false);
std::unique_ptr<CompilerInvocation> CI = createInvocation(Args, Opts);
ASSERT_TRUE(CI);
- EXPECT_THAT(CI->TargetOpts->Triple, testing::StartsWith("i386-"));
+ EXPECT_THAT(CI->getTargetOpts().Triple, testing::StartsWith("i386-"));
}
// buildInvocationFromCommandLine should not translate -include to -include-pch,
diff --git a/clang/unittests/Lex/HeaderSearchTest.cpp b/clang/unittests/Lex/HeaderSearchTest.cpp
index 4d07150c04e8d..c9cd6608254ba 100644
--- a/clang/unittests/Lex/HeaderSearchTest.cpp
+++ b/clang/unittests/Lex/HeaderSearchTest.cpp
@@ -36,7 +36,7 @@ class HeaderSearchTest : public ::testing::Test {
Search(std::make_shared<HeaderSearchOptions>(), SourceMgr, Diags,
LangOpts, Target.get()) {
TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
- Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+ Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
}
void addSearchDir(llvm::StringRef Dir) {
diff --git a/clang/unittests/Lex/LexerTest.cpp b/clang/unittests/Lex/LexerTest.cpp
index 29c61fee6f531..97cebbb260e88 100644
--- a/clang/unittests/Lex/LexerTest.cpp
+++ b/clang/unittests/Lex/LexerTest.cpp
@@ -48,7 +48,7 @@ class LexerTest : public ::testing::Test {
TargetOpts(new TargetOptions)
{
TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
- Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+ Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
}
std::unique_ptr<Preprocessor> CreatePP(StringRef Source,
diff --git a/clang/unittests/Lex/ModuleDeclStateTest.cpp b/clang/unittests/Lex/ModuleDeclStateTest.cpp
index 15306ba22bf67..ca277aca4be27 100644
--- a/clang/unittests/Lex/ModuleDeclStateTest.cpp
+++ b/clang/unittests/Lex/ModuleDeclStateTest.cpp
@@ -58,7 +58,7 @@ class ModuleDeclStateTest : public ::testing::Test {
Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
TargetOpts->Triple = "x86_64-unknown-linux-gnu";
- Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+ Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
}
std::unique_ptr<Preprocessor>
diff --git a/clang/unittests/Lex/PPCallbacksTest.cpp b/clang/unittests/Lex/PPCallbacksTest.cpp
index f3cdb1dfb2874..e9750d21a662a 100644
--- a/clang/unittests/Lex/PPCallbacksTest.cpp
+++ b/clang/unittests/Lex/PPCallbacksTest.cpp
@@ -139,7 +139,7 @@ class PPCallbacksTest : public ::testing::Test {
Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions()) {
TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
- Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+ Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
}
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
diff --git a/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp b/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
index 84c4cc3a1b2dc..e9019fe298f70 100644
--- a/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
+++ b/clang/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
@@ -36,7 +36,7 @@ class PPConditionalDirectiveRecordTest : public ::testing::Test {
TargetOpts(new TargetOptions)
{
TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
- Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+ Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
}
FileSystemOptions FileMgrOpts;
diff --git a/clang/unittests/Lex/PPDependencyDirectivesTest.cpp b/clang/unittests/Lex/PPDependencyDirectivesTest.cpp
index 6ff87f720a559..83e42cacf188a 100644
--- a/clang/unittests/Lex/PPDependencyDirectivesTest.cpp
+++ b/clang/unittests/Lex/PPDependencyDirectivesTest.cpp
@@ -35,7 +35,7 @@ class PPDependencyDirectivesTest : public ::testing::Test {
Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
TargetOpts->Triple = "x86_64-apple-macos12";
- Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+ Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
}
FileSystemOptions FileMgrOpts;
diff --git a/clang/unittests/Lex/PPMemoryAllocationsTest.cpp b/clang/unittests/Lex/PPMemoryAllocationsTest.cpp
index f7fb097b1f7fa..e500c1b4cd670 100644
--- a/clang/unittests/Lex/PPMemoryAllocationsTest.cpp
+++ b/clang/unittests/Lex/PPMemoryAllocationsTest.cpp
@@ -31,7 +31,7 @@ class PPMemoryAllocationsTest : public ::testing::Test {
Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
- Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+ Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
}
FileSystemOptions FileMgrOpts;
>From 7b73dfc331d2adad52dace12ab9821ca45266546 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Tue, 27 Aug 2024 11:27:28 -0700
Subject: [PATCH 2/6] [clang] Extend the lifetime of `CompilerInvocation` in
`ASTUnit::Parse()`
---
clang/include/clang/Frontend/ASTUnit.h | 4 ++++
clang/lib/Frontend/ASTUnit.cpp | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index 1f98c6ab328ba..8c2a2c0d3ba28 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -140,6 +140,10 @@ class ASTUnit {
/// LoadFromCommandLine available.
std::shared_ptr<CompilerInvocation> Invocation;
+ /// Optional owned invocation, just used to keep the invocation alive for the
+ /// members initialized in transferASTDataFromCompilerInstance.
+ std::shared_ptr<CompilerInvocation> ModifiedInvocation;
+
/// Fake module loader: the AST unit doesn't need to load any modules.
TrivialModuleLoader ModuleLoader;
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index cce2a2be3957e..66f71863e137e 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -1501,6 +1501,10 @@ void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {
Target = &CI.getTarget();
Reader = CI.getASTReader();
HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure();
+ if (Invocation != CI.getInvocationPtr()) {
+ // This happens when Parse creates a copy of \c Invocation to modify.
+ ModifiedInvocation = CI.getInvocationPtr();
+ }
}
StringRef ASTUnit::getMainFileName() const {
>From d4d28b85f203e1bed8b7ce83a3018cc328d4c668 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Tue, 27 Aug 2024 11:41:15 -0700
Subject: [PATCH 3/6] [clangd] `Preamble` owns `TargetOptions`
---
clang-tools-extra/clangd/Preamble.cpp | 7 +++++--
clang-tools-extra/clangd/Preamble.h | 2 +-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp
index b634981bb46bd..c58b1c8a2f6ed 100644
--- a/clang-tools-extra/clangd/Preamble.cpp
+++ b/clang-tools-extra/clangd/Preamble.cpp
@@ -713,7 +713,10 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
Result->Marks = CapturedInfo.takeMarks();
Result->StatCache = StatCache;
Result->MainIsIncludeGuarded = CapturedInfo.isMainFileIncludeGuarded();
- Result->TargetOpts = CI.TargetOpts;
+ // Move the options instead of copying them. The invocation doesn't need
+ // them anymore.
+ Result->TargetOpts =
+ std::make_unique<TargetOptions>(std::move(CI.getTargetOpts()));
if (PreambleCallback) {
trace::Span Tracer("Running PreambleCallback");
auto Ctx = CapturedInfo.takeLife();
@@ -934,7 +937,7 @@ void PreamblePatch::apply(CompilerInvocation &CI) const {
// ParsedASTTest.PreambleWithDifferentTarget.
// Make sure this is a deep copy, as the same Baseline might be used
// concurrently.
- *CI.TargetOpts = *Baseline->TargetOpts;
+ CI.getTargetOpts() = *Baseline->TargetOpts;
// No need to map an empty file.
if (PatchContents.empty())
diff --git a/clang-tools-extra/clangd/Preamble.h b/clang-tools-extra/clangd/Preamble.h
index be8fed4ab88cd..7f2eb233ee1aa 100644
--- a/clang-tools-extra/clangd/Preamble.h
+++ b/clang-tools-extra/clangd/Preamble.h
@@ -103,7 +103,7 @@ struct PreambleData {
// Target options used when building the preamble. Changes in target can cause
// crashes when deserializing preamble, this enables consumers to use the
// same target (without reparsing CompileCommand).
- std::shared_ptr<TargetOptions> TargetOpts = nullptr;
+ std::unique_ptr<TargetOptions> TargetOpts = nullptr;
PrecompiledPreamble Preamble;
std::vector<Diag> Diags;
// Processes like code completions and go-to-definitions will need #include
>From 99c210b71cc577fdcee5331abad1e039637799f8 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Tue, 27 Aug 2024 11:41:38 -0700
Subject: [PATCH 4/6] [clang] Hide `CompilerInvocation::TargetOpts`
---
clang/include/clang/Frontend/CompilerInvocation.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h
index 1e4d2da86c2be..05191f5ef0f7a 100644
--- a/clang/include/clang/Frontend/CompilerInvocation.h
+++ b/clang/include/clang/Frontend/CompilerInvocation.h
@@ -268,7 +268,6 @@ class CompilerInvocation : public CompilerInvocationBase {
/// Base class internals.
/// @{
using CompilerInvocationBase::LangOpts;
- using CompilerInvocationBase::TargetOpts;
std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() {
return HSOpts;
}
>From 0e28ac67fbcad623f1f13b52330809ed3038bf5b Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Tue, 27 Aug 2024 15:59:19 -0700
Subject: [PATCH 5/6] Document lifetime on `CreateTargetInfo()`
---
clang/include/clang/Basic/TargetInfo.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 4fb87428be8a0..7b6f6a7e39806 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -310,7 +310,7 @@ class TargetInfo : public TransferrableTargetInfo,
///
/// \param Opts - The options to use to initialize the target. The target may
/// modify the options to canonicalize the target feature information to match
- /// what the backend expects.
+ /// what the backend expects. These must outlive the returned TargetInfo.
static TargetInfo *CreateTargetInfo(DiagnosticsEngine &Diags,
TargetOptions &Opts);
>From d30014fb65b7433822a181ed08187c155b6df0ab Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Tue, 11 Mar 2025 10:59:10 -0700
Subject: [PATCH 6/6] Update ToolChainTest.cpp
---
clang/unittests/Driver/ToolChainTest.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp
index 14c505b5fbd9e..9fe8cd18beb9b 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -589,8 +589,7 @@ TEST(ToolChainTest, UEFICallingConventionTest) {
compiler.getTargetOpts().Triple = Tr.getTriple();
compiler.setTarget(clang::TargetInfo::CreateTargetInfo(
- compiler.getDiagnostics(),
- std::make_shared<clang::TargetOptions>(compiler.getTargetOpts())));
+ compiler.getDiagnostics(), compiler.getTargetOpts()));
EXPECT_EQ(compiler.getTarget().getCallingConvKind(true),
TargetInfo::CallingConvKind::CCK_MicrosoftWin64);
More information about the cfe-commits
mailing list