llvm-project/lld/lib/Driver/WinLinkInputGraph.cpp
Rui Ueyama 961f43fb70 Make File always take the ownership of a MemoryBuffer.
The documentation of parseFile() said that "the resulting File
object may take ownership of the MemoryBuffer." So, whether or not
the ownership of a MemoryBuffer would be taken was not clear.
A FileNode (a subclass of InputElement, which is being deprecated)
keeps the ownership if a File doesn't take it.

This patch makes File always take the ownership of a buffer.
Buffers lifespan is not always the same as File instances.
Files are able to deallocate buffers after parsing the contents.

llvm-svn: 224113
2014-12-12 10:27:33 +00:00

64 lines
2.0 KiB
C++

//===- lib/Driver/WinLinkInputGraph.cpp -----------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lld/Driver/WinLinkInputGraph.h"
namespace lld {
bool isCOFFLibraryFileExtension(StringRef path) {
return path.endswith_lower(".lib") || path.endswith_lower(".imp");
}
/// \brief Parse the input file to lld::File.
std::error_code PECOFFFileNode::parse(const LinkingContext &ctx,
raw_ostream &diagnostics) {
if (_parsed)
return std::error_code();
_parsed = true;
ErrorOr<StringRef> filePath = getPath(ctx);
if (std::error_code ec = filePath.getError()) {
diagnostics << "File not found: " << _path << "\n";
return ec;
}
ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
MemoryBuffer::getFileOrSTDIN(*filePath);
if (std::error_code ec = mb.getError()) {
diagnostics << "Cannot open file: " << *filePath << "\n";
return ec;
}
if (ctx.logInputFiles())
diagnostics << *filePath << "\n";
return ctx.registry().parseFile(std::move(mb.get()), _files);
}
ErrorOr<File &> PECOFFFileNode::getNextFile() {
if (_nextFileIndex == _files.size())
return make_error_code(InputGraphError::no_more_files);
return *_files[_nextFileIndex++];
}
ErrorOr<StringRef> PECOFFFileNode::getPath(const LinkingContext &) const {
if (isCOFFLibraryFileExtension(_path))
return _ctx.searchLibraryFile(_path);
if (llvm::sys::path::extension(_path).empty())
return _ctx.allocate(_path.str() + ".obj");
return _path;
}
ErrorOr<StringRef> PECOFFLibraryNode::getPath(const LinkingContext &) const {
if (isCOFFLibraryFileExtension(_path))
return _ctx.searchLibraryFile(_path);
return _ctx.searchLibraryFile(_ctx.allocate(_path.str() + ".lib"));
}
} // end anonymous namespace