https://github.com/mincrmatt12 created https://github.com/llvm/llvm-project/pull/115798
This adds an extra validation step to `ToolChain::getTargetAndModeFromProgramName` to actually try constructing the target info for the triple it deduces, instead of just relying on the LLVM target registry. Some targets, like `xtensa`, are supported by LLVM but are not supported by clang, so just checking the LLVM registry causes inconsistency. This is based on the discussion from clangd/clangd#2184 (and indeed would solve that issue) - the approach here of "construct the target info and check for null" is taken from [clangd](https://github.com/llvm/llvm-project/blob/5716f836d25e93bf8f664a14fe55c70e07a369be/clang-tools-extra/clangd/SystemIncludeExtractor.cpp#L253). >From f111040a50db8275b1d6aaee3cf5e4b8af2b08f5 Mon Sep 17 00:00:00 2001 From: Matthew Mirvish <matt...@mm12.xyz> Date: Mon, 11 Nov 2024 20:20:20 -0500 Subject: [PATCH] [Clang][Driver] Ensure clang can construct toolchain target names This adds an extra validation step to `ToolChain::getTargetAndModeFromProgramName` to actually try constructing the target info for the triple it deduces, instead of just relying on the LLVM target registry. Some targets, like `xtensa`, are supported by LLVM but are not supported by clang, so just checking the LLVM registry causes inconsistency. --- clang/lib/Driver/ToolChain.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 646dbc0faf5a9f..e094a5fd0267f3 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -16,6 +16,8 @@ #include "ToolChains/InterfaceStubs.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/Sanitizers.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" #include "clang/Config/config.h" #include "clang/Driver/Action.h" #include "clang/Driver/Driver.h" @@ -496,8 +498,21 @@ ToolChain::getTargetAndModeFromProgramName(StringRef PN) { StringRef Prefix(ProgName); Prefix = Prefix.slice(0, LastComponent); std::string IgnoredError; + + // First, check if the target is a supported LLVM target. bool IsRegistered = llvm::TargetRegistry::lookupTarget(std::string(Prefix), IgnoredError); + // If so, further check that clang is able to use it as a target. + if (IsRegistered) { + std::shared_ptr<TargetOptions> TargetOpts(new TargetOptions); + TargetOpts->Triple = Prefix.str(); + DiagnosticsEngine Diags(new DiagnosticIDs, new DiagnosticOptions, + new IgnoringDiagConsumer); + llvm::IntrusiveRefCntPtr<TargetInfo> Target = + clang::TargetInfo::CreateTargetInfo(Diags, TargetOpts); + if (!Target) + IsRegistered = false; + } return ParsedClangName{std::string(Prefix), ModeSuffix, DS->ModeFlag, IsRegistered}; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits