aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Driver/ToolChain.cpp
diff options
context:
space:
mode:
authorMichael Platings <michael.platings@arm.com>2023-03-09 19:38:26 +0000
committerMichael Platings <michael.platings@arm.com>2023-06-14 06:46:41 +0100
commita794ab92b41f00ba29b5852c34a510173638dcc0 (patch)
treef951a50a7dd8739e33c9abde1623dd7d2dfa7f7b /clang/lib/Driver/ToolChain.cpp
parent4794bdab7aed92e699db29e031bfe71f4005326f (diff)
downloadllvm-a794ab92b41f00ba29b5852c34a510173638dcc0.zip
llvm-a794ab92b41f00ba29b5852c34a510173638dcc0.tar.gz
llvm-a794ab92b41f00ba29b5852c34a510173638dcc0.tar.bz2
[Driver] Add -print-multi-flags-experimental option
This option causes the flags used for selecting multilibs to be printed. This is an experimental feature that is documented in detail in D143587. Differential Revision: https://reviews.llvm.org/D142933
Diffstat (limited to 'clang/lib/Driver/ToolChain.cpp')
-rw-r--r--clang/lib/Driver/ToolChain.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index ccaebb3..9276b9a 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -7,8 +7,10 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/ToolChain.h"
+#include "ToolChains/Arch/AArch64.h"
#include "ToolChains/Arch/ARM.h"
#include "ToolChains/Clang.h"
+#include "ToolChains/CommonArgs.h"
#include "ToolChains/Flang.h"
#include "ToolChains/InterfaceStubs.h"
#include "clang/Basic/ObjCRuntime.h"
@@ -39,6 +41,7 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/TargetParser/AArch64TargetParser.h"
#include "llvm/TargetParser/TargetParser.h"
#include "llvm/TargetParser/Triple.h"
#include <cassert>
@@ -171,6 +174,101 @@ bool ToolChain::defaultToIEEELongDouble() const {
return PPC_LINUX_DEFAULT_IEEELONGDOUBLE && getTriple().isOSLinux();
}
+static void getAArch64MultilibFlags(const Driver &D,
+ const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args,
+ Multilib::flags_list &Result) {
+ std::vector<StringRef> Features;
+ tools::aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, false);
+ const auto UnifiedFeatures = tools::unifyTargetFeatures(Features);
+ llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
+ UnifiedFeatures.end());
+ std::vector<std::string> MArch;
+ for (const auto &Ext : AArch64::Extensions)
+ if (FeatureSet.find(Ext.Feature) != FeatureSet.end())
+ MArch.push_back(Ext.Name.str());
+ for (const auto &Ext : AArch64::Extensions)
+ if (FeatureSet.find(Ext.NegFeature) != FeatureSet.end())
+ MArch.push_back(("no" + Ext.Name).str());
+ MArch.insert(MArch.begin(), ("-march=" + Triple.getArchName()).str());
+ Result.push_back(llvm::join(MArch, "+"));
+}
+
+static void getARMMultilibFlags(const Driver &D,
+ const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args,
+ Multilib::flags_list &Result) {
+ std::vector<StringRef> Features;
+ llvm::ARM::FPUKind FPUKind =
+ tools::arm::getARMTargetFeatures(D, Triple, Args, Features, false);
+ const auto UnifiedFeatures = tools::unifyTargetFeatures(Features);
+ llvm::DenseSet<StringRef> FeatureSet(UnifiedFeatures.begin(),
+ UnifiedFeatures.end());
+ std::vector<std::string> MArch;
+ for (const auto &Ext : ARM::ARCHExtNames)
+ if (FeatureSet.find(Ext.Feature) != FeatureSet.end())
+ MArch.push_back(Ext.Name.str());
+ for (const auto &Ext : ARM::ARCHExtNames)
+ if (FeatureSet.find(Ext.NegFeature) != FeatureSet.end())
+ MArch.push_back(("no" + Ext.Name).str());
+ MArch.insert(MArch.begin(), ("-march=" + Triple.getArchName()).str());
+ Result.push_back(llvm::join(MArch, "+"));
+
+ switch (FPUKind) {
+#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
+ case llvm::ARM::KIND: \
+ Result.push_back("-mfpu=" NAME); \
+ break;
+#include "llvm/TargetParser/ARMTargetParser.def"
+ default:
+ llvm_unreachable("Invalid FPUKind");
+ }
+
+ switch (arm::getARMFloatABI(D, Triple, Args)) {
+ case arm::FloatABI::Soft:
+ Result.push_back("-mfloat-abi=soft");
+ break;
+ case arm::FloatABI::SoftFP:
+ Result.push_back("-mfloat-abi=softfp");
+ break;
+ case arm::FloatABI::Hard:
+ Result.push_back("-mfloat-abi=hard");
+ break;
+ case arm::FloatABI::Invalid:
+ llvm_unreachable("Invalid float ABI");
+ }
+}
+
+Multilib::flags_list
+ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
+ using namespace clang::driver::options;
+
+ std::vector<std::string> Result;
+ const llvm::Triple Triple(ComputeEffectiveClangTriple(Args));
+ Result.push_back("--target=" + Triple.str());
+
+ switch (Triple.getArch()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
+ case llvm::Triple::aarch64_be:
+ getAArch64MultilibFlags(D, Triple, Args, Result);
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ getARMMultilibFlags(D, Triple, Args, Result);
+ break;
+ default:
+ break;
+ }
+
+ // Sort and remove duplicates.
+ std::sort(Result.begin(), Result.end());
+ Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
+ return Result;
+}
+
SanitizerArgs
ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const {
SanitizerArgs SanArgs(*this, JobArgs, !SanitizerArgsChecked);