[llvm] [TableGen] Include source location in JSON dump (PR #79028)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 24 06:49:30 PST 2024
https://github.com/ostannard updated https://github.com/llvm/llvm-project/pull/79028
>From 538c588569a11826eb9571e0b7e56f3f3cb3117a Mon Sep 17 00:00:00 2001
From: Oliver Stannard <oliver.stannard at arm.com>
Date: Mon, 22 Jan 2024 17:13:43 +0000
Subject: [PATCH 1/2] [TableGen] Include source location in JSON dump
This adds a '!loc' field to each record containing the file name and
line number of the record declaration.
---
llvm/lib/TableGen/JSONBackend.cpp | 2 ++
llvm/test/TableGen/JSON.td | 2 ++
2 files changed, 4 insertions(+)
diff --git a/llvm/lib/TableGen/JSONBackend.cpp b/llvm/lib/TableGen/JSONBackend.cpp
index 2a3f522a9c0ef2f..9b489cf7deddbe4 100644
--- a/llvm/lib/TableGen/JSONBackend.cpp
+++ b/llvm/lib/TableGen/JSONBackend.cpp
@@ -15,6 +15,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/JSON.h"
+#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#define DEBUG_TYPE "json-emitter"
@@ -158,6 +159,7 @@ void JSONEmitter::run(raw_ostream &OS) {
obj["!name"] = Name;
obj["!anonymous"] = Def.isAnonymous();
+ obj["!loc"] = SrcMgr.getFormattedLocationNoOffset(Def.getLoc().front());
root[Name] = std::move(obj);
diff --git a/llvm/test/TableGen/JSON.td b/llvm/test/TableGen/JSON.td
index 3fb2ec4014fbcd2..20d3c0fcc131989 100644
--- a/llvm/test/TableGen/JSON.td
+++ b/llvm/test/TableGen/JSON.td
@@ -3,12 +3,14 @@
// CHECK: data['!tablegen_json_version'] == 1
// CHECK: all(data[s]['!name'] == s for s in data if not s.startswith("!"))
+// CHECK: all(data[s]['!loc'].startswith("JSON.td:") for s in data if not s.startswith("!"))
class Base {}
class Intermediate : Base {}
class Derived : Intermediate {}
def D : Intermediate {}
+// CHECK: data['D']['!loc'] == 'JSON.td:12'
// CHECK: 'D' in data['!instanceof']['Base']
// CHECK: 'D' in data['!instanceof']['Intermediate']
// CHECK: 'D' not in data['!instanceof']['Derived']
>From e39b4d7b2c433388242d575283301fbdb31e27cc Mon Sep 17 00:00:00 2001
From: Oliver Stannard <oliver.stannard at arm.com>
Date: Wed, 24 Jan 2024 14:45:04 +0000
Subject: [PATCH 2/2] Emit an array of source locations for multiclasses
---
llvm/docs/TableGen/BackEnds.rst | 6 +++++
llvm/lib/TableGen/JSONBackend.cpp | 6 ++++-
llvm/test/TableGen/JSON-locs.td | 44 +++++++++++++++++++++++++++++++
llvm/test/TableGen/JSON.td | 5 ++--
4 files changed, 58 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/TableGen/JSON-locs.td
diff --git a/llvm/docs/TableGen/BackEnds.rst b/llvm/docs/TableGen/BackEnds.rst
index 5cbb3232ef02387..742fea51bcf32be 100644
--- a/llvm/docs/TableGen/BackEnds.rst
+++ b/llvm/docs/TableGen/BackEnds.rst
@@ -506,6 +506,12 @@ following fixed keys:
specified by the TableGen input (if it is ``false``), or invented by
TableGen itself (if ``true``).
+* ``!locs``: an array of strings giving the source locations associated with
+ this record. For records instantiated from a ``multiclass``, this gives the
+ location of each ``def`` or ``defm``, starting with the inner-most
+ ``multiclass``, and ending with the top-level ``defm``. Each string contains
+ the file name and line number, separated by a colon.
+
For each variable defined in a record, the ``def`` object for that
record also has a key for the variable name. The corresponding value
is a translation into JSON of the variable's value, using the
diff --git a/llvm/lib/TableGen/JSONBackend.cpp b/llvm/lib/TableGen/JSONBackend.cpp
index 9b489cf7deddbe4..cd10c22094e45bf 100644
--- a/llvm/lib/TableGen/JSONBackend.cpp
+++ b/llvm/lib/TableGen/JSONBackend.cpp
@@ -159,7 +159,11 @@ void JSONEmitter::run(raw_ostream &OS) {
obj["!name"] = Name;
obj["!anonymous"] = Def.isAnonymous();
- obj["!loc"] = SrcMgr.getFormattedLocationNoOffset(Def.getLoc().front());
+
+ json::Array locs;
+ for (const SMLoc Loc : Def.getLoc())
+ locs.push_back(SrcMgr.getFormattedLocationNoOffset(Loc));
+ obj["!locs"] = std::move(locs);
root[Name] = std::move(obj);
diff --git a/llvm/test/TableGen/JSON-locs.td b/llvm/test/TableGen/JSON-locs.td
new file mode 100644
index 000000000000000..38baf4693148904
--- /dev/null
+++ b/llvm/test/TableGen/JSON-locs.td
@@ -0,0 +1,44 @@
+// RUN: llvm-tblgen -dump-json %s | %python %S/JSON-check.py %s
+
+def Simple {}
+// CHECK: data['Simple']['!locs'] == ['JSON-locs.td:3']
+
+multiclass Multiclass1 {
+ def Instance1 {}
+ def Instance2 {}
+}
+
+defm DefM1 : Multiclass1;
+
+// CHECK: data['DefM1Instance1']['!locs'] == ['JSON-locs.td:7', 'JSON-locs.td:11']
+// CHECK: data['DefM1Instance2']['!locs'] == ['JSON-locs.td:8', 'JSON-locs.td:11']
+
+multiclass Multiclass2 {
+ def Instance3 {}
+ def Instance4 {}
+}
+
+defm DefM2 : Multiclass1, Multiclass2;
+// CHECK: data['DefM2Instance1']['!locs'] == ['JSON-locs.td:7', 'JSON-locs.td:21']
+// CHECK: data['DefM2Instance2']['!locs'] == ['JSON-locs.td:8', 'JSON-locs.td:21']
+// CHECK: data['DefM2Instance3']['!locs'] == ['JSON-locs.td:17', 'JSON-locs.td:21']
+// CHECK: data['DefM2Instance4']['!locs'] == ['JSON-locs.td:18', 'JSON-locs.td:21']
+
+multiclass Multiclass3 {
+ defm InnerDefM : Multiclass1;
+ def Instance5 {}
+}
+
+defm DefM3: Multiclass3;
+// CHECK: data['DefM3InnerDefMInstance1']['!locs'] == ['JSON-locs.td:7', 'JSON-locs.td:28', 'JSON-locs.td:32']
+// CHECK: data['DefM3InnerDefMInstance2']['!locs'] == ['JSON-locs.td:8', 'JSON-locs.td:28', 'JSON-locs.td:32']
+// CHECK: data['DefM3Instance5']['!locs'] == ['JSON-locs.td:29', 'JSON-locs.td:32']
+
+class BaseClass {}
+class DerivedClass : BaseClass {}
+// Classes do not appear in the JSON, so do not get locations.
+// CHECK: 'BaseClass' not in data
+// CHECK: 'DerivedClass' not in data
+
+def ClassInstance : DerivedClass {}
+// CHECK: data['ClassInstance']['!locs'] == ['JSON-locs.td:43']
diff --git a/llvm/test/TableGen/JSON.td b/llvm/test/TableGen/JSON.td
index 20d3c0fcc131989..4d8c3a466bfd072 100644
--- a/llvm/test/TableGen/JSON.td
+++ b/llvm/test/TableGen/JSON.td
@@ -3,14 +3,15 @@
// CHECK: data['!tablegen_json_version'] == 1
// CHECK: all(data[s]['!name'] == s for s in data if not s.startswith("!"))
-// CHECK: all(data[s]['!loc'].startswith("JSON.td:") for s in data if not s.startswith("!"))
+// CHECK: all('!locs' in data[s] for s in data if not s.startswith("!"))
+// CHECK: all(all(loc.startswith("JSON.td:") for loc in data[s]['!locs']) for s in data if not s.startswith("!"))
class Base {}
class Intermediate : Base {}
class Derived : Intermediate {}
def D : Intermediate {}
-// CHECK: data['D']['!loc'] == 'JSON.td:12'
+// CHECK: data['D']['!locs'] == ['JSON.td:13']
// CHECK: 'D' in data['!instanceof']['Base']
// CHECK: 'D' in data['!instanceof']['Intermediate']
// CHECK: 'D' not in data['!instanceof']['Derived']
More information about the llvm-commits
mailing list