[lld] r199022 - [PECOFF] Support VERSION directive.
Rui Ueyama
ruiu at google.com
Sat Jan 11 14:45:01 PST 2014
Author: ruiu
Date: Sat Jan 11 16:45:00 2014
New Revision: 199022
URL: http://llvm.org/viewvc/llvm-project?rev=199022&view=rev
Log:
[PECOFF] Support VERSION directive.
Modified:
lld/trunk/include/lld/Driver/WinLinkModuleDef.h
lld/trunk/lib/Driver/WinLinkDriver.cpp
lld/trunk/lib/Driver/WinLinkModuleDef.cpp
lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp
Modified: lld/trunk/include/lld/Driver/WinLinkModuleDef.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/WinLinkModuleDef.h?rev=199022&r1=199021&r2=199022&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/WinLinkModuleDef.h (original)
+++ lld/trunk/include/lld/Driver/WinLinkModuleDef.h Sat Jan 11 16:45:00 2014
@@ -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;
Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=199022&r1=199021&r2=199022&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Sat Jan 11 16:45:00 2014
@@ -948,6 +948,9 @@ WinLinkDriver::parse(int argc, const cha
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");
Modified: lld/trunk/lib/Driver/WinLinkModuleDef.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkModuleDef.cpp?rev=199022&r1=199021&r2=199022&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkModuleDef.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkModuleDef.cpp Sat Jan 11 16:45:00 2014
@@ -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::pars
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;
}
@@ -198,6 +206,23 @@ bool Parser::parseName(std::string &outp
}
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
Modified: lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp?rev=199022&r1=199021&r2=199022&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp Sat Jan 11 16:45:00 2014
@@ -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());
+}
More information about the llvm-commits
mailing list