rengolin created this revision.
rengolin added reviewers: mcrosier, kristof.beyls, jmolloy.
rengolin added a subscriber: cfe-commits.
rengolin set the repository for this revision to rL LLVM.
Herald added subscribers: rengolin, aemerson.

To be able to handle -Wa, options in the assembler (ClangAs), we need to
make the handling of options based on the value of the options, not direct
Arguments from the list, since the list is immutable.

No functional change in this patch, but this allows validating of -Wa,-mfpu
and friends in the same way we validate -mfpu and friends, *just* for the
assembler.

Prepares for the PR20700 fix.

Repository:
  rL LLVM

http://reviews.llvm.org/D11147

Files:
  lib/Driver/ToolChain.cpp
  lib/Driver/Tools.cpp
  lib/Driver/Tools.h

Index: lib/Driver/Tools.h
===================================================================
--- lib/Driver/Tools.h
+++ lib/Driver/Tools.h
@@ -231,11 +231,11 @@
 } // end namespace hexagon.
 
 namespace arm {
-  std::string getARMTargetCPU(const llvm::opt::ArgList &Args,
+  std::string getARMTargetCPU(StringRef CPU, StringRef Arch,
                               const llvm::Triple &Triple);
-  const std::string getARMArch(const llvm::opt::ArgList &Args,
+  const std::string getARMArch(StringRef Arch,
                                const llvm::Triple &Triple);
-  const char* getARMCPUForMArch(const llvm::opt::ArgList &Args,
+  const char* getARMCPUForMArch(StringRef Arch,
                                 const llvm::Triple &Triple);
   const char* getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch);
 
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -502,11 +502,36 @@
   }
 }
 
+// ARM tools start.
+
+// Get SubArch (vN).
+static int getARMSubArchVersionNumber(const llvm::Triple &Triple) {
+  llvm::StringRef Arch = Triple.getArchName();
+  return llvm::ARMTargetParser::parseArchVersion(Arch);
+}
+
+// True if M-profile.
+static bool isARMMProfile(const llvm::Triple &Triple) {
+  llvm::StringRef Arch = Triple.getArchName();
+  unsigned Profile = llvm::ARMTargetParser::parseArchProfile(Arch);
+  return Profile == llvm::ARM::PK_M;
+}
+
+// Get Arch/CPU from args.
+static void getARMArchCPUFromArgs(const ArgList &Args,
+                                  llvm::StringRef &Arch,
+                                  llvm::StringRef &CPU) {
+  if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+    CPU = A->getValue();
+  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
+    Arch = A->getValue();
+}
+
 // Handle -mhwdiv=.
 static void getARMHWDivFeatures(const Driver &D, const Arg *A,
                                 const ArgList &Args,
+                                StringRef HWDiv,
                                 std::vector<const char *> &Features) {
-  StringRef HWDiv = A->getValue();
   if (HWDiv == "arm") {
     Features.push_back("+hwdiv-arm");
     Features.push_back("-hwdiv");
@@ -526,22 +551,33 @@
 // Handle -mfpu=.
 static void getARMFPUFeatures(const Driver &D, const Arg *A,
                               const ArgList &Args,
+                              StringRef FPU,
                               std::vector<const char *> &Features) {
-  StringRef FPU = A->getValue();
   unsigned FPUID = llvm::ARMTargetParser::parseFPU(FPU);
   if (!llvm::ARMTargetParser::getFPUFeatures(FPUID, Features))
     D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
 }
 
-static int getARMSubArchVersionNumber(const llvm::Triple &Triple) {
-  llvm::StringRef Arch = Triple.getArchName();
-  return llvm::ARMTargetParser::parseArchVersion(Arch);
+// Check -march=.
+static void checkARMArchName(const Driver &D, const Arg *A,
+                             const ArgList &Args,
+                             llvm::StringRef ArchName,
+                             const llvm::Triple &Triple) {
+  std::string MArch = arm::getARMArch(ArchName, Triple);
+  if (llvm::ARMTargetParser::parseArch(MArch) == llvm::ARM::AK_INVALID)
+    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
 }
 
-static bool isARMMProfile(const llvm::Triple &Triple) {
-  llvm::StringRef Arch = Triple.getArchName();
-  unsigned Profile = llvm::ARMTargetParser::parseArchProfile(Arch);
-  return Profile == llvm::ARM::PK_M;
+// Check -mcpu=.
+static void checkARMCPUName(const Driver &D, const Arg *A,
+                            const ArgList &Args,
+                            llvm::StringRef CPUName,
+                            llvm::StringRef ArchName,
+                            const llvm::Triple &Triple) {
+  std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
+  std::string Arch = arm::getARMArch(ArchName, Triple);
+  if (strcmp(arm::getLLVMArchSuffixForARM(CPU, Arch), "") == 0)
+    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
 }
 
 // Select the float ABI as determined by -msoft-float, -mhard-float, and
@@ -665,27 +701,27 @@
 
   // Honor -mfpu=.
   if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
-    getARMFPUFeatures(D, A, Args, Features);
+    getARMFPUFeatures(D, A, Args, A->getValue(), Features);
+  // Honor -mhwdiv=
   if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ))
-    getARMHWDivFeatures(D, A, Args, Features);
+    getARMHWDivFeatures(D, A, Args, A->getValue(), Features);
 
   // Check if -march is valid by checking if it can be canonicalised and parsed.
   // getARMArch is used here instead of just checking the -march value in order
   // to handle -march=native correctly.
+  StringRef ArchName;
   if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
-    std::string Arch = arm::getARMArch(Args, Triple);
-    if (llvm::ARMTargetParser::parseArch(Arch) == llvm::ARM::AK_INVALID)
-      D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
+    ArchName = A->getValue();
+    checkARMArchName(D, A, Args, ArchName, Triple);
   }
 
   // We do a similar thing with -mcpu, but here things are complicated because
   // the only function we have to check if a cpu is valid is
   // getLLVMArchSuffixForARM which also needs an architecture.
+  StringRef CPUName;
   if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
-    std::string CPU = arm::getARMTargetCPU(Args, Triple);
-    std::string Arch = arm::getARMArch(Args, Triple);
-    if (strcmp(arm::getLLVMArchSuffixForARM(CPU, Arch), "") == 0)
-      D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
+    CPUName = A->getValue();
+    checkARMCPUName(D, A, Args, CPUName, ArchName, Triple);
   }
 
   // Setting -msoft-float effectively disables NEON because of the GCC
@@ -836,6 +872,7 @@
     CmdArgs.push_back("-arm-reserve-r9");
   }
 }
+// ARM tools end.
 
 /// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
 /// targeting.
@@ -1475,9 +1512,11 @@
   case llvm::Triple::arm:
   case llvm::Triple::armeb:
   case llvm::Triple::thumb:
-  case llvm::Triple::thumbeb:
-    return arm::getARMTargetCPU(Args, T);
-
+  case llvm::Triple::thumbeb: {
+    StringRef MArch, MCPU;
+    getARMArchCPUFromArgs(Args, MArch, MCPU);
+    return arm::getARMTargetCPU(MCPU, MArch, T);
+  }
   case llvm::Triple::mips:
   case llvm::Triple::mipsel:
   case llvm::Triple::mips64:
@@ -5749,16 +5788,13 @@
 }
 // Hexagon tools end.
 
-const std::string arm::getARMArch(const ArgList &Args,
+const std::string arm::getARMArch(StringRef Arch,
                                   const llvm::Triple &Triple) {
   std::string MArch;
-  if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
-    // Otherwise, if we have -march= choose the base CPU for that arch.
-    MArch = A->getValue();
-  } else {
-    // Otherwise, use the Arch from the triple.
+  if (!Arch.empty())
+    MArch = Arch;
+  else
     MArch = Triple.getArchName();
-  }
   MArch = StringRef(MArch).lower();
 
   // Handle -march=native.
@@ -5779,9 +5815,9 @@
   return MArch;
 }
 /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
-const char *arm::getARMCPUForMArch(const ArgList &Args,
+const char *arm::getARMCPUForMArch(StringRef Arch,
                                    const llvm::Triple &Triple) {
-  std::string MArch = getARMArch(Args, Triple);
+  std::string MArch = getARMArch(Arch, Triple);
   // getARMCPUForArch defaults to the triple if MArch is empty, but empty MArch
   // here means an -march=native that we can't handle, so instead return no CPU.
   if (MArch.empty())
@@ -5797,12 +5833,13 @@
 }
 
 /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
-std::string arm::getARMTargetCPU(const ArgList &Args,
+std::string arm::getARMTargetCPU(StringRef CPU,
+                                 StringRef Arch,
                                  const llvm::Triple &Triple) {
   // FIXME: Warn on inconsistent use of -mcpu and -march.
   // If we have -mcpu=, use that.
-  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
-    std::string MCPU = StringRef(A->getValue()).lower();
+  if (!CPU.empty()) {
+    std::string MCPU = StringRef(CPU).lower();
     // Handle -mcpu=native.
     if (MCPU == "native")
       return llvm::sys::getHostCPUName();
@@ -5810,7 +5847,7 @@
       return MCPU;
   }
 
-  return getARMCPUForMArch(Args, Triple);
+  return getARMCPUForMArch(Arch, Triple);
 }
 
 /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
@@ -7309,8 +7346,10 @@
   case llvm::Triple::armeb:
   case llvm::Triple::thumb:
   case llvm::Triple::thumbeb: {
-    std::string MArch = arm::getARMTargetCPU(Args, getToolChain().getTriple());
-    CmdArgs.push_back(Args.MakeArgString("-mcpu=" + MArch));
+    StringRef MArch, MCPU;
+    getARMArchCPUFromArgs(Args, MArch, MCPU);
+    std::string Arch = arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple());
+    CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch));
     break;
   }
 
Index: lib/Driver/ToolChain.cpp
===================================================================
--- lib/Driver/ToolChain.cpp
+++ lib/Driver/ToolChain.cpp
@@ -303,12 +303,17 @@
     // Thumb2 is the default for V7 on Darwin.
     //
     // FIXME: Thumb should just be another -target-feaure, not in the triple.
+    StringRef MCPU, MArch;
+    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
+      MCPU = A->getValue();
+    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
+      MArch = A->getValue();
     std::string CPU = Triple.isOSBinFormatMachO()
-      ? tools::arm::getARMCPUForMArch(Args, Triple)
-      : tools::arm::getARMTargetCPU(Args, Triple);
+      ? tools::arm::getARMCPUForMArch(MArch, Triple)
+      : tools::arm::getARMTargetCPU(MCPU, MArch, Triple);
     StringRef Suffix = 
       tools::arm::getLLVMArchSuffixForARM(CPU,
-                                          tools::arm::getARMArch(Args, Triple));
+                                          tools::arm::getARMArch(MArch, Triple));
     bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") ||
       Suffix.startswith("v7em") ||
       (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO());
_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to