<div dir="ltr">Looks like I can. Will do.<div><br></div><div>BTW many command line handling functions takes not std::vector but SmallVector. Do you know why?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jun 6, 2015 at 8:21 PM, Rafael Espíndola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Could this use  cl::ExpandResponseFiles?<br>
<div class="HOEnZb"><div class="h5"><br>
On 6 June 2015 at 22:55, Rui Ueyama <<a href="mailto:ruiu@google.com">ruiu@google.com</a>> wrote:<br>
> Author: ruiu<br>
> Date: Sat Jun  6 21:55:19 2015<br>
> New Revision: 239242<br>
><br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D239242-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=b-x7AI9kNrzLRQWn1yzx-Up3DlbMlUMXdw_OqVAmd6I&s=aCoWPH72nZZuLTpohKRd4Jr9q2-pg4fwe6PVBfD_sKE&e=" target="_blank">http://llvm.org/viewvc/llvm-project?rev=239242&view=rev</a><br>
> Log:<br>
> COFF: Support resonpse files.<br>
><br>
> Added:<br>
>     lld/trunk/test/COFF/responsefile.test<br>
> Modified:<br>
>     lld/trunk/COFF/Driver.cpp<br>
>     lld/trunk/COFF/Driver.h<br>
>     lld/trunk/COFF/DriverUtils.cpp<br>
><br>
> Modified: lld/trunk/COFF/Driver.cpp<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lld_trunk_COFF_Driver.cpp-3Frev-3D239242-26r1-3D239241-26r2-3D239242-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=b-x7AI9kNrzLRQWn1yzx-Up3DlbMlUMXdw_OqVAmd6I&s=JmYI3Wrz-wyH_iiLcThcFjJfvQHNRlXFuvBvt_6pOlk&e=" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=239242&r1=239241&r2=239242&view=diff</a><br>
> ==============================================================================<br>
> --- lld/trunk/COFF/Driver.cpp (original)<br>
> +++ lld/trunk/COFF/Driver.cpp Sat Jun  6 21:55:19 2015<br>
> @@ -77,31 +77,12 @@ ErrorOr<std::unique_ptr<InputFile>> Link<br>
>    return std::unique_ptr<InputFile>(new ObjectFile(MBRef));<br>
>  }<br>
><br>
> -namespace {<br>
> -class BumpPtrStringSaver : public llvm::cl::StringSaver {<br>
> -public:<br>
> -  BumpPtrStringSaver(lld::coff::StringAllocator *A) : Alloc(A) {}<br>
> -  const char *SaveString(const char *S) override {<br>
> -    return Alloc->save(S).data();<br>
> -  }<br>
> -  lld::coff::StringAllocator *Alloc;<br>
> -};<br>
> -}<br>
> -<br>
>  // Parses .drectve section contents and returns a list of files<br>
>  // specified by /defaultlib.<br>
>  std::error_code<br>
>  LinkerDriver::parseDirectives(StringRef S,<br>
>                                std::vector<std::unique_ptr<InputFile>> *Res) {<br>
> -  SmallVector<const char *, 16> Tokens;<br>
> -  Tokens.push_back("link"); // argv[0] value. Will be ignored.<br>
> -  BumpPtrStringSaver Saver(&Alloc);<br>
> -  llvm::cl::TokenizeWindowsCommandLine(S, Saver, Tokens);<br>
> -  Tokens.push_back(nullptr);<br>
> -  int Argc = Tokens.size() - 1;<br>
> -  const char **Argv = &Tokens[0];<br>
> -<br>
> -  auto ArgsOrErr = parseArgs(Argc, Argv);<br>
> +  auto ArgsOrErr = Parser.parse(S);<br>
>    if (auto EC = ArgsOrErr.getError())<br>
>      return EC;<br>
>    std::unique_ptr<llvm::opt::InputArgList> Args = std::move(ArgsOrErr.get());<br>
> @@ -204,7 +185,7 @@ bool LinkerDriver::link(int Argc, const<br>
>    llvm::InitializeAllDisassemblers();<br>
><br>
>    // Parse command line options.<br>
> -  auto ArgsOrErr = parseArgs(Argc, Argv);<br>
> +  auto ArgsOrErr = Parser.parse(Argc, Argv);<br>
>    if (auto EC = ArgsOrErr.getError()) {<br>
>      llvm::errs() << EC.message() << "\n";<br>
>      return false;<br>
><br>
> Modified: lld/trunk/COFF/Driver.h<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lld_trunk_COFF_Driver.h-3Frev-3D239242-26r1-3D239241-26r2-3D239242-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=b-x7AI9kNrzLRQWn1yzx-Up3DlbMlUMXdw_OqVAmd6I&s=ED9w9gLG7lBlUBokmqf66fKC2HIi-s_HtHb7P5TQp-o&e=" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=239242&r1=239241&r2=239242&view=diff</a><br>
> ==============================================================================<br>
> --- lld/trunk/COFF/Driver.h (original)<br>
> +++ lld/trunk/COFF/Driver.h Sat Jun  6 21:55:19 2015<br>
> @@ -35,6 +35,29 @@ class InputFile;<br>
>  // Entry point of the COFF linker.<br>
>  bool link(int Argc, const char *Argv[]);<br>
><br>
> +class ArgParser {<br>
> +public:<br>
> +  // Parses command line options.<br>
> +  ErrorOr<std::unique_ptr<llvm::opt::InputArgList>> parse(int Argc,<br>
> +                                                          const char *Argv[]);<br>
> +<br>
> +  // Tokenizes a given string and then parses as command line options.<br>
> +  ErrorOr<std::unique_ptr<llvm::opt::InputArgList>> parse(StringRef S) {<br>
> +    return parse(tokenize(S));<br>
> +  }<br>
> +<br>
> +private:<br>
> +  ErrorOr<std::unique_ptr<llvm::opt::InputArgList>><br>
> +  parse(std::vector<const char *> Argv);<br>
> +<br>
> +  std::vector<const char *> tokenize(StringRef S);<br>
> +<br>
> +  ErrorOr<std::vector<const char *>><br>
> +  replaceResponseFiles(std::vector<const char *>);<br>
> +<br>
> +  StringAllocator Alloc;<br>
> +};<br>
> +<br>
>  class LinkerDriver {<br>
>  public:<br>
>   LinkerDriver() : SearchPaths(getSearchPaths()) {}<br>
> @@ -46,6 +69,7 @@ public:<br>
><br>
>  private:<br>
>    StringAllocator Alloc;<br>
> +  ArgParser Parser;<br>
><br>
>    // Opens a file. Path has to be resolved already.<br>
>    ErrorOr<std::unique_ptr<InputFile>> openFile(StringRef Path);<br>
> @@ -68,9 +92,6 @@ private:<br>
>    std::vector<std::unique_ptr<MemoryBuffer>> OwningMBs;<br>
>  };<br>
><br>
> -ErrorOr<std::unique_ptr<llvm::opt::InputArgList>><br>
> -parseArgs(int Argc, const char *Argv[]);<br>
> -<br>
>  // Functions below this line are defined in DriverUtils.cpp.<br>
><br>
>  void printHelp(const char *Argv0);<br>
><br>
> Modified: lld/trunk/COFF/DriverUtils.cpp<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lld_trunk_COFF_DriverUtils.cpp-3Frev-3D239242-26r1-3D239241-26r2-3D239242-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=b-x7AI9kNrzLRQWn1yzx-Up3DlbMlUMXdw_OqVAmd6I&s=wjIvjbVFFHILUImpSIM1bYFYRViSJ2zMdcH_1Okzl7U&e=" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=239242&r1=239241&r2=239242&view=diff</a><br>
> ==============================================================================<br>
> --- lld/trunk/COFF/DriverUtils.cpp (original)<br>
> +++ lld/trunk/COFF/DriverUtils.cpp Sat Jun  6 21:55:19 2015<br>
> @@ -159,13 +159,24 @@ public:<br>
>    COFFOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable), true) {}<br>
>  };<br>
><br>
> +// Parses a given list of options.<br>
>  ErrorOr<std::unique_ptr<llvm::opt::InputArgList>><br>
> -parseArgs(int Argc, const char *Argv[]) {<br>
> +ArgParser::parse(std::vector<const char *> Argv) {<br>
> +  // First, replace respnose files (@<file>-style options).<br>
> +  auto ArgvOrErr = replaceResponseFiles(Argv);<br>
> +  if (auto EC = ArgvOrErr.getError()) {<br>
> +    llvm::errs() << "error while reading response file: " << EC.message()<br>
> +                 << "\n";<br>
> +    return EC;<br>
> +  }<br>
> +  Argv = std::move(ArgvOrErr.get());<br>
> +<br>
> +  // Make InputArgList from string vectors.<br>
>    COFFOptTable Table;<br>
>    unsigned MissingIndex;<br>
>    unsigned MissingCount;<br>
> -  std::unique_ptr<llvm::opt::InputArgList> Args(<br>
> -      Table.ParseArgs(&Argv[1], &Argv[Argc], MissingIndex, MissingCount));<br>
> +  std::unique_ptr<llvm::opt::InputArgList> Args(Table.ParseArgs(<br>
> +      &Argv[0], &Argv[0] + Argv.size(), MissingIndex, MissingCount));<br>
>    if (MissingCount) {<br>
>      llvm::errs() << "missing arg value for \""<br>
>                   << Args->getArgString(MissingIndex)<br>
> @@ -178,6 +189,55 @@ parseArgs(int Argc, const char *Argv[])<br>
>    return std::move(Args);<br>
>  }<br>
><br>
> +ErrorOr<std::unique_ptr<llvm::opt::InputArgList>><br>
> +ArgParser::parse(int Argc, const char *Argv[]) {<br>
> +  std::vector<const char *> V;<br>
> +  V.insert(V.end(), Argv + 1, Argv + Argc);<br>
> +  return parse(V);<br>
> +}<br>
> +<br>
> +namespace {<br>
> +class BumpPtrStringSaver : public llvm::cl::StringSaver {<br>
> +public:<br>
> +  BumpPtrStringSaver(lld::coff::StringAllocator *A) : Alloc(A) {}<br>
> +  const char *SaveString(const char *S) override {<br>
> +    return Alloc->save(S).data();<br>
> +  }<br>
> +  lld::coff::StringAllocator *Alloc;<br>
> +};<br>
> +}<br>
> +<br>
> +std::vector<const char *> ArgParser::tokenize(StringRef S) {<br>
> +  SmallVector<const char *, 16> Tokens;<br>
> +  BumpPtrStringSaver Saver(&Alloc);<br>
> +  llvm::cl::TokenizeWindowsCommandLine(S, Saver, Tokens);<br>
> +  std::vector<const char *> V;<br>
> +  V.insert(V.end(), &Tokens[0], &Tokens[0] + Tokens.size());<br>
> +  return V;<br>
> +}<br>
> +<br>
> +// Creates a new command line by replaceing options starting with '@'<br>
> +// character. '@<filename>' is replaced by the file's contents.<br>
> +ErrorOr<std::vector<const char *>><br>
> +ArgParser::replaceResponseFiles(std::vector<const char *> Argv) {<br>
> +  std::vector<const char *> V;<br>
> +  for (const char *S : Argv) {<br>
> +    if (S[0] != '@') {<br>
> +      V.push_back(S);<br>
> +      continue;<br>
> +    }<br>
> +    StringRef Path = S + 1;<br>
> +    auto BufOrErr = MemoryBuffer::getFile(Path);<br>
> +    if (auto EC = BufOrErr.getError())<br>
> +      return EC;<br>
> +    std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());<br>
> +    StringRef Str = Alloc.save(Buf->getBuffer());<br>
> +    std::vector<const char *> Tokens = tokenize(Str);<br>
> +    V.insert(V.end(), Tokens.begin(), Tokens.end());<br>
> +  }<br>
> +  return V;<br>
> +}<br>
> +<br>
>  void printHelp(const char *Argv0) {<br>
>    COFFOptTable Table;<br>
>    Table.PrintHelp(llvm::outs(), Argv0, "LLVM Linker", false);<br>
><br>
> Added: lld/trunk/test/COFF/responsefile.test<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lld_trunk_test_COFF_responsefile.test-3Frev-3D239242-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=b-x7AI9kNrzLRQWn1yzx-Up3DlbMlUMXdw_OqVAmd6I&s=JfzdS1viM9FJNzUO-MbAWg_3yk5UZ0TrT2AurKMb8LQ&e=" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/responsefile.test?rev=239242&view=auto</a><br>
> ==============================================================================<br>
> --- lld/trunk/test/COFF/responsefile.test (added)<br>
> +++ lld/trunk/test/COFF/responsefile.test Sat Jun  6 21:55:19 2015<br>
> @@ -0,0 +1,7 @@<br>
> +# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj<br>
> +<br>
> +# RUN: echo /out:%t.exe %t.obj > %t.rsp<br>
> +# RUN: lld -flavor link2 @%t.rsp /heap:0x3000<br>
> +# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s<br>
> +<br>
> +CHECK: SizeOfHeapReserve: 12288<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">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>
</div></div></blockquote></div><br></div>