From: Reid Kleckner Date: Thu, 18 Jul 2013 20:00:53 +0000 (+0000) Subject: [Driver] Use LLVM's response file parser because it can read UTF-16 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=87f2cb5aec7b81ea6f6f9fbf6e14ef4f2de6dea6;p=clang [Driver] Use LLVM's response file parser because it can read UTF-16 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 --- diff --git a/test/Driver/at_file.c b/test/Driver/at_file.c index 4ad2a5fde3..ea9004c9d5 100644 --- a/test/Driver/at_file.c +++ b/test/Driver/at_file.c @@ -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 diff --git a/test/Driver/at_file.c.args b/test/Driver/at_file.c.args index 9a2b4ee93b..8e73597a6b 100644 --- a/test/Driver/at_file.c.args +++ b/test/Driver/at_file.c.args @@ -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 index 0000000000..a2ff0240ee Binary files /dev/null and b/test/Driver/at_file.c.args.utf16le differ diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp index 48eeed91ea..2a40a86c91 100644 --- a/tools/driver/driver.cpp +++ b/tools/driver/driver.cpp @@ -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 &ArgVector, - std::set &SavedStrings) { - const char *FName = Arg + 1; - OwningPtr 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 &ArgVector, - std::set &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 &ArgVector, std::set &SavedStrings, Driver &TheDriver) @@ -342,14 +271,26 @@ static void ParseProgName(SmallVectorImpl &ArgVector, } } +namespace { + class StringSetSaver : public llvm::cl::StringSaver { + public: + StringSetSaver(std::set &Storage) : Storage(Storage) {} + const char *SaveString(const char *Str) LLVM_OVERRIDE { + return SaveStringInSet(Storage, Str); + } + private: + std::set &Storage; + }; +} + int main(int argc_, const char **argv_) { llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc_, argv_); std::set SavedStrings; - SmallVector argv; - - ExpandArgv(argc_, argv_, argv, SavedStrings); + SmallVector 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")) {