<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Mar 28, 2014 at 1:37 PM, Reid Kleckner <span dir="ltr"><<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">On Fri, Mar 28, 2014 at 12:34 PM, Rui Ueyama <span dir="ltr"><<a href="mailto:ruiu@google.com" target="_blank">ruiu@google.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: ruiu<br>
Date: Fri Mar 28 14:34:34 2014<br>
New Revision: 205038<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=205038&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=205038&view=rev</a><br>
Log:<br>
[ELF] Support response file.<br>
<br>
Response file is a command line argument in the form of @file. The GNU-<br>
compatible driver expands the file contents, replacing @file argument.<br>
<br>
Differential Revision: <a href="http://llvm-reviews.chandlerc.com/D3210" target="_blank">http://llvm-reviews.chandlerc.com/D3210</a><br>
<br>
Added:<br>
    lld/trunk/test/elf/Inputs/responsefile<br>
    lld/trunk/test/elf/responsefile.test<br>
Modified:<br>
    lld/trunk/lib/Driver/GnuLdDriver.cpp<br>
<br>
Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=205038&r1=205037&r2=205038&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=205038&r1=205037&r2=205038&view=diff</a><br>



==============================================================================<br>
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)<br>
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Fri Mar 28 14:34:34 2014<br>
@@ -32,8 +32,13 @@<br>
 #include "llvm/Support/raw_ostream.h"<br>
 #include "llvm/Support/Signals.h"<br>
<br>
+#include <cstring><br>
+#include <tuple><br>
+<br>
 using namespace lld;<br>
<br>
+using llvm::BumpPtrAllocator;<br>
+<br>
 namespace {<br>
<br>
 // Create enum with OPT_xxx values for each option in GnuLdOptions.td<br>
@@ -68,8 +73,49 @@ public:<br>
   GnuLdOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable)){}<br>
 };<br>
<br>
+class DriverStringSaver : public llvm::cl::StringSaver {<br>
+public:<br>
+  DriverStringSaver(BumpPtrAllocator &alloc) : _alloc(alloc) {}<br>
+<br>
+  const char *SaveString(const char *s) override {<br>
+    char *p = _alloc.Allocate<char>(strlen(s) + 1);<br>
+    strcpy(p, s);<br>
+    return p;<br>
+  }<br>
+<br>
+private:<br>
+  BumpPtrAllocator &_alloc;<br>
+};<br>
+<br>
 } // anonymous namespace<br>
<br>
+// If a command line option starts with "@", the driver reads its suffix as a<br>
+// file, parse its contents as a list of command line options, and insert them<br>
+// at the original @file position. If file cannot be read, @file is not expanded<br>
+// and left unmodified. @file can appear in a response file, so it's a recursive<br>
+// process.<br>
+static std::tuple<int, const char **><br>
+maybeExpandResponseFiles(int argc, const char **argv, BumpPtrAllocator &alloc) {<br>
+  // Expand response files.<br>
+  SmallVector<const char *, 256> smallvec;<br>
+  for (int i = 0; i < argc; ++i)<br>
+    smallvec.push_back(argv[i]);<br>
+  DriverStringSaver saver(alloc);<br>
+  llvm::cl::ExpandResponseFiles(saver, llvm::cl::TokenizeGNUCommandLine, smallvec);<br>
+<br>
+  // Pack the results to a C-array.<br>
+  argc = smallvec.size();<br>
+  std::vector<const char *> result;<br>
+  for (size_t i = 0, e = smallvec.size(); i < e; ++i)<br>
+    result.push_back(smallvec[i]);<br>
+  result.push_back(nullptr);  // terminate ARGV with NULL<br></blockquote><div><br></div></div></div><div>Why do you need an intermediate std::vector here?  It looks unused.</div><div class=""><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



+<br>
+  // Allocate memory for the result and return it.<br>
+  const char **copy = alloc.Allocate<const char *>(argc + 1);<br>
+  std::copy(smallvec.begin(), smallvec.end(), copy);<br></blockquote><div><br></div></div><div>Do you need to append a null pointer to this?</div></div></div></div></blockquote><div><br></div><div>These are issues indeed. Will address in a followup patch.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



+  return std::make_tuple(argc, copy);<br>
+}<br>
+<br>
 // Get the Input file magic for creating appropriate InputGraph nodes.<br>
 static error_code getFileMagic(ELFLinkingContext &ctx, StringRef path,<br>
                                llvm::sys::fs::file_magic &magic) {<br>
@@ -118,6 +164,8 @@ std::string ELFFileNode::errStr(error_co<br>
<br>
 bool GnuLdDriver::linkELF(int argc, const char *argv[],<br>
                           raw_ostream &diagnostics) {<br>
+  BumpPtrAllocator alloc;<br>
+  std::tie(argc, argv) = maybeExpandResponseFiles(argc, argv, alloc);<br>
   std::unique_ptr<ELFLinkingContext> options;<br>
   if (!parse(argc, argv, options, diagnostics))<br>
     return false;<br>
@@ -133,7 +181,6 @@ bool GnuLdDriver::linkELF(int argc, cons<br>
   if (options->allowLinkWithDynamicLibraries())<br>
     options->registry().addSupportELFDynamicSharedObjects(<br>
         options->useShlibUndefines(), options->targetHandler());<br>
-<br>
   return link(*options, diagnostics);<br>
 }<br>
<br>
<br>
Added: lld/trunk/test/elf/Inputs/responsefile<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/responsefile?rev=205038&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/responsefile?rev=205038&view=auto</a><br>



==============================================================================<br>
--- lld/trunk/test/elf/Inputs/responsefile (added)<br>
+++ lld/trunk/test/elf/Inputs/responsefile Fri Mar 28 14:34:34 2014<br>
@@ -0,0 +1 @@<br>
+--inresponsefile<br>
<br>
Added: lld/trunk/test/elf/responsefile.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/responsefile.test?rev=205038&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/responsefile.test?rev=205038&view=auto</a><br>



==============================================================================<br>
--- lld/trunk/test/elf/responsefile.test (added)<br>
+++ lld/trunk/test/elf/responsefile.test Fri Mar 28 14:34:34 2014<br>
@@ -0,0 +1,6 @@<br>
+# RUN: not lld -flavor gnu --abc @%p/Inputs/responsefile --baz >& %t.log<br>
+# RUN: FileCheck %s < %t.log<br>
+<br>
+CHECK: warning: ignoring unknown argument: --abc<br>
+CHECK: warning: ignoring unknown argument: --inresponsefile<br>
+CHECK: warning: ignoring unknown argument: --baz<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>