start wiring up support for target-specific -mfoo options like -msse


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65881 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/clang.cpp b/Driver/clang.cpp
index f402a20..54e93f8 100644
--- a/Driver/clang.cpp
+++ b/Driver/clang.cpp
@@ -517,6 +517,12 @@
 static llvm::cl::opt<bool>
 Ansi("ansi", llvm::cl::desc("Equivalent to specifying -std=c89."));
 
+
+static llvm::cl::list<std::string>
+TargetOptions("m", llvm::cl::Prefix, llvm::cl::value_desc("option"),
+          llvm::cl::desc("Target-specific options, such as -msse3"));
+
+
 // FIXME: add:
 //   -fdollars-in-identifiers
 static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
@@ -524,6 +530,23 @@
   // Allow the target to set the default the langauge options as it sees fit.
   Target->getDefaultLangOptions(Options);
   
+  // If the user specified any -mfoo options, pass them to the target for
+  // validation and processing.
+  if (!TargetOptions.empty()) {
+    std::string ErrorStr;
+    int Opt = Target->HandleTargetOptions(&TargetOptions[0],
+                                          TargetOptions.size(), ErrorStr);
+    if (Opt != -1) {
+      if (ErrorStr.empty())
+        fprintf(stderr, "invalid command line option '%s'\n",
+                TargetOptions[Opt].c_str());
+      else
+        fprintf(stderr, "command line option '%s': %s\n",
+                TargetOptions[Opt].c_str(), ErrorStr.c_str());
+      exit(1);
+    }
+  }
+  
   if (Ansi) // "The -ansi option is equivalent to -std=c89."
     LangStd = lang_c89;
   
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 00edc57..b9c8b14 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -249,6 +249,16 @@
   /// options. 
   virtual void getDefaultLangOptions(LangOptions &Opts) {}
 
+  /// HandleTargetOptions - Handle target-specific options like -msse2 and
+  /// friends.  An array of arguments is passed in: if they are all valid, this
+  /// should handle them and return -1.  If there is an error, the index of the
+  /// invalid argument should be returned along with an optional error string.
+  virtual int HandleTargetOptions(std::string *StrArray, unsigned NumStrs,
+                                  std::string &ErrorReason) {
+    if (NumStrs == 0)
+      return -1;
+    return 0;
+  }
 protected:
   virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
     return PointerWidth;