[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