[lld] r239242 - COFF: Support resonpse files.

Rui Ueyama ruiu at google.com
Sat Jun 6 19:55:20 PDT 2015


Author: ruiu
Date: Sat Jun  6 21:55:19 2015
New Revision: 239242

URL: http://llvm.org/viewvc/llvm-project?rev=239242&view=rev
Log:
COFF: Support resonpse files.

Added:
    lld/trunk/test/COFF/responsefile.test
Modified:
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/Driver.h
    lld/trunk/COFF/DriverUtils.cpp

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=239242&r1=239241&r2=239242&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Sat Jun  6 21:55:19 2015
@@ -77,31 +77,12 @@ ErrorOr<std::unique_ptr<InputFile>> Link
   return std::unique_ptr<InputFile>(new ObjectFile(MBRef));
 }
 
-namespace {
-class BumpPtrStringSaver : public llvm::cl::StringSaver {
-public:
-  BumpPtrStringSaver(lld::coff::StringAllocator *A) : Alloc(A) {}
-  const char *SaveString(const char *S) override {
-    return Alloc->save(S).data();
-  }
-  lld::coff::StringAllocator *Alloc;
-};
-}
-
 // Parses .drectve section contents and returns a list of files
 // specified by /defaultlib.
 std::error_code
 LinkerDriver::parseDirectives(StringRef S,
                               std::vector<std::unique_ptr<InputFile>> *Res) {
-  SmallVector<const char *, 16> Tokens;
-  Tokens.push_back("link"); // argv[0] value. Will be ignored.
-  BumpPtrStringSaver Saver(&Alloc);
-  llvm::cl::TokenizeWindowsCommandLine(S, Saver, Tokens);
-  Tokens.push_back(nullptr);
-  int Argc = Tokens.size() - 1;
-  const char **Argv = &Tokens[0];
-
-  auto ArgsOrErr = parseArgs(Argc, Argv);
+  auto ArgsOrErr = Parser.parse(S);
   if (auto EC = ArgsOrErr.getError())
     return EC;
   std::unique_ptr<llvm::opt::InputArgList> Args = std::move(ArgsOrErr.get());
@@ -204,7 +185,7 @@ bool LinkerDriver::link(int Argc, const
   llvm::InitializeAllDisassemblers();
 
   // Parse command line options.
-  auto ArgsOrErr = parseArgs(Argc, Argv);
+  auto ArgsOrErr = Parser.parse(Argc, Argv);
   if (auto EC = ArgsOrErr.getError()) {
     llvm::errs() << EC.message() << "\n";
     return false;

Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=239242&r1=239241&r2=239242&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Sat Jun  6 21:55:19 2015
@@ -35,6 +35,29 @@ class InputFile;
 // Entry point of the COFF linker.
 bool link(int Argc, const char *Argv[]);
 
+class ArgParser {
+public:
+  // Parses command line options.
+  ErrorOr<std::unique_ptr<llvm::opt::InputArgList>> parse(int Argc,
+                                                          const char *Argv[]);
+
+  // Tokenizes a given string and then parses as command line options.
+  ErrorOr<std::unique_ptr<llvm::opt::InputArgList>> parse(StringRef S) {
+    return parse(tokenize(S));
+  }
+
+private:
+  ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>
+  parse(std::vector<const char *> Argv);
+
+  std::vector<const char *> tokenize(StringRef S);
+
+  ErrorOr<std::vector<const char *>>
+  replaceResponseFiles(std::vector<const char *>);
+
+  StringAllocator Alloc;
+};
+
 class LinkerDriver {
 public:
  LinkerDriver() : SearchPaths(getSearchPaths()) {}
@@ -46,6 +69,7 @@ public:
 
 private:
   StringAllocator Alloc;
+  ArgParser Parser;
 
   // Opens a file. Path has to be resolved already.
   ErrorOr<std::unique_ptr<InputFile>> openFile(StringRef Path);
@@ -68,9 +92,6 @@ private:
   std::vector<std::unique_ptr<MemoryBuffer>> OwningMBs;
 };
 
-ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>
-parseArgs(int Argc, const char *Argv[]);
-
 // Functions below this line are defined in DriverUtils.cpp.
 
 void printHelp(const char *Argv0);

Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=239242&r1=239241&r2=239242&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Sat Jun  6 21:55:19 2015
@@ -159,13 +159,24 @@ public:
   COFFOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable), true) {}
 };
 
