]> granicus.if.org Git - clang/commitdiff
clang-cl: Implement the /Tc, /TC, /Tp and /TP options.
authorHans Wennborg <hans@hanshq.net>
Tue, 6 Aug 2013 00:20:31 +0000 (00:20 +0000)
committerHans Wennborg <hans@hanshq.net>
Tue, 6 Aug 2013 00:20:31 +0000 (00:20 +0000)
These are used to specify source files, and whether to treat source
files as C or C++.

Differential Revision: http://llvm-reviews.chandlerc.com/D1290

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187760 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticDriverKinds.td
include/clang/Driver/CLCompatOptions.td
lib/Driver/Driver.cpp
test/Driver/cl-inputs.c [new file with mode: 0644]
test/Driver/cl-options.c

index 68e13584ed3660a96180ed3b153701cdf3094f45..266e2f0f76bb993f53c4581cce81a3816aca2299 100644 (file)
@@ -133,6 +133,9 @@ def warn_drv_assuming_mfloat_abi_is : Warning<
   "unknown platform, assuming -mfloat-abi=%0">;
 def warn_ignoring_ftabstop_value : Warning<
   "ignoring invalid -ftabstop value '%0', using default value %1">;
+def warn_drv_overriding_t_option : Warning<
+  "overriding '%0' option with '%1'">,
+  InGroup<DiagGroup<"overriding-t-option">>;
 def warn_drv_treating_input_as_cxx : Warning<
   "treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
   InGroup<Deprecated>;
index d3494da5d74ad19ed15af8639a3fc5d758992f5b..5a3ad805ce4a36c597557284484990b30ed1f79c 100644 (file)
@@ -81,6 +81,16 @@ def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">,
   Alias<fsyntax_only>;
 
 
+// Non-aliases:
+
+def _SLASH_Tc : CLJoinedOrSeparate<"Tc">, HelpText<"Specify a C source file">,
+  MetaVarName<"<filename>">;
+def _SLASH_TC : CLFlag<"TC">, HelpText<"Treat all source files as C">;
+def _SLASH_Tp : CLJoinedOrSeparate<"Tp">, HelpText<"Specify a C++ source file">,
+  MetaVarName<"<filename>">;
+def _SLASH_TP : CLFlag<"TP">, HelpText<"Treat all source files as C++">;
+
+
 // Ignored:
 
 def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">;
@@ -114,10 +124,6 @@ def _SLASH_MTd : CLFlag<"MTd">;
 def _SLASH_Oi : CLFlag<"Oi">;
 def _SLASH_RTC : CLJoined<"RTC">;
 def _SLASH_showIncludes : CLJoined<"showIncludes">;
-def _SLASH_Tc : CLJoined<"Tc">;
-def _SLASH_TC : CLFlag<"TC">;
-def _SLASH_Tp : CLJoined<"Tp">;
-def _SLASH_TP : CLFlag<"TP">;
 def _SLASH_w : CLJoined<"w">;
 def _SLASH_Zc : CLJoined<"Zc:">;
 def _SLASH_ZI : CLFlag<"ZI">;
index 4f9cd3e38a0f920c08d6949033b6af57f7035166..84e5fe2cfbb75afd7b860f946a5e946a36e42a1f 100644 (file)
@@ -943,6 +943,41 @@ void Driver::BuildUniversalActions(const ToolChain &TC,
   }
 }
 
+/// \brief Check that the file referenced by Value exists. If it doesn't,
+/// issue a diagnostic and return false.
+static bool DiagnoseInputExistance(const Driver &D, const DerivedArgList &Args,
+                                   StringRef Value) {
+  if (!D.getCheckInputsExist())
+    return true;
+
+  // stdin always exists.
+  if (Value == "-")
+    return true;
+
+  SmallString<64> Path(Value);
+  if (Arg *WorkDir = Args.getLastArg(options::OPT_working_directory)) {
+    if (!llvm::sys::path::is_absolute(Path.str())) {
+      SmallString<64> Directory(WorkDir->getValue());
+      llvm::sys::path::append(Directory, Value);
+      Path.assign(Directory);
+    }
+  }
+
+  if (llvm::sys::fs::exists(Twine(Path)))
+    return true;
+
+  D.Diag(clang::diag::err_drv_no_such_file) << Path.str();
+  return false;
+}
+
+static Arg* MakeInputArg(const DerivedArgList &Args, OptTable *Opts,
+                         StringRef Value) {
+  unsigned Index = Args.getBaseArgs().MakeIndex(Value);
+  Arg *A = Opts->ParseOneArg(Args, Index);
+  A->claim();
+  return A;
+}
+
 // Construct a the list of inputs and their types.
 void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
                          InputList &Inputs) const {
@@ -952,6 +987,29 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
   types::ID InputType = types::TY_Nothing;
   Arg *InputTypeArg = 0;
 
+  // The /TC and /TP options set the input type to C or C++ globally.
+  if (Arg *TCTP = Args.getLastArg(options::OPT__SLASH_TC,
+                                  options::OPT__SLASH_TP)) {
+    InputTypeArg = TCTP;
+    unsigned opposite;
+
+    if (TCTP->getOption().matches(options::OPT__SLASH_TC)) {
+      InputType = types::TY_C;
+      opposite = options::OPT__SLASH_TP;
+    } else {
+      InputType = types::TY_CXX;
+      opposite = options::OPT__SLASH_TC;
+    }
+
+    if (Arg *OppositeArg = Args.getLastArg(opposite)) {
+      Diag(clang::diag::warn_drv_overriding_t_option)
+        << OppositeArg->getSpelling() << InputTypeArg->getSpelling();
+    }
+
+    // No driver mode exposes -x and /TC or /TP; we don't support mixing them.
+    assert(!Args.hasArg(options::OPT_x) && "-x and /TC or /TP is not allowed");
+  }
+
   for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
        it != ie; ++it) {
     Arg *A = *it;
@@ -1020,24 +1078,23 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
         Ty = InputType;
       }
 
-      // Check that the file exists, if enabled.
-      if (CheckInputsExist && memcmp(Value, "-", 2) != 0) {
-        SmallString<64> Path(Value);
-        if (Arg *WorkDir = Args.getLastArg(options::OPT_working_directory)) {
-          if (!llvm::sys::path::is_absolute(Path.str())) {
-            SmallString<64> Directory(WorkDir->getValue());
-            llvm::sys::path::append(Directory, Value);
-            Path.assign(Directory);
-          }
-        }
-
-        if (!llvm::sys::fs::exists(Twine(Path)))
-          Diag(clang::diag::err_drv_no_such_file) << Path.str();
-        else
-          Inputs.push_back(std::make_pair(Ty, A));
-      } else
+      if (DiagnoseInputExistance(*this, Args, Value))
         Inputs.push_back(std::make_pair(Ty, A));
 
+    } else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
+      StringRef Value = A->getValue();
+      if (DiagnoseInputExistance(*this, Args, Value)) {
+        Arg *InputArg = MakeInputArg(Args, Opts, A->getValue());
+        Inputs.push_back(std::make_pair(types::TY_C, InputArg));
+      }
+      A->claim();
+    } else if (A->getOption().matches(options::OPT__SLASH_Tp)) {
+      StringRef Value = A->getValue();
+      if (DiagnoseInputExistance(*this, Args, Value)) {
+        Arg *InputArg = MakeInputArg(Args, Opts, A->getValue());
+        Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
+      }
+      A->claim();
     } else if (A->getOption().hasFlag(options::LinkerInput)) {
       // Just treat as object type, we could make a special type for this if
       // necessary.
@@ -1060,9 +1117,7 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
   if (CCCIsCPP() && Inputs.empty()) {
     // If called as standalone preprocessor, stdin is processed
     // if no other input is present.
-    unsigned Index = Args.getBaseArgs().MakeIndex("-");
-    Arg *A = Opts->ParseOneArg(Args, Index);
-    A->claim();
+    Arg *A = MakeInputArg(Args, Opts, "-");
     Inputs.push_back(std::make_pair(types::TY_C, A));
   }
 }
diff --git a/test/Driver/cl-inputs.c b/test/Driver/cl-inputs.c
new file mode 100644 (file)
index 0000000..1918e4c
--- /dev/null
@@ -0,0 +1,22 @@
+// Don't attempt slash switches on msys bash.\r
+// REQUIRES: shell-preserves-root\r
+\r
+// Note: %s must be preceded by --, otherwise it may be interpreted as a\r
+// command-line option, e.g. on Mac where %s is commonly under /Users.\r
+\r
+// RUN: %clang_cl /TC -### -- %s 2>&1 | FileCheck -check-prefix=TC %s\r
+// TC:  "-x" "c"\r
+\r
+// RUN: %clang_cl /TP -### -- %s 2>&1 | FileCheck -check-prefix=TP %s\r
+// TP:  "-x" "c++"\r
+\r
+// RUN: %clang_cl -### /Tc%s 2>&1 | FileCheck -check-prefix=Tc %s\r
+// RUN: %clang_cl -### /TP /Tc%s 2>&1 | FileCheck -check-prefix=Tc %s\r
+// Tc:  "-x" "c"\r
+\r
+// RUN: %clang_cl -### /Tp%s 2>&1 | FileCheck -check-prefix=Tp %s\r
+// RUN: %clang_cl -### /TC /Tp%s 2>&1 | FileCheck -check-prefix=Tp %s\r
+// Tp:  "-x" "c++"\r
+\r
+// RUN: %clang_cl /TP /TC -### -- %s 2>&1 | FileCheck -check-prefix=WARN %s\r
+// WARN: overriding '/TP' option with '/TC'\r
index 44d32350adbe7dacb5ead3a835e276a700ccd0cc..ca286f739d9cc3b113341a118d1fb077658f70b4 100644 (file)
@@ -90,5 +90,5 @@
 // (/Zs is for syntax-only)
 // RUN: %clang_cl /Zs /EHsc /Fdfoo /Fobar /fp:precise /Gd /GL /GL- -- %s 2>&1
 // RUN: %clang_cl /Zs /Gm /Gm- /GS /Gy /Gy- /GZ /MD /MT /MDd /MTd /Oi -- %s 2>&1
-// RUN: %clang_cl /Zs /RTC1 /Tcfoo /TC /Tpbar /TP /wfoo /Zc:wchar_t- -- %s 2>&1
+// RUN: %clang_cl /Zs /RTC1 /wfoo /Zc:wchar_t- -- %s 2>&1
 // RUN: %clang_cl /Zs /ZI /Zi /showIncludes -- %s 2>&1