[lld] r198993 - [PECOFF] Refactor module-defintion file parser.
Rui Ueyama
ruiu at google.com
Fri Jan 10 17:33:42 PST 2014
Author: ruiu
Date: Fri Jan 10 19:33:42 2014
New Revision: 198993
URL: http://llvm.org/viewvc/llvm-project?rev=198993&view=rev
Log:
[PECOFF] Refactor module-defintion file parser.
Refactor the parser so that the parser can return arbitrary type of parse
result other than a vector of ExportDesc. Parsers for non-EXPORTS directives
will be implemented in different patches. No functionality change.
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=198993&r1=198992&r2=198993&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/WinLinkModuleDef.h (original)
+++ lld/trunk/include/lld/Driver/WinLinkModuleDef.h Fri Jan 10 19:33:42 2014
@@ -17,6 +17,8 @@
#include "lld/Core/LLVM.h"
#include "lld/ReaderWriter/PECOFFLinkingContext.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Allocator.h"
namespace lld {
namespace moduledef {
@@ -54,10 +56,43 @@ private:
llvm::SourceMgr _sourceManager;
};
+class Directive {
+public:
+ enum class Kind { exports };
+
+ Kind getKind() const { return _kind; }
+ virtual ~Directive() {}
+
+protected:
+ explicit Directive(Kind k) : _kind(k) {}
+
+private:
+ Kind _kind;
+};
+
+class Exports : public Directive {
+public:
+ explicit Exports(const std::vector<PECOFFLinkingContext::ExportDesc> &exports)
+ : Directive(Kind::exports), _exports(exports) {}
+
+ static bool classof(const Directive *dir) {
+ return dir->getKind() == Kind::exports;
+ }
+
+ const std::vector<PECOFFLinkingContext::ExportDesc> &getExports() const {
+ return _exports;
+ }
+
+private:
+ const std::vector<PECOFFLinkingContext::ExportDesc> _exports;
+};
+
class Parser {
public:
- explicit Parser(Lexer &lex) : _lex(lex) {}
- bool parse(std::vector<PECOFFLinkingContext::ExportDesc> &result);
+ explicit Parser(Lexer &lex, llvm::BumpPtrAllocator &alloc)
+ : _lex(lex), _alloc(alloc) {}
+
+ llvm::Optional<Directive *> parse();
private:
void consumeToken();
@@ -67,6 +102,7 @@ private:
bool parseExport(PECOFFLinkingContext::ExportDesc &result);
Lexer &_lex;
+ llvm::BumpPtrAllocator &_alloc;
Token _tok;
std::vector<Token> _tokBuf;
};
Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=198993&r1=198992&r2=198993&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Fri Jan 10 19:33:42 2014
@@ -340,14 +340,14 @@ bool parseExport(StringRef option, PECOF
}
// Read module-definition file.
-bool parseDef(StringRef option,
- std::vector<PECOFFLinkingContext::ExportDesc> &ret) {
+llvm::Optional<moduledef::Directive *> parseDef(StringRef option,
+ llvm::BumpPtrAllocator &alloc) {
OwningPtr<MemoryBuffer> buf;
if (MemoryBuffer::getFile(option, buf))
- return false;
+ return llvm::None;
moduledef::Lexer lexer(std::unique_ptr<MemoryBuffer>(buf.take()));
- moduledef::Parser parser(lexer);
- return parser.parse(ret);
+ moduledef::Parser parser(lexer, alloc);
+ return parser.parse();
}
StringRef replaceExtension(PECOFFLinkingContext &ctx, StringRef path,
@@ -919,14 +919,22 @@ WinLinkDriver::parse(int argc, const cha
}
case OPT_deffile: {
- std::vector<PECOFFLinkingContext::ExportDesc> exports;
- if (!parseDef(inputArg->getValue(), exports)) {
+ llvm::BumpPtrAllocator alloc;
+ llvm::Optional<moduledef::Directive *> dir =
+ parseDef(inputArg->getValue(), alloc);
+ if (!dir.hasValue()) {
diagnostics << "Error: invalid module-definition file\n";
return false;
}
- for (PECOFFLinkingContext::ExportDesc desc : exports) {
- desc.name = ctx.decorateSymbol(desc.name);
- ctx.addDllExport(desc);
+
+ if (auto *exp = dyn_cast<moduledef::Exports>(dir.getValue())) {
+ for (PECOFFLinkingContext::ExportDesc desc : exp->getExports()) {
+ desc.name = ctx.decorateSymbol(desc.name);
+ ctx.addDllExport(desc);
+ }
+ } 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=198993&r1=198992&r2=198993&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkModuleDef.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkModuleDef.cpp Fri Jan 10 19:33:42 2014
@@ -72,18 +72,20 @@ void Parser::error(const Token &tok, Twi
msg);
}
-bool Parser::parse(std::vector<PECOFFLinkingContext::ExportDesc> &result) {
+llvm::Optional<Directive *> Parser::parse() {
consumeToken();
- if (_tok._kind != Kind::kw_exports) {
- error(_tok, "Expected EXPORTS");
- return false;
- }
- for (;;) {
- PECOFFLinkingContext::ExportDesc desc;
- if (!parseExport(desc))
- return true;
- result.push_back(desc);
+ if (_tok._kind == Kind::kw_exports) {
+ std::vector<PECOFFLinkingContext::ExportDesc> exports;
+ for (;;) {
+ PECOFFLinkingContext::ExportDesc desc;
+ if (!parseExport(desc))
+ break;
+ exports.push_back(desc);
+ }
+ return new (_alloc) Exports(exports);
}
+ error(_tok, "Expected EXPORTS");
+ return llvm::None;
}
bool Parser::parseExport(PECOFFLinkingContext::ExportDesc &result) {
Modified: lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp?rev=198993&r1=198992&r2=198993&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkModuleDefTest.cpp Fri Jan 10 19:33:42 2014
@@ -18,25 +18,33 @@ using namespace lld;
class ParserTest : public testing::Test {
protected:
- bool parse(const char *contents,
- std::vector<PECOFFLinkingContext::ExportDesc> &ret) {
+ llvm::Optional<moduledef::Directive *> parse(const char *contents,
+ llvm::BumpPtrAllocator &alloc) {
auto membuf =
std::unique_ptr<MemoryBuffer>(MemoryBuffer::getMemBuffer(contents));
moduledef::Lexer lexer(std::move(membuf));
- moduledef::Parser parser(lexer);
- return parser.parse(ret);
+ moduledef::Parser parser(lexer, alloc);
+ return parser.parse();
}
};
TEST_F(ParserTest, Exports) {
- std::vector<PECOFFLinkingContext::ExportDesc> exports;
- EXPECT_TRUE(parse("EXPORTS\n"
- " sym1\n"
- " sym2 @5\n"
- " sym3 @8 NONAME\n"
- " sym4 DATA\n"
- " sym5 @10 NONAME DATA\n",
- exports));
+ llvm::BumpPtrAllocator alloc;
+ llvm::Optional<moduledef::Directive *> dir = parse("EXPORTS\n"
+ " sym1\n"
+ " sym2 @5\n"
+ " sym3 @8 NONAME\n"
+ " sym4 DATA\n"
+ " sym5 @10 NONAME DATA\n",
+ alloc);
+ EXPECT_TRUE(dir.hasValue());
+ EXPECT_EQ(moduledef::Directive::Kind::exports, dir.getValue()->getKind());
+
+ auto *exportsDir = dyn_cast<moduledef::Exports>(dir.getValue());
+ EXPECT_TRUE(exportsDir != nullptr);
+
+ const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
+ exportsDir->getExports();
EXPECT_EQ(5U, exports.size());
EXPECT_EQ(exports[0].name, "sym1");
EXPECT_EQ(exports[0].ordinal, -1);
More information about the llvm-commits
mailing list