150 lines
4.6 KiB
C++
150 lines
4.6 KiB
C++
//===- lib/Driver/InputGraph.cpp ------------------------------------------===//
|
|
//
|
|
// The LLVM Linker
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "lld/Core/Resolver.h"
|
|
#include "lld/Driver/InputGraph.h"
|
|
|
|
using namespace lld;
|
|
|
|
namespace {
|
|
bool sortInputElements(const std::unique_ptr<InputElement> &a,
|
|
const std::unique_ptr<InputElement> &b) {
|
|
return a->getOrdinal() < b->getOrdinal();
|
|
}
|
|
}
|
|
|
|
bool InputGraph::addInputElement(std::unique_ptr<InputElement> ie) {
|
|
_inputArgs.push_back(std::move(ie));
|
|
return true;
|
|
}
|
|
|
|
bool InputGraph::assignOrdinals() {
|
|
for (auto &ie : _inputArgs)
|
|
ie->setOrdinal(++_ordinal);
|
|
return true;
|
|
}
|
|
|
|
bool InputGraph::assignFileOrdinals(uint64_t &startOrdinal) {
|
|
for (auto &ie : _inputArgs)
|
|
ie->assignFileOrdinals(startOrdinal);
|
|
return true;
|
|
}
|
|
|
|
void InputGraph::doPostProcess() {
|
|
std::stable_sort(_inputArgs.begin(), _inputArgs.end(), sortInputElements);
|
|
}
|
|
|
|
bool InputGraph::validate() {
|
|
for (auto &ie : _inputArgs)
|
|
if (!ie->validate())
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
bool InputGraph::dump(raw_ostream &diagnostics) {
|
|
for (auto &ie : _inputArgs)
|
|
if (!ie->dump(diagnostics))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
void InputGraph::insertElementsAt(
|
|
std::vector<std::unique_ptr<InputElement> > inputElements,
|
|
Position position, int32_t pos) {
|
|
if (position == InputGraph::Position::BEGIN)
|
|
pos = 0;
|
|
else if (position == InputGraph::Position::END)
|
|
pos = _inputArgs.size();
|
|
_inputArgs.insert(_inputArgs.begin() + pos,
|
|
std::make_move_iterator(inputElements.begin()),
|
|
std::make_move_iterator(inputElements.end()));
|
|
}
|
|
|
|
void InputGraph::insertOneElementAt(std::unique_ptr<InputElement> element,
|
|
Position position, int32_t pos) {
|
|
if (position == InputGraph::Position::BEGIN)
|
|
pos = 0;
|
|
else if (position == InputGraph::Position::END)
|
|
pos = _inputArgs.size();
|
|
_inputArgs.insert(_inputArgs.begin() + pos, std::move(element));
|
|
}
|
|
|
|
/// \brief Helper functions for the resolver
|
|
ErrorOr<InputElement *> InputGraph::getNextInputElement() {
|
|
if (_nextElementIndex >= _inputArgs.size())
|
|
return make_error_code(input_graph_error::no_more_elements);
|
|
return _inputArgs[_nextElementIndex++].get();
|
|
}
|
|
|
|
/// \brief Set the index on what inputElement has to be returned
|
|
ErrorOr<void> InputGraph::setNextElementIndex(uint32_t index) {
|
|
if (index > _inputArgs.size())
|
|
return make_error_code(llvm::errc::invalid_argument);
|
|
_nextElementIndex = index;
|
|
return error_code::success();
|
|
}
|
|
|
|
/// InputElement
|
|
|
|
/// \brief Initialize the Input Element, The ordinal value of an input Element
|
|
/// is initially set to -1, if the user wants to override its ordinal,
|
|
/// let the user do it
|
|
InputElement::InputElement(Kind type, int64_t ordinal)
|
|
: _kind(type), _ordinal(ordinal), _weight(0),
|
|
_resolveState(Resolver::StateNoChange), _nextFileIndex(0) {}
|
|
|
|
/// \brief Assign File ordinals for files contained
|
|
/// in the InputElement
|
|
void FileNode::assignFileOrdinals(uint64_t &startOrdinal) {
|
|
for (auto &file : _files)
|
|
file->setOrdinalAndIncrement(startOrdinal);
|
|
}
|
|
|
|
/// \brief Read the file into _buffer.
|
|
error_code
|
|
FileNode::readFile(const LinkingContext &ctx, raw_ostream &diagnostics) {
|
|
ErrorOr<StringRef> filePath = getPath(ctx);
|
|
if (!filePath &&
|
|
error_code(filePath) == llvm::errc::no_such_file_or_directory)
|
|
return make_error_code(llvm::errc::no_such_file_or_directory);
|
|
|
|
// Create a memory buffer
|
|
OwningPtr<llvm::MemoryBuffer> opmb;
|
|
|
|
if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(*filePath, opmb))
|
|
return ec;
|
|
|
|
std::unique_ptr<MemoryBuffer> mb(opmb.take());
|
|
_buffer = std::move(mb);
|
|
|
|
if (ctx.logInputFiles())
|
|
diagnostics << _buffer->getBufferIdentifier() << "\n";
|
|
|
|
// YAML file is identified by a .objtxt extension
|
|
// FIXME : Identify YAML files by using a magic
|
|
if (filePath->endswith(".objtxt"))
|
|
if (error_code ec = ctx.getYAMLReader().parseFile(_buffer, _files))
|
|
return ec;
|
|
return error_code::success();
|
|
}
|
|
|
|
|
|
/// \brief Assign File ordinals for files contained
|
|
/// in the InputElement
|
|
void ControlNode::assignFileOrdinals(uint64_t &startOrdinal) {
|
|
for (auto &elem : _elements)
|
|
elem->assignFileOrdinals(startOrdinal);
|
|
}
|
|
|
|
/// \brief Assign File ordinals for files contained
|
|
/// in the InputElement
|
|
void SimpleFileNode::assignFileOrdinals(uint64_t &startOrdinal) {
|
|
for (auto &file : _files)
|
|
file->setOrdinalAndIncrement(startOrdinal);
|
|
}
|