[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