[PATCH] Teach Clang how to use response files when calling other tools

Sean Silva chisophugis at gmail.com
Fri Aug 29 16:06:03 PDT 2014


================
Comment at: lib/Driver/Job.cpp:105
@@ +104,3 @@
+static bool ArgNeedsQuotes(const char *Str) {
+  return Str[0] == '\0' || strpbrk(Str, "\t \"&\'()*<>\\`^|") != 0;
+}
----------------
Tiny nit: Use nullptr instead of 0

================
Comment at: lib/Driver/Job.cpp:133-139
@@ +132,9 @@
+/// Check if string \p Arg is present in the list of inputs.
+static bool isInInputList(const llvm::SmallVectorImpl<const char *> &Inputs,
+                          const char *Arg) {
+  for (auto InputName : Inputs) {
+    if (strcmp(Arg, InputName) == 0)
+      return true;
+  }
+  return false;
+}
----------------
In the future, consider using std::find_if instead of writing this function http://en.cppreference.com/w/cpp/algorithm/find

I'm not sure a linear search here is acceptable though, see my comment below.

================
Comment at: lib/Driver/Job.cpp:144-150
@@ +143,9 @@
+/// file.
+static llvm::SmallVector<const char *, 128>
+buildArgvForResponseFile(const char *ResponseFlag, const char *Executable) {
+  llvm::SmallVector<const char *, 128> Argv;
+  Argv.push_back(Executable);
+  Argv.push_back(ResponseFlag);
+  return Argv;
+}
+
----------------
This seems like an unusual thing to have a helper for. The real problem seems to be that this is part of a larger block of code which is duplicated. Just pulling out this part doesn't help things: get rid of this helper function and deduplicate a larger scope.

================
Comment at: lib/Driver/Job.cpp:163
@@ +162,3 @@
+/// \p Arguments - Original arguments when calling the tool
+static llvm::SmallVector<const char *, 128>
+buildArgvForFileList(const llvm::SmallVectorImpl<const char *> &Inputs,
----------------
Returning a SmallVector by value is undesirable. in this case, I think NRVO will negate part of the issue (large sizeof), but you still have the problem that this hardcodes what SmallVector size the caller is using. I would recommend switching this to taking a non-const `SmallVectorImpl<const char *> &Out` instead of returning a SmallVector.

================
Comment at: lib/Driver/Job.cpp:172
@@ +171,3 @@
+  for (auto Arg : Arguments) {
+    if (!isInInputList(Inputs, Arg)) {
+      Argv.push_back(Arg);
----------------
isInInputList seems to be doing linear work. If Arguments is mostly Inputs, then this will go quadratic. Is that a potential problem?

================
Comment at: lib/Driver/Job.cpp:185-186
@@ +184,4 @@
+static void
+writeFileList(raw_ostream &OS,
+              const llvm::SmallVectorImpl<const char *> &Inputs) {
+  for (auto Arg : Inputs) {
----------------
Use ArrayRef here.

================
Comment at: lib/Driver/Job.cpp:187-190
@@ +186,6 @@
+              const llvm::SmallVectorImpl<const char *> &Inputs) {
+  for (auto Arg : Inputs) {
+    OS << Arg;
+    OS << '\n';
+  }
+}
----------------
Simpler:

```
for (auto Arg : Inputs)
  OS << Arg << '\n';
```

Also, for clarity, consider just saying const char * instead of auto.

================
Comment at: lib/Driver/Job.cpp:205
@@ +204,3 @@
+    ResponseFlag = Creator.getResponseFileFlag();
+    ResponseFlag += ResponseFile.data();
+    if (RespFileSup == Tool::RF_FileList)
----------------
I don't think this is correct. ResponseFile.data() isn't guaranteed to be 0 terminated (and you don't want to embed that hidden assumption). Maybe use .append(begin, end)?

================
Comment at: lib/Driver/Job.cpp:216-232
@@ -104,16 +215,19 @@
+
+  for (size_t i = 0, e = Args.size(); i < e; ++i) {
+    const char *const Arg = Args[i];
 
     if (CrashReport) {
       if (int Skip = skipArgs(Arg)) {
         i += Skip - 1;
         continue;
       }
     }
 
     OS << ' ';
     PrintArg(OS, Arg, Quote);
 
     if (CrashReport && quoteNextArg(Arg) && i + 1 < e) {
       OS << ' ';
-      PrintArg(OS, Arguments[++i], true);
+      PrintArg(OS, Args[++i], true);
     }
   }
----------------
This loop scares me. Could you clean this up in a separate patch? Or at least add comment here for now.

================
Comment at: lib/Driver/Job.cpp:235
@@ +234,3 @@
+
+  if (NeedsResponseFile && ResponseFile.data() != nullptr) {
+    OS << "\n Arguments passed via response file:\n";
----------------
This call seems duplicated, along with a lot of stuff in this if. Pull this into a helper?

================
Comment at: lib/Driver/Tools.h:309
@@ +308,3 @@
+    }
+    virtual const char *getResponseFileFlag() const override {
+      return "-filelist";
----------------
Tiny nit: Don't use `virtual` with `override`.

================
Comment at: lib/Driver/Tools.h:531-537
@@ -441,1 +530,9 @@
+
+    ResponseFileSupport getResponseFilesSupport() const override {
+      return RF_Full;
+    }
+    llvm::sys::fs::WindowsEncodingMethod
+    getResponseFileEncoding() const override {
+      return llvm::sys::fs::WEM_CurrentCodePage;
+    }
   };
----------------
This seems highly repetitive. Is there a way to reduce it?

Also, I'm not sure that it makes sense to have a method returning WindowsEncodingMethod for a netbsd tool (same goes for most tools that have no reason to run on windows).

http://reviews.llvm.org/D4897






More information about the cfe-commits mailing list