COFF: Create LinkerDriver class.

Previously the main linker routine is just a non-member function.
We store some context information to the Config object.
This patch makes it belong to Driver.

llvm-svn: 238677
This commit is contained in:
Rui Ueyama 2015-05-31 19:17:09 +00:00
parent 412c4dbbd9
commit a9cbbf885f
5 changed files with 44 additions and 21 deletions

View File

@ -37,13 +37,6 @@ public:
uint32_t MinorImageVersion = 0;
uint32_t MajorOSVersion = 6;
uint32_t MinorOSVersion = 0;
bool insertFile(llvm::StringRef Path) {
return VisitedFiles.insert(Path.lower()).second;
}
private:
std::set<std::string> VisitedFiles;
};
extern Configuration *Config;

View File

@ -35,6 +35,15 @@ namespace lld {
namespace coff {
Configuration *Config;
LinkerDriver *Driver;
bool link(int Argc, const char *Argv[]) {
auto C = make_unique<Configuration>();
Config = C.get();
auto D = make_unique<LinkerDriver>();
Driver = D.get();
return Driver->link(Argc, Argv);
}
static std::string getOutputPath(llvm::opt::InputArgList *Args) {
if (auto *Arg = Args->getLastArg(OPT_out))
@ -68,12 +77,12 @@ public:
// Parses .drectve section contents and returns a list of files
// specified by /defaultlib.
std::error_code parseDirectives(StringRef S,
std::vector<std::unique_ptr<InputFile>> *Res,
StringAllocator *Alloc) {
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);
BumpPtrStringSaver Saver(&Alloc);
llvm::cl::TokenizeWindowsCommandLine(S, Saver, Tokens);
Tokens.push_back(nullptr);
int Argc = Tokens.size() - 1;
@ -86,16 +95,15 @@ std::error_code parseDirectives(StringRef S,
for (auto *Arg : Args->filtered(OPT_defaultlib)) {
std::string Path = findLib(Arg->getValue());
if (!Config->insertFile(Path))
if (!insertFile(Path))
continue;
Res->push_back(llvm::make_unique<ArchiveFile>(Path));
}
return std::error_code();
}
bool link(int Argc, const char *Argv[]) {
bool LinkerDriver::link(int Argc, const char *Argv[]) {
// Parse command line options.
Config = new Configuration();
auto ArgsOrErr = parseArgs(Argc, Argv);
if (auto EC = ArgsOrErr.getError()) {
llvm::errs() << EC.message() << "\n";
@ -180,7 +188,7 @@ bool link(int Argc, const char *Argv[]) {
SymbolTable Symtab;
for (auto *Arg : Args->filtered(OPT_INPUT)) {
std::string Path = findFile(Arg->getValue());
if (!Config->insertFile(Path))
if (!insertFile(Path))
continue;
if (auto EC = Symtab.addFile(createFile(Path))) {
llvm::errs() << Path << ": " << EC.message() << "\n";
@ -229,5 +237,9 @@ bool link(int Argc, const char *Argv[]) {
return true;
}
bool LinkerDriver::insertFile(StringRef Path) {
return VisitedFiles.insert(Path.lower()).second;
}
} // namespace coff
} // namespace lld

View File

@ -16,23 +16,42 @@
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include <memory>
#include <set>
#include <system_error>
#include <vector>
namespace lld {
namespace coff {
class LinkerDriver;
extern LinkerDriver *Driver;
using llvm::COFF::MachineTypes;
using llvm::COFF::WindowsSubsystem;
class InputFile;
// Entry point of the COFF linker.
bool link(int Argc, const char *Argv[]);
class LinkerDriver {
public:
bool link(int Argc, const char *Argv[]);
// Used by the resolver to parse .drectve section contents.
std::error_code
parseDirectives(StringRef S, std::vector<std::unique_ptr<InputFile>> *Res);
private:
// Returns false if a given file has already been read.
bool insertFile(StringRef Path);
std::set<std::string> VisitedFiles;
StringAllocator Alloc;
};
ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>
parseArgs(int Argc, const char *Argv[]);
std::error_code parseDirectives(StringRef S,
std::vector<std::unique_ptr<InputFile>> *Res,
StringAllocator *Alloc);
// Functions below this line are defined in DriverUtils.cpp.
void printHelp(const char *Argv0);

View File

@ -49,7 +49,7 @@ std::error_code SymbolTable::addObject(ObjectFile *File) {
StringRef Dir = File->getDirectives();
if (!Dir.empty()) {
std::vector<std::unique_ptr<InputFile>> Libs;
if (auto EC = parseDirectives(Dir, &Libs, &StringAlloc))
if (auto EC = Driver->parseDirectives(Dir, &Libs))
return EC;
for (std::unique_ptr<InputFile> &Lib : Libs)
addFile(std::move(Lib));

View File

@ -78,7 +78,6 @@ private:
std::vector<std::unique_ptr<ArchiveFile>> ArchiveFiles;
std::vector<std::unique_ptr<SymbolBody>> OwningSymbols;
llvm::BumpPtrAllocator Alloc;
StringAllocator StringAlloc;
};
} // namespace pecoff