summaryrefslogtreecommitdiffstats
path: root/lld/lib/Driver/WinLinkInputGraph.cpp
blob: eebebf4a9d6b0a7441a7231f9c27d10777086c7b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//===- 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"

using llvm::sys::fs::file_magic;
using llvm::sys::fs::identify_magic;

namespace lld {

/// \brief Parse the input file to lld::File.
error_code PECOFFFileNode::parse(const LinkingContext &ctx,
                                 raw_ostream &diagnostics) {
  ErrorOr<StringRef> filePath = getPath(ctx);
  if (!filePath) {
    diagnostics << "File not found: " << _path << "\n";
    return error_code(filePath);
  }

  if (error_code ec = getBuffer(*filePath)) {
    diagnostics << "Cannot open file: " << *filePath << "\n";
    return ec;
  }

  if (ctx.logInputFiles())
    diagnostics << *filePath << "\n";

  if (filePath->endswith(".objtxt"))
    return ctx.getYAMLReader().parseFile(_buffer, _files);
  if (identify_magic(_buffer->getBuffer()) == file_magic::archive) {
    // Archive File
    error_code ec;
    _files.push_back(std::unique_ptr<File>(
                       new FileArchive(ctx, std::move(_buffer), ec, false)));
    return ec;
  }
  return _ctx.getDefaultReader().parseFile(_buffer, _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 (_path.endswith_lower(".lib"))
    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 (_path.endswith_lower(".lib"))
    return _ctx.searchLibraryFile(_path);
  return _ctx.searchLibraryFile(_ctx.allocate(_path.str() + ".lib"));
}

} // end anonymous namespace
OpenPOWER on IntegriCloud