]> granicus.if.org Git - clang/commitdiff
[Driver] Use LLVM's response file parser because it can read UTF-16
authorReid Kleckner <reid@kleckner.net>
Thu, 18 Jul 2013 20:00:53 +0000 (20:00 +0000)
committerReid Kleckner <reid@kleckner.net>
Thu, 18 Jul 2013 20:00:53 +0000 (20:00 +0000)
MSBuild writes response files as UTF-16 little endian with a byte order
mark.  With this change, clang will be able to read them, although we
still can't parse any of their flags.

Adds a UTF-16-LE response file with a BOM for testing.

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

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

test/Driver/at_file.c
test/Driver/at_file.c.args
test/Driver/at_file.c.args.utf16le [new file with mode: 0644]
tools/driver/driver.cpp

index 4ad2a5fde3d6eae95c2884ce35fb60966db24e46..ea9004c9d573b25b307d6b1df077039170055b18 100644 (file)
@@ -1,5 +1,7 @@
 // RUN: %clang -E %s @%s.args -o %t.log
 // RUN: FileCheck --input-file=%t.log %s
+// RUN: %clang -E %s @%s.args.utf16le -o %t.log
+// RUN: FileCheck --input-file=%t.log %s
 
 // CHECK: bar1
 // CHECK-NEXT: bar2 zed2
@@ -13,6 +15,7 @@
 // CHECK-NEXT: foo10"bar10"zed10
 // CHECK: bar
 // CHECK: zed12
+// CHECK: one\two
 
 foo1
 foo2
@@ -28,3 +31,4 @@ foo10
 bar
 #endif
 foo12
+foo13
index 9a2b4ee93bd37fe532622c213bb55af9cd4e95d3..8e73597a6bf1119353c4da4c5188472ef655465b 100644 (file)
@@ -9,3 +9,4 @@
 -Dfoo10=foo10\"bar10\"zed10
 -D foo11
 -Dfoo12=zed12\
+-Dfoo13='one\\two'
diff --git a/test/Driver/at_file.c.args.utf16le b/test/Driver/at_file.c.args.utf16le
new file mode 100644 (file)
index 0000000..a2ff024
Binary files /dev/null and b/test/Driver/at_file.c.args.utf16le differ
index 48eeed91eafef6dff1a7027c9214861b4a9538e2..2a40a86c912d8652d105df0149333abc4a46b995 100644 (file)
@@ -29,6 +29,7 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/OptTable.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
@@ -189,78 +190,6 @@ extern int cc1_main(const char **ArgBegin, const char **ArgEnd,
 extern int cc1as_main(const char **ArgBegin, const char **ArgEnd,
                       const char *Argv0, void *MainAddr);
 
-static void ExpandArgsFromBuf(const char *Arg,
-                              SmallVectorImpl<const char*> &ArgVector,
-                              std::set<std::string> &SavedStrings) {
-  const char *FName = Arg + 1;
-  OwningPtr<llvm::MemoryBuffer> MemBuf;
-  if (llvm::MemoryBuffer::getFile(FName, MemBuf)) {
-    ArgVector.push_back(SaveStringInSet(SavedStrings, Arg));
-    return;
-  }
-
-  const char *Buf = MemBuf->getBufferStart();
-  char InQuote = ' ';
-  std::string CurArg;
-
-  for (const char *P = Buf; ; ++P) {
-    if (*P == '\0' || (isWhitespace(*P) && InQuote == ' ')) {
-      if (!CurArg.empty()) {
-
-        if (CurArg[0] != '@') {
-          ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg));
-        } else {
-          ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings);
-        }
-
-        CurArg = "";
-      }
-      if (*P == '\0')
-        break;
-      else
-        continue;
-    }
-
-    if (isWhitespace(*P)) {
-      if (InQuote != ' ')
-        CurArg.push_back(*P);
-      continue;
-    }
-
-    if (*P == '"' || *P == '\'') {
-      if (InQuote == *P)
-        InQuote = ' ';
-      else if (InQuote == ' ')
-        InQuote = *P;
-      else
-        CurArg.push_back(*P);
-      continue;
-    }
-
-    if (*P == '\\') {
-      ++P;
-      if (*P != '\0')
-        CurArg.push_back(*P);
-      continue;
-    }
-    CurArg.push_back(*P);
-  }
-}
-
-static void ExpandArgv(int argc, const char **argv,
-                       SmallVectorImpl<const char*> &ArgVector,
-                       std::set<std::string> &SavedStrings) {
-  for (int i = 0; i < argc; ++i) {
-    const char *Arg = argv[i];
-    if (Arg[0] != '@') {
-      ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg)));
-      continue;
-    }
-
-    ExpandArgsFromBuf(Arg, ArgVector, SavedStrings);
-  }
-}
-
 static void ParseProgName(SmallVectorImpl<const char *> &ArgVector,
                           std::set<std::string> &SavedStrings,
                           Driver &TheDriver)
@@ -342,14 +271,26 @@ static void ParseProgName(SmallVectorImpl<const char *> &ArgVector,
   }
 }
 
+namespace {
+  class StringSetSaver : public llvm::cl::StringSaver {
+  public:
+    StringSetSaver(std::set<std::string> &Storage) : Storage(Storage) {}
+    const char *SaveString(const char *Str) LLVM_OVERRIDE {
+      return SaveStringInSet(Storage, Str);
+    }
+  private:
+    std::set<std::string> &Storage;
+  };
+}
+
 int main(int argc_, const char **argv_) {
   llvm::sys::PrintStackTraceOnErrorSignal();
   llvm::PrettyStackTraceProgram X(argc_, argv_);
 
   std::set<std::string> SavedStrings;
-  SmallVector<const char*, 256> argv;
-
-  ExpandArgv(argc_, argv_, argv, SavedStrings);
+  SmallVector<const char*, 256> argv(argv_, argv_ + argc_);
+  StringSetSaver Saver(SavedStrings);
+  llvm::cl::ExpandResponseFiles(Saver, llvm::cl::TokenizeGNUCommandLine, argv);
 
   // Handle -cc1 integrated tools.
   if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1")) {