[llvm] e865fa7 - [TableGen] Add a library-based entry point for parsing td files

River Riddle via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 3 16:14:25 PST 2022


Author: River Riddle
Date: 2022-03-03T16:14:03-08:00
New Revision: e865fa75308aa8dc103ed2ac559e678b5531fa30

URL: https://github.com/llvm/llvm-project/commit/e865fa75308aa8dc103ed2ac559e678b5531fa30
DIFF: https://github.com/llvm/llvm-project/commit/e865fa75308aa8dc103ed2ac559e678b5531fa30.diff

LOG: [TableGen] Add a library-based entry point for parsing td files

This commit adds a new `TableGenParseFile` entry point for tablegen
that parses an input buffer and invokes a callback function with
a record keeper (notably without an output buffer). This kind of entry
point is very useful for tablegen consuming tools that don't create
output, and want invoke tablegen multiple times. The current way
that we interact with tablegen is via relative includes to
TGParser(not great).

Differential Revision: https://reviews.llvm.org/D119899

Added: 
    llvm/include/llvm/TableGen/Parser.h
    llvm/lib/TableGen/Parser.cpp
    llvm/lib/TableGen/RecordContext.h
    llvm/unittests/TableGen/ParserEntryPointTest.cpp

Modified: 
    llvm/lib/TableGen/CMakeLists.txt
    llvm/lib/TableGen/Record.cpp
    llvm/unittests/TableGen/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/TableGen/Parser.h b/llvm/include/llvm/TableGen/Parser.h
new file mode 100644
index 0000000000000..88b37a7cf47a3
--- /dev/null
+++ b/llvm/include/llvm/TableGen/Parser.h
@@ -0,0 +1,39 @@
+//===- llvm/TableGen/Parser.h - tblgen parser entry point -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares an entry point into the tablegen parser for use by tools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TABLEGEN_PARSER_H
+#define LLVM_TABLEGEN_PARSER_H
+
+#include "llvm/ADT/STLExtras.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+class MemoryBuffer;
+class RecordKeeper;
+
+/// Peform the tablegen action using the given set of parsed records. Returns
+/// true on error, false otherwise.
+using TableGenParserFn = function_ref<bool(RecordKeeper &)>;
+
+/// Parse the given input buffer containing a tablegen file, invoking the
+/// provided parser function with the set of parsed records. All tablegen state
+/// is reset after the provided parser function is invoked, i.e., the provided
+/// parser function should not maintain references to any tablegen constructs
+/// after executing. Returns true on failure, false otherwise.
+bool TableGenParseFile(std::unique_ptr<MemoryBuffer> Buffer,
+                       std::vector<std::string> IncludeDirs,
+                       TableGenParserFn ParserFn);
+
+} // end namespace llvm
+
+#endif // LLVM_TABLEGEN_PARSER_H

diff  --git a/llvm/lib/TableGen/CMakeLists.txt b/llvm/lib/TableGen/CMakeLists.txt
index a73e6aec0165a..c550840f147d7 100644
--- a/llvm/lib/TableGen/CMakeLists.txt
+++ b/llvm/lib/TableGen/CMakeLists.txt
@@ -3,6 +3,7 @@ add_llvm_component_library(LLVMTableGen
   Error.cpp
   JSONBackend.cpp
   Main.cpp
+  Parser.cpp
   Record.cpp
   SetTheory.cpp
   StringMatcher.cpp

diff  --git a/llvm/lib/TableGen/Parser.cpp b/llvm/lib/TableGen/Parser.cpp
new file mode 100644
index 0000000000000..47882c8524ab5
--- /dev/null
+++ b/llvm/lib/TableGen/Parser.cpp
@@ -0,0 +1,38 @@
+//===- Parser.cpp - Top-Level TableGen Parser implementation --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/TableGen/Parser.h"
+#include "RecordContext.h"
+#include "TGParser.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+
+using namespace llvm;
+
+bool llvm::TableGenParseFile(std::unique_ptr<MemoryBuffer> Buffer,
+                             std::vector<std::string> IncludeDirs,
+                             TableGenParserFn ParserFn) {
+  RecordKeeper Records;
+  Records.saveInputFilename(Buffer->getBufferIdentifier().str());
+
+  SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
+  SrcMgr.setIncludeDirs(IncludeDirs);
+  TGParser Parser(SrcMgr, /*Macros=*/None, Records);
+  if (Parser.ParseFile())
+    return true;
+
+  // Invoke the provided handler function.
+  if (ParserFn(Records))
+    return true;
+
+  // After parsing, reset the tablegen data.
+  detail::resetTablegenRecordContext();
+  SrcMgr = SourceMgr();
+  return false;
+}

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 58d8c99368964..05ca946390c54 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/TableGen/Record.h"
+#include "RecordContext.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -93,6 +94,8 @@ struct RecordContext {
 
 ManagedStatic<detail::RecordContext> Context;
 
+void llvm::detail::resetTablegenRecordContext() { Context.destroy(); }
+
 //===----------------------------------------------------------------------===//
 //    Type implementations
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/TableGen/RecordContext.h b/llvm/lib/TableGen/RecordContext.h
new file mode 100644
index 0000000000000..fa687f6fc8d5b
--- /dev/null
+++ b/llvm/lib/TableGen/RecordContext.h
@@ -0,0 +1,27 @@
+//===- RecordContext.h - RecordContext implementation ---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions for interacting with the tablegen record
+// context.
+//
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+namespace detail {
+
+/// Resets the Tablegen record context and all currently parsed record data.
+/// Tablegen currently relies on a lot of static data to keep track of parsed
+/// records, which accumulates into static fields. This method resets all of
+/// that data to enable successive executions of the tablegen parser.
+/// FIXME: Ideally tablegen would use a properly scoped (non-static) context,
+/// which would remove any need for managing the context in this way. In that
+/// case, this method could be removed.
+void resetTablegenRecordContext();
+
+} // end namespace detail
+} // end namespace llvm

diff  --git a/llvm/unittests/TableGen/CMakeLists.txt b/llvm/unittests/TableGen/CMakeLists.txt
index 15f60800aa9c5..e0c7c682df53c 100644
--- a/llvm/unittests/TableGen/CMakeLists.txt
+++ b/llvm/unittests/TableGen/CMakeLists.txt
@@ -10,8 +10,9 @@ tablegen(LLVM AutomataAutomata.inc -gen-automata)
 add_public_tablegen_target(AutomataTestTableGen)
 
 add_llvm_unittest(TableGenTests DISABLE_LLVM_LINK_LLVM_DYLIB
-  CodeExpanderTest.cpp
   AutomataTest.cpp
+  CodeExpanderTest.cpp
+  ParserEntryPointTest.cpp
   )
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../utils/TableGen)
 target_link_libraries(TableGenTests PRIVATE LLVMTableGenGlobalISel LLVMTableGen)

diff  --git a/llvm/unittests/TableGen/ParserEntryPointTest.cpp b/llvm/unittests/TableGen/ParserEntryPointTest.cpp
new file mode 100644
index 0000000000000..f064c447c27e5
--- /dev/null
+++ b/llvm/unittests/TableGen/ParserEntryPointTest.cpp
@@ -0,0 +1,39 @@
+//===- unittest/TableGen/ParserEntryPointTest.cpp - Parser tests ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/TableGen/Parser.h"
+#include "llvm/TableGen/Record.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(Parser, SanityTest) {
+  // Simple TableGen source file with a single record.
+  const char *SimpleTdSource = R"td(
+    def Foo {
+      string strField = "value";
+    }
+  )td";
+
+  auto ProcessFn = [&](const RecordKeeper &Records) {
+    Record *Foo = Records.getDef("Foo");
+    Optional<StringRef> Field = Foo->getValueAsOptionalString("strField");
+    EXPECT_TRUE(Field.hasValue());
+    EXPECT_EQ(Field.getValue(), "value");
+    return false;
+  };
+
+  bool ProcessResult = TableGenParseFile(
+      MemoryBuffer::getMemBuffer(SimpleTdSource, "test_buffer"),
+      /*IncludeDirs=*/{}, ProcessFn);
+  EXPECT_FALSE(ProcessResult);
+}


        


More information about the llvm-commits mailing list