Use clang-tblgen-20 to Inspect Clang TableGen Inputs
Feed clang-tblgen-20 a tiny .td file and you can see exactly which records Clang's TableGen sees, before a real build gets involved. This guide gives you a repeatable way to inspect those records and request machine-readable JSON, using Ubuntu LLVM 20.1.8 from the installed llvm-20 package.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes.
- You need a shell, the
clang-tblgen-20executable, and a text editor or a way to create a temporary file. - What it touches: the examples only read a temporary input and write output under
/tmp. They do not install anything, alter Clang, or write to a source tree.
1. Confirm the installed tool
Start with read-only checks. They need no elevated privileges:
$ command -v clang-tblgen-20
/usr/bin/clang-tblgen-20
$ clang-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-1~exp1
The package revision can differ on another machine. What matters is the split between the program's LLVM version and the distribution's package revision. If command -v finds nothing, stop here and install or enable the package through your normal system management. Do not work around a missing executable by guessing a path.
Checkpoint
You should have a working clang-tblgen-20 and know which version will run your input.
2. Create a minimal TableGen input
clang-tblgen-20 translates compiler-related TableGen description files. Its input is normally a filename ending in .td, given as a positional argument. Create a harmless scratch file:
$ workdir=$(mktemp -d /tmp/clang-tblgen-20.XXXXXX)
$ printf '%s\n' 'class Demo { int Value = 1; }' > "$workdir/demo.td"
$ sed -n '1p' "$workdir/demo.td"
class Demo { int Value = 1; }
This declares a class named Demo with one integer field. It does not define an instance, so the default record listing will show a class but no defs.
Tip
A real Clang source checkout may include other .td files and use include directories. Keep this first test self-contained, so a missing include cannot be mistaken for a problem in the executable.
The temporary directory is not a persistent configuration change. Leave it in place for the later examples. To keep the input, copy it somewhere deliberate after reviewing it. Otherwise remove this directory and its files in step 7.
3. Print the records
Run the input without an action option. The installed program defaults to --print-records:
$ clang-tblgen-20 "$workdir/demo.td"
------------- Classes -----------------
class Demo {
int Value = 1;
}
------------- Defs -----------------
The headings separate classes from defs. An empty defs section is expected here because the sample declares a class only. A real input can produce many records, and the exact ordering and formatting are output details, not a stable API for scripts.
You can make the default explicit when reading a longer command:
$ clang-tblgen-20 --print-records "$workdir/demo.td" > "$workdir/records.txt"
$ sed -n '1,12p' "$workdir/records.txt"
Tip
Use ordinary shell redirection to save stdout. Do not expect -o to be implied by redirection: -o is a TableGen option for selecting an output file, and some output actions require it.
4. Emit JSON for inspection or tooling
Select --dump-json when another program needs a machine-readable representation:
$ clang-tblgen-20 --dump-json "$workdir/demo.td" > "$workdir/demo.json"
$ sed -n '1p' "$workdir/demo.json"
{"!instanceof":{"Demo":[]},"!tablegen_json_version":1}
The JSON carries a TableGen JSON version marker and an !instanceof index. The record set depends on the input. Treat the output as data from this LLVM tool version, not a promise that every future release will format or order fields identically.
Check the file is valid JSON with a tool already on your system:
$ python3 -m json.tool "$workdir/demo.json" > /dev/null
$ printf 'JSON check: %s\n' "$?"
JSON check: 0
If Python is not available, check the command's exit status instead. A non-zero status from clang-tblgen-20 means its output is not a successful result, even if a partial file was created.
5. Add include paths only when needed
The -I option adds a directory searched for included TableGen files. Keep the input and include directory separate, and quote paths that may contain spaces:
$ clang-tblgen-20 -I "$workdir/includes" "$workdir/demo.td"
That command fails if the directory or an included file is absent, which is useful: it tells you the dependency is not available. Do not create arbitrary include files just to silence an error, because the definitions they provide change the generated output.
-D defines a macro name for the TableGen preprocessor, while -I supplies an include directory. Both affect how an input is interpreted, so record the exact values in your build command if you need reproducible output.
6. Diagnose the two common command errors
A missing input is a file or path problem. Reproduce it without privileges:
$ clang-tblgen-20 "$workdir/missing.td"
clang-tblgen-20: Could not open input file '.../missing.td': No such file or directory
$ printf 'exit status: %s\n' "$?"
exit status: 1
The temporary-directory part of the diagnostic varies. Check pwd, the filename, and the result of ls -l "$workdir". sudo will not fix a misspelt path.
Some actions need an explicit output file. For example, the dependency option -d must be used together with -o:
$ clang-tblgen-20 -d "$workdir/demo.d" "$workdir/demo.td"
clang-tblgen-20: the option -d must be used together with -o
$ printf 'exit status: %s\n' "$?"
exit status: 1
This is an option-contract error, not a permissions problem, so do not reach for elevated privileges. Before using a generator option in a build, check its help text and give it the output path it requires.
Warning
A generator action can overwrite an existing output file. Review the output path before running one against a source tree.
7. Clean up and verify the result
When the inspection is done, check what the scratch directory holds:
$ find "$workdir" -maxdepth 1 -type f -printf '%f\n' | sort
demo.json
demo.td
records.txt
Remove only the directory you created, if you no longer need those files:
$ rm -rf -- "$workdir"
$ test ! -e "$workdir" && echo 'scratch directory removed'
scratch directory removed
Warning
There is no undo for a generated file you deliberately remove, so save any output you need before this step. Nothing in this guide changes a service, compiler installation, build configuration or system-wide state.
Done means
- Tool confirmed. You checked the installed LLVM 20.1.8 executable and package.
- Self-contained input. You supplied a
.tdfile as the positional input. - Records understood. You inspected the default record output and know why the defs section was empty.
- JSON works. You emitted JSON with
--dump-jsonand checked its exit status. - Options known.
-Iadds include directories and-drequires-o, and you can tell a missing file from an option-contract error withoutsudo. - Scratch handled. You removed or deliberately kept the scratch files, knowing what will be lost.