Files
clang-p2996/lld/lib/Driver/GnuLdInputGraph.cpp
Rui Ueyama 5a25fd5962 [ELF] Remove {ELF,}GNULinkerScript.
Instead of representing a linker script file as an "InputElement",
parse and evaluate scripts in the driver as we see them.

Linker scripts are not regular input files (regular file is one of
object, archive, or shared library file). They are more like
extended command line options. Linker script handling was needlessly
complicated because of that inappropriate abstraction (besides
excessive class hierarchy -- there is no such thing like ELF linker
script but we had two classes there for some reason.)

LinkerScript was one of a few remaining InputElement subclasses
that can be expanded to multiple files. With this patch, we are one
step closer to retire InputElement.

http://reviews.llvm.org/D6648

llvm-svn: 225330
2015-01-07 01:13:08 +00:00

66 lines
2.3 KiB
C++

//===- lib/Driver/GnuLdInputGraph.cpp -------------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lld/Driver/GnuLdInputGraph.h"
#include "lld/ReaderWriter/LinkerScript.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
using namespace lld;
llvm::ErrorOr<StringRef> ELFFileNode::getPath(const LinkingContext &) const {
if (_attributes._isDashlPrefix)
return _elfLinkingContext.searchLibrary(_path);
return _elfLinkingContext.searchFile(_path, _attributes._isSysRooted);
}
std::string ELFFileNode::errStr(std::error_code errc) {
if (errc == llvm::errc::no_such_file_or_directory) {
if (_attributes._isDashlPrefix)
return (Twine("Unable to find library -l") + _path).str();
return (Twine("Unable to find file ") + _path).str();
}
return FileNode::errStr(errc);
}
/// \brief Parse the input file to lld::File.
std::error_code ELFFileNode::parse(const LinkingContext &ctx,
raw_ostream &diagnostics) {
ErrorOr<StringRef> filePath = getPath(ctx);
if (std::error_code ec = filePath.getError())
return ec;
ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
MemoryBuffer::getFileOrSTDIN(*filePath);
if (std::error_code ec = mb.getError())
return ec;
if (ctx.logInputFiles())
diagnostics << *filePath << "\n";
if (_attributes._isWholeArchive) {
std::vector<std::unique_ptr<File>> parsedFiles;
if (std::error_code ec = ctx.registry().parseFile(
std::move(mb.get()), parsedFiles))
return ec;
assert(parsedFiles.size() == 1);
std::unique_ptr<File> f(parsedFiles[0].release());
if (const auto *archive = dyn_cast<ArchiveLibraryFile>(f.get())) {
// Have this node own the FileArchive object.
_archiveFile.reset(archive);
f.release();
// Add all members to _files vector
return archive->parseAllMembers(_files);
}
// if --whole-archive is around non-archive, just use it as normal.
_files.push_back(std::move(f));
return std::error_code();
}
return ctx.registry().parseFile(std::move(mb.get()), _files);
}