+// Parses a given list of options.
 ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>
-parseArgs(int Argc, const char *Argv[]) {
+ArgParser::parse(std::vector<const char *> Argv) {
+  // First, replace respnose files (@<file>-style options).
+  auto ArgvOrErr = replaceResponseFiles(Argv);
+  if (auto EC = ArgvOrErr.getError()) {
+    llvm::errs() << "error while reading response file: " << EC.message()
+                 << "\n";
+    return EC;
+  }
+  Argv = std::move(ArgvOrErr.get());
+
+  // Make InputArgList from string vectors.
   COFFOptTable Table;
   unsigned MissingIndex;
   unsigned MissingCount;
-  std::unique_ptr<llvm::opt::InputArgList> Args(
-      Table.ParseArgs(&Argv[1], &Argv[Argc], MissingIndex, MissingCount));
+  std::unique_ptr<llvm::opt::InputArgList> Args(Table.ParseArgs(
+      &Argv[0], &Argv[0] + Argv.size(), MissingIndex, MissingCount));
   if (MissingCount) {
     llvm::errs() << "missing arg value for \""
                  << Args->getArgString(MissingIndex)
@@ -178,6 +189,55 @@ parseArgs(int Argc, const char *Argv[])
   return std::move(Args);
 }
 
+ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>
+ArgParser::parse(int Argc, const char *Argv[]) {
+  std::vector<const char *> V;
+  V.insert(V.end(), Argv + 1, Argv + Argc);
+  return parse(V);
+}
+
+namespace {
+class BumpPtrStringSaver : public llvm::cl::StringSaver {
+public:
+  BumpPtrStringSaver(lld::coff::StringAllocator *A) : Alloc(A) {}
+  const char *SaveString(const char *S) override {
+    return Alloc->save(S).data();
+  }
+  lld::coff::StringAllocator *Alloc;
+};
+}
+
+std::vector<const char *> ArgParser::tokenize(StringRef S) {
+  SmallVector<const char *, 16> Tokens;
+  BumpPtrStringSaver Saver(&Alloc);
+  llvm::cl::TokenizeWindowsCommandLine(S, Saver, Tokens);
+  std::vector<const char *> V;
+  V.insert(V.end(), &Tokens[0], &Tokens[0] + Tokens.size());
+  return V;
+}
+
+// Creates a new command line by replaceing options starting with '@'
+// character. '@<filename>' is replaced by the file's contents.
+ErrorOr<std::vector<const char *>>
+ArgParser::replaceResponseFiles(std::vector<const char *> Argv) {
+  std::vector<const char *> V;
+  for (const char *S : Argv) {
+    if (S[0] != '@') {
+      V.push_back(S);
+      continue;
+    }
+    StringRef Path = S + 1;
+    auto BufOrErr = MemoryBuffer::getFile(Path);
+    if (auto EC = BufOrErr.getError())
+      return EC;
+    std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
+    StringRef Str = Alloc.save(Buf->getBuffer());
+    std::vector<const char *> Tokens = tokenize(Str);
+    V.insert(V.end(), Tokens.begin(), Tokens.end());
+  }
+  return V;
+}
+
 void printHelp(const char *Argv0) {
   COFFOptTable Table;
   Table.PrintHelp(llvm::outs(), Argv0, "LLVM Linker", false);

Added: lld/trunk/test/COFF/responsefile.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/responsefile.test?rev=239242&view=auto
==============================================================================
--- lld/trunk/test/COFF/responsefile.test (added)
+++ lld/trunk/test/COFF/responsefile.test Sat Jun  6 21:55:19 2015
@@ -0,0 +1,7 @@
+# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
+
+# RUN: echo /out:%t.exe %t.obj > %t.rsp
+# RUN: lld -flavor link2 @%t.rsp /heap:0x3000
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
+
+CHECK: SizeOfHeapReserve: 12288





More information about the llvm-commits mailing list