forked from OSchip/llvm-project
parent
605f7791a3
commit
415625028c
|
@ -35,6 +35,7 @@ enum class Kind {
|
|||
kw_heapsize,
|
||||
kw_name,
|
||||
kw_noname,
|
||||
kw_version,
|
||||
};
|
||||
|
||||
class Token {
|
||||
|
@ -62,7 +63,7 @@ private:
|
|||
|
||||
class Directive {
|
||||
public:
|
||||
enum class Kind { exports, heapsize, name };
|
||||
enum class Kind { exports, heapsize, name, version };
|
||||
|
||||
Kind getKind() const { return _kind; }
|
||||
virtual ~Directive() {}
|
||||
|
@ -125,6 +126,23 @@ private:
|
|||
const uint64_t _baseaddr;
|
||||
};
|
||||
|
||||
class Version : public Directive {
|
||||
public:
|
||||
explicit Version(int major, int minor)
|
||||
: Directive(Kind::version), _major(major), _minor(minor) {}
|
||||
|
||||
static bool classof(const Directive *dir) {
|
||||
return dir->getKind() == Kind::version;
|
||||
}
|
||||
|
||||
int getMajorVersion() const { return _major; }
|
||||
int getMinorVersion() const { return _minor; }
|
||||
|
||||
private:
|
||||
const int _major;
|
||||
const int _minor;
|
||||
};
|
||||
|
||||
class Parser {
|
||||
public:
|
||||
explicit Parser(Lexer &lex, llvm::BumpPtrAllocator &alloc)
|
||||
|
@ -143,6 +161,7 @@ private:
|
|||
bool parseExport(PECOFFLinkingContext::ExportDesc &result);
|
||||
bool parseHeapsize(uint64_t &reserve, uint64_t &commit);
|
||||
bool parseName(std::string &outfile, uint64_t &baseaddr);
|
||||
bool parseVersion(int &major, int &minor);
|
||||
|
||||
Lexer &_lex;
|
||||
llvm::BumpPtrAllocator &_alloc;
|
||||
|
|
|
@ -948,6 +948,9 @@ WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ctx,
|
|||
ctx.setOutputPath(ctx.allocate(name->getOutputPath()));
|
||||
if (name->getBaseAddress() && ctx.getBaseAddress())
|
||||
ctx.setBaseAddress(name->getBaseAddress());
|
||||
} else if (auto *ver = dyn_cast<moduledef::Version>(dir.getValue())) {
|
||||
ctx.setImageVersion(PECOFFLinkingContext::Version(
|
||||
ver->getMajorVersion(), ver->getMinorVersion()));
|
||||
} else {
|
||||
llvm::dbgs() << static_cast<int>(dir.getValue()->getKind()) << "\n";
|
||||
llvm_unreachable("Unknown module-definition directive.\n");
|
||||
|
|
|
@ -54,6 +54,7 @@ Token Lexer::lex() {
|
|||
.Case("HEAPSIZE", Kind::kw_heapsize)
|
||||
.Case("NAME", Kind::kw_name)
|
||||
.Case("NONAME", Kind::kw_noname)
|
||||
.Case("VERSION", Kind::kw_version)
|
||||
.Default(Kind::identifier);
|
||||
_buffer = (end == _buffer.npos) ? "" : _buffer.drop_front(end);
|
||||
return Token(kind, word);
|
||||
|
@ -129,6 +130,13 @@ llvm::Optional<Directive *> Parser::parse() {
|
|||
return llvm::None;
|
||||
return new (_alloc) Name(outputPath, baseaddr);
|
||||
}
|
||||
// VERSION
|
||||
if (_tok._kind == Kind::kw_version) {
|
||||
int major, minor;
|
||||
if (!parseVersion(major, minor))
|
||||
return llvm::None;
|
||||
return new (_alloc) Version(major, minor);
|
||||
}
|
||||
error(_tok, Twine("Unknown directive: ") + _tok._range);
|
||||
return llvm::None;
|
||||
}
|
||||
|
@ -199,5 +207,22 @@ bool Parser::parseName(std::string &outputPath, uint64_t &baseaddr) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// VERSION major[.minor]
|
||||
bool Parser::parseVersion(int &major, int &minor) {
|
||||
consumeToken();
|
||||
if (_tok._kind != Kind::identifier)
|
||||
return false;
|
||||
StringRef v1, v2;
|
||||
llvm::tie(v1, v2) = _tok._range.split('.');
|
||||
if (v1.getAsInteger(10, major))
|
||||
return false;
|
||||
if (v2.empty()) {
|
||||
minor = 0;
|
||||
} else if (v2.getAsInteger(10, minor)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // moddef
|
||||
} // namespace lld
|
||||
|
|
|
@ -107,3 +107,23 @@ TEST_F(ParserTest, Name2) {
|
|||
EXPECT_EQ("foo.exe", name->getOutputPath());
|
||||
EXPECT_EQ(4096U, name->getBaseAddress());
|
||||
}
|
||||
|
||||
TEST_F(ParserTest, Version1) {
|
||||
llvm::BumpPtrAllocator alloc;
|
||||
llvm::Optional<moduledef::Directive *> dir = parse("VERSION 12", alloc);
|
||||
EXPECT_TRUE(dir.hasValue());
|
||||
auto *ver = dyn_cast<moduledef::Version>(dir.getValue());
|
||||
EXPECT_TRUE(ver != nullptr);
|
||||
EXPECT_EQ(12, ver->getMajorVersion());
|
||||
EXPECT_EQ(0, ver->getMinorVersion());
|
||||
}
|
||||
|
||||
TEST_F(ParserTest, Version2) {
|
||||
llvm::BumpPtrAllocator alloc;
|
||||
llvm::Optional<moduledef::Directive *> dir = parse("VERSION 12.34", alloc);
|
||||
EXPECT_TRUE(dir.hasValue());
|
||||
auto *ver = dyn_cast<moduledef::Version>(dir.getValue());
|
||||
EXPECT_TRUE(ver != nullptr);
|
||||
EXPECT_EQ(12, ver->getMajorVersion());
|
||||
EXPECT_EQ(34, ver->getMinorVersion());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue