[clang] Hide the TargetOptions pointer from CompilerInvocation (#106271)
This PR hides the reference-counted pointer that holds `TargetOptions` from the public API of `CompilerInvocation`. This gives `CompilerInvocation` an exclusive control over the lifetime of this member, which will eventually be leveraged to implement a copy-on-write behavior. There are two clients that currently share ownership of that pointer: * `TargetInfo` - This was refactored to hold a non-owning reference to `TargetOptions`. The options object is typically owned by the `CompilerInvocation` or by the new `CompilerInstance::AuxTargetOpts` for the auxiliary target. This needed a bit of care in `ASTUnit::Parse()` to keep the `CompilerInvocation` alive. * `clangd::PreambleData` - This was refactored to exclusively own the `TargetOptions` that get moved out of the `CompilerInvocation`.
This commit is contained in:
@@ -711,7 +711,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();
|
||||
@@ -932,7 +935,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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -256,7 +256,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)), HSOpts(),
|
||||
HeaderInfo(new HeaderSearch(HSOpts, *SourceMgr, *Diagnostics, *LangOpts,
|
||||
|
||||
@@ -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
|
||||
@@ -310,10 +310,9 @@ public:
|
||||
///
|
||||
/// \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);
|
||||
/// what the backend expects. These must outlive the returned TargetInfo.
|
||||
static TargetInfo *CreateTargetInfo(DiagnosticsEngine &Diags,
|
||||
TargetOptions &Opts);
|
||||
|
||||
virtual ~TargetInfo();
|
||||
|
||||
|
||||
@@ -143,6 +143,10 @@ private:
|
||||
/// Parse available.
|
||||
std::shared_ptr<CompilerInvocation> CCInvocation;
|
||||
|
||||
/// 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;
|
||||
|
||||
|
||||
@@ -88,6 +88,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;
|
||||
|
||||
|
||||
@@ -268,7 +268,6 @@ public:
|
||||
/// Base class internals.
|
||||
/// @{
|
||||
using CompilerInvocationBase::LangOpts;
|
||||
using CompilerInvocationBase::TargetOpts;
|
||||
std::shared_ptr<LangOptions> getLangOptsPtr() { return LangOpts; }
|
||||
/// @}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -615,7 +615,7 @@ public:
|
||||
|
||||
this->TargetOpts = std::make_shared<TargetOptions>(TargetOpts);
|
||||
Target =
|
||||
TargetInfo::CreateTargetInfo(PP.getDiagnostics(), this->TargetOpts);
|
||||
TargetInfo::CreateTargetInfo(PP.getDiagnostics(), *this->TargetOpts);
|
||||
|
||||
updated();
|
||||
return false;
|
||||
@@ -1499,6 +1499,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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -110,7 +110,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() {
|
||||
if (!getAuxTarget() &&
|
||||
(getLangOpts().CUDA || getLangOpts().isTargetDevice()) &&
|
||||
!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) {
|
||||
|
||||
@@ -125,7 +125,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. "
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -39,7 +39,7 @@ protected:
|
||||
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__
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ protected:
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -34,7 +34,7 @@ protected:
|
||||
SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions),
|
||||
Search(HSOpts, 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) {
|
||||
|
||||
@@ -48,7 +48,7 @@ protected:
|
||||
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,
|
||||
|
||||
@@ -58,7 +58,7 @@ protected:
|
||||
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>
|
||||
|
||||
@@ -139,7 +139,7 @@ protected:
|
||||
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;
|
||||
|
||||
@@ -36,7 +36,7 @@ protected:
|
||||
TargetOpts(new TargetOptions)
|
||||
{
|
||||
TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
|
||||
Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
|
||||
Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
|
||||
}
|
||||
|
||||
FileSystemOptions FileMgrOpts;
|
||||
|
||||
@@ -35,7 +35,7 @@ protected:
|
||||
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;
|
||||
|
||||
@@ -31,7 +31,7 @@ protected:
|
||||
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;
|
||||
|
||||
@@ -72,7 +72,7 @@ protected:
|
||||
SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
|
||||
// This is an arbitrarily chosen target triple to create the target info.
|
||||
TargetOpts->Triple = "dxil";
|
||||
Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
|
||||
Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts);
|
||||
}
|
||||
|
||||
std::unique_ptr<Preprocessor> createPP(StringRef Source,
|
||||
|
||||
@@ -789,7 +789,7 @@ ClangExpressionParser::ClangExpressionParser(
|
||||
|
||||
if (auto *target_info = TargetInfo::CreateTargetInfo(
|
||||
m_compiler->getDiagnostics(),
|
||||
m_compiler->getInvocation().TargetOpts)) {
|
||||
m_compiler->getInvocation().getTargetOpts())) {
|
||||
if (log) {
|
||||
LLDB_LOGF(log, "Target datalayout string: '%s'",
|
||||
target_info->getDataLayoutString());
|
||||
|
||||
@@ -742,7 +742,7 @@ ClangModulesDeclVendor::Create(Target &target) {
|
||||
std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction);
|
||||
|
||||
instance->setTarget(clang::TargetInfo::CreateTargetInfo(
|
||||
*diagnostics_engine, instance->getInvocation().TargetOpts));
|
||||
*diagnostics_engine, instance->getInvocation().getTargetOpts()));
|
||||
|
||||
if (!instance->hasTarget())
|
||||
return nullptr;
|
||||
|
||||
@@ -744,7 +744,7 @@ TargetInfo *TypeSystemClang::getTargetInfo() {
|
||||
// target_triple should be something like "x86_64-apple-macosx"
|
||||
if (m_target_info_up == nullptr && !m_target_triple.empty())
|
||||
m_target_info_up.reset(TargetInfo::CreateTargetInfo(
|
||||
getASTContext().getDiagnostics(), getTargetOptions()));
|
||||
getASTContext().getDiagnostics(), *getTargetOptions()));
|
||||
return m_target_info_up.get();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user