[mips] Improve handling of -fno-[pic/PIC] option

In order to disable PIC and to match GCC behaviour, -mno-abicalls
option is neccessary. When -fno-[pic/PIC] is used witout -mno-abicalls,
warning is reported. An error is reported when -fno-pic or -fno-PIC is
used in combination with -mabicalls.

In this commit, test case is added.

Depends on D44381.

Differential Revision: https://reviews.llvm.org/D44684

llvm-svn: 331640
diff --git a/clang/lib/Driver/ToolChains/Arch/Mips.cpp b/clang/lib/Driver/ToolChains/Arch/Mips.cpp
index e72754d..a8bed7d 100644
--- a/clang/lib/Driver/ToolChains/Arch/Mips.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/Mips.cpp
@@ -214,6 +214,7 @@
   // For case (a) we need to add +noabicalls for N64.
 
   bool IsN64 = ABIName == "64";
+  bool IsPIC = false;
   bool NonPIC = false;
 
   Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
@@ -225,6 +226,9 @@
     NonPIC =
         (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) ||
          O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
+    IsPIC =
+        (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
+         O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie));
   }
 
   bool UseAbiCalls = false;
@@ -234,9 +238,14 @@
   UseAbiCalls =
       !ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls);
 
-  if (UseAbiCalls && IsN64 && NonPIC) {
-    D.Diag(diag::warn_drv_unsupported_abicalls);
-    UseAbiCalls = false;
+  if (IsN64 && NonPIC && (!ABICallsArg || UseAbiCalls)) {
+    D.Diag(diag::warn_drv_unsupported_pic_with_mabicalls)
+        << LastPICArg->getAsString(Args) << (!ABICallsArg ? 0 : 1);
+    NonPIC = false;
+  }
+
+  if (ABICallsArg && !UseAbiCalls && IsPIC) {
+    D.Diag(diag::err_drv_unsupported_noabicalls_pic);
   }
 
   if (!UseAbiCalls)
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index be09bc1..7013b43 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1018,6 +1018,14 @@
        Triple.getArch() == llvm::Triple::mipsel ||
        Triple.getArch() == llvm::Triple::mips64 ||
        Triple.getArch() == llvm::Triple::mips64el) {
+    StringRef CPUName;
+    StringRef ABIName;
+    mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
+    // When targeting the N64 ABI, PIC is the default, except in the case
+    // when the -mno-abicalls option is used. In that case we exit
+    // at next check regardless of PIC being set below.
+    if (ABIName == "n64")
+      PIC = true;
     // When targettng MIPS with -mno-abicalls, it's always static.
     if(Args.hasArg(options::OPT_mno_abicalls))
       return std::make_tuple(llvm::Reloc::Static, 0U, false);