Home / Alt manpages / tblgen-20(1)

  • tblgen-20(1)
  • User command
  • linux

Use llvm-tblgen-20 to Test TableGen Files and Capture Output

llvm-tblgen-20 is the tool that turns a declarative TableGen source file into the records LLVM, Clang, LLDB and MLIR actually build from. This parses a small TableGen file, inspects the records it creates, and saves the result without accidentally clobbering useful output. The examples use llvm-tblgen-20 from Ubuntu's llvm-20 package, version 1:20.1.8~++20250804090239+87f0227cb601-1~exp1~20250804210352.139.

Allow about fifteen minutes if the input file is ready. It reads declarative .td files and passes the resulting records to a selected backend. It is not a general C++ compiler, and most Linux users do not need it unless they are building or extending one of those four projects.

1. Check the installed tool

Run these ordinary, read-only checks first. They do not need sudo:

$ command -v llvm-tblgen-20
/usr/bin/llvm-tblgen-20
$ llvm-tblgen-20 --version
Ubuntu LLVM version 20.1.8
  Optimized build.
$ dpkg-query -W -f='${Package} ${Version}\n' llvm-20
llvm-20 1:20.1.8~++20250804090239+87f0227cb601-1~exp1~20250804210352.139

The installed manpage describes a family of commands and uses *-tblgen as shorthand. On this machine the executable to invoke is llvm-tblgen-20. Options are version-sensitive, so when a build requires a different LLVM release, check that release's help rather than copying a backend name blindly.

Checkpoint

Confirm the available actions with llvm-tblgen-20 -help. The list includes -print-records, -dump-json, -null-backend and several code-generation backends. The default backend is record printing, but a real LLVM build normally supplies a backend explicitly.

2. Create a minimal input file

Use a separate working directory for experiments. This harmless example defines a class with one string field and creates one record:

class Greeting<string Text> {
  string text = Text;
}

def Hello: Greeting<"hello from TableGen">;

Save it as /tmp/tablegen-example.td or as a file inside your source tree. The angle brackets are part of TableGen syntax; they are escaped above because this article is HTML. Do not edit a generated file in place while trying to repair the source. Keep the .td file as the source of truth.

3. Parse and inspect the records

Run the file with no backend-specific option:

$ llvm-tblgen-20 /tmp/tablegen-example.td
------------- Classes -----------------
class Greeting<string Greeting:Text = ?> {
  string text = Greeting:Text;
}
------------- Defs -----------------
def Hello {
  string text = "hello from TableGen";
}

Exact comments can vary, but the useful checkpoints are a class named Greeting, a definition named Hello, and the resolved text value. A zero exit status means the input was accepted and the selected action completed. It does not mean that a target-specific backend generated the file you ultimately need.

When you want to see the status separately, capture it immediately:

$ llvm-tblgen-20 /tmp/tablegen-example.td >/tmp/tablegen-records.txt
$ status=$?
$ printf 'tblgen status: %s\n' "$status"
tblgen status: 0

4. Write output to a chosen file

Use -o when another tool expects a named output. A filename writes there; - means standard output:

$ llvm-tblgen-20 -o /tmp/tablegen-records.txt /tmp/tablegen-example.td
$ file /tmp/tablegen-records.txt
/tmp/tablegen-records.txt: ASCII text
$ sed -n '1,10p' /tmp/tablegen-records.txt
------------- Classes -----------------
class Greeting<string Greeting:Text = ?> {
  string text = Greeting:Text;
}

The shell's > operator truncates an existing destination before the program starts. For an important generated file, write a temporary sibling and replace the old file only after success:

$ llvm-tblgen-20 -o /tmp/tablegen-records.txt.new /tmp/tablegen-example.td
$ test "$?" -eq 0 && mv /tmp/tablegen-records.txt.new /tmp/tablegen-records.txt
$ test -s /tmp/tablegen-records.txt && echo 'output is non-empty'
output is non-empty

Safety boundary

mv replaces the destination name. Use a new filename if the old output is still needed, or copy it first. If the generation fails, leave the old file alone and inspect the diagnostic. Removing a backup is irreversible and is not part of this workflow.

5. Use JSON for machine-readable inspection

The installed tool's -dump-json action emits a JSON representation of the records. Capture it and parse it with a JSON tool rather than grepping a pretty-printed report:

$ llvm-tblgen-20 -dump-json /tmp/tablegen-example.td > /tmp/tablegen-records.json
$ jq -r '.Hello.text' /tmp/tablegen-records.json
hello from TableGen
$ jq -r '.["!tablegen_json_version"]' /tmp/tablegen-records.json
1

The JSON includes metadata keys beginning with !, including the format version and record locations. Treat that format as an interface of this LLVM release, not as a promise that unrelated LLVM versions will emit identical fields.

6. Separate parsing from backend work

Use -null-backend when you want to measure or validate the front end without running a generator:

$ llvm-tblgen-20 -null-backend /tmp/tablegen-example.td
$ printf 'status: %s\n' "$?"
status: 0

This normally produces no generated output. It confirms that the source can be parsed and records can be built. For actual LLVM work, choose the backend named by the project's build instructions, such as -gen-asm-matcher or -gen-instr-info. The correct backend also depends on the input files and target; do not substitute one merely because it appears in help.

If an input includes another .td file, add its directory with -I:

$ llvm-tblgen-20 -I /path/to/llvm/include -dump-json /path/to/source.td > /tmp/records.json

Use an include directory that belongs to the same LLVM source checkout as the input. Mixing headers from another release is a common source of missing definitions and confusing parse errors. -D=NAME defines a macro name without a value when the source deliberately tests for that macro.

7. Diagnose the common failures

A missing input is an ordinary path problem:

$ test -r /path/to/source.td && echo readable
$ llvm-tblgen-20 /path/to/source.td
error: Could not open input file: /path/to/source.td

Check the path and permissions before reaching for elevated privileges. sudo should not be needed for a source tree you own; using it can create root-owned generated files that later builds cannot replace.

A syntax or semantic error is different from a backend error. First rerun with the smallest input that reproduces it, then check the matching release's .td includes and backend. Avoid adding flags until you know which stage failed. For verbose investigation, -debug, -stats and -time-phases are available in the installed manpage, but their output is diagnostic rather than a stable data format.

Done means

  • Version confirmed: llvm-tblgen-20 --version identifies the expected LLVM 20.1.8 installation.
  • Parse succeeded: your .td file parses with a zero exit status.
  • Right action chosen: you selected a backend or inspection action that matches the job.
  • Output protected: important output is written to a deliberate path and checked before replacement.
  • JSON treated as JSON: its LLVM version is recorded for anything automated that consumes it.
  • Nothing else touched: no source, service, system package or privileged file was changed by the test.