Home / Alt manpages / lldb-tblgen-20(1)

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

Run an LLDB TableGen File Safely with LLVM 20

You will finish with a checked TableGen workflow for LLDB-related .td input: identify the installed LLVM 20 tools, parse a small file without leaving an output behind, then write generated data to a deliberate destination. The package installed on this machine provides the lldb-tblgen-20 manual page but not an executable of that name, so the verification uses the installed llvm-tblgen-20 binary and calls out the boundary clearly.

Allow about twenty minutes. You need a shell, the llvm-20 package, a TableGen source tree or a small test file, and permission to read its included files. These commands are ordinary user commands. Nothing here needs sudo, and the examples do not alter an LLVM checkout or a system service.

1. Check the installed version and executable names

Start with the package and binary checks. They are read-only and make the version assumption visible:

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

The installed package owns the lldb-tblgen-20 manpage, but this host has no lldb-tblgen-20 command in PATH. That is a packaging detail worth checking before putting the name in a build script. The manpage describes the common *-tblgen interface; it is not proof that every family member was installed.

Checkpoint

If command -v lldb-tblgen-20 prints a path on your machine, use that executable for the LLDB-specific backend work. If it prints nothing, continue with the available LLVM 20 binary for syntax and record checks, then install or build the LLDB tool through your normal LLVM build process before requesting an LLDB-specific backend.

2. Understand the input and output boundary

TableGen reads a Target Description file, normally ending in .td. It parses declarations into records and a backend turns those records into generated output. The filename is optional: when it is omitted, TableGen can read standard input. The -o option selects an output file, while -o - sends output to standard output.

Do not treat a generic backend as an LLDB backend. The output is determined by the executable and the backend option, not by the filename extension. Start with -null-backend when the question is only whether the source parses and records can be built.

The option spellings in the LLVM 20 manpage include -I for include directories, -D for defining a macro, -d for a dependency file, -o for output, -null-backend, -print-records, -dump-json and -write-if-changed. Ask the installed program for its complete list when working with a particular backend:

$ llvm-tblgen-20 --help | sed -n '1,45p'
USAGE: llvm-tblgen-20 [options] <input file>

OPTIONS:

General options:
  -D <macro name>       Name of the macro to be defined
  -I <directory>        Directory of include files
  -d <filename>         Dependency filename

3. Parse a small source without creating a file

Use standard input for a smoke test. The source below defines one class and one concrete record. It exercises parsing and record construction but does not claim to model an LLDB target:

$ printf '%s\n' \
    'class Demo<int N> { int value = N; }' \
    'def Example : Demo<7>;' \
  | llvm-tblgen-20 -null-backend -
$ printf 'exit status: %s\n' "$?"
exit status: 0

A zero status means this frontend accepted the input and built its records. -null-backend deliberately produces no generated file, so there is no output to clean up. This is a useful first checkpoint when a larger file fails: it separates a tool installation problem from an include, syntax or backend problem.

To inspect what the parser built, use the default record-printing backend instead:

$ printf '%s\n' \
    'class Demo<int N> { int value = N; }' \
    'def Example : Demo<7>;' \
  | llvm-tblgen-20 -print-records -
------------- Classes -----------------
class Demo<int Demo:N = ?> {
  int value = Demo:N;
}
------------- Defs -----------------
def Example {    // Demo
  int value = 7;
}

Formatting can change between LLVM releases. Check the exit status and the records, rather than matching whitespace in a script.

4. Run a real file with its include path

Move to the directory used by the source tree and pass include roots explicitly. LLVM projects commonly rely on included .td files, so running from an arbitrary directory can produce a misleading missing-file error:

$ cd /path/to/llvm-project
$ llvm-tblgen-20 -I /path/to/llvm-project/llvm/include \
    -I /path/to/llvm-project/lldb/include \
    -null-backend /path/to/input.td
$ printf 'exit status: %s\n' "$?"
exit status: 0

Replace both paths and the input with locations that exist in your checkout. Add further -I values only for directories that the source's include statements require. If an include is missing, check the path and the exact spelling before changing the source. Elevated privileges will not repair a wrong include root.

If the file parses, select the backend required by the tool that consumes the generated code. Backend names are executable-specific; inspect lldb-tblgen-20 --help when that command exists, or the build documentation for the LLVM revision you are using. Do not copy an llvm-tblgen-20 backend option into an LLDB command without verifying it.

5. Write output without losing an existing file

Output generation changes files, so inspect the destination first. Shell redirection and -o can replace an existing file. Use a new temporary destination in the same filesystem, verify it, then replace the final file only when you are ready:

$ test ! -e /path/to/generated.new || \
    { printf '%s\n' 'Refusing to overwrite generated.new'; exit 1; }
$ llvm-tblgen-20 -I /path/to/include \
    -print-records /path/to/input.td -o /path/to/generated.new
$ test -s /path/to/generated.new
$ mv -- /path/to/generated.new /path/to/generated.inc

Warning

The final mv replaces generated.inc if it already exists. Keep a copy or use version control before doing that in a working tree. If generation fails, do not move the incomplete file. Remove only the named temporary file after checking the failure; the original generated file remains untouched.

For repeatable builds, -write-if-changed can avoid rewriting an output whose content is identical. That reduces timestamp churn, but it does not validate that the selected backend is the right one.

6. Diagnose the common failure modes

A missing lldb-tblgen-20 command is different from a bad .td file. First run command -v and dpkg-query again. If only llvm-tblgen-20 is present, generic parsing is available but LLDB-specific generation is not demonstrated by this host.

A non-zero status with an include error usually means that an -I directory is missing or points at the wrong checkout. A syntax or type diagnostic points at the source. A successful parse followed by an unknown backend option means the option belongs to a different TableGen executable or LLVM revision. Preserve the full diagnostic and the exact version output when reporting the issue.

Do not use sudo to run a compiler generator against a source tree you own. It can leave root-owned generated files behind and hide ordinary path mistakes. Use elevated privileges only when your build directory is intentionally protected, and prefer fixing its ownership or permissions through the project administrator.

Done means

  • The installed LLVM package and TableGen version were recorded.
  • You checked whether the LLDB-specific executable exists instead of assuming the manpage installed it.
  • A small .td input parsed successfully with -null-backend.
  • Real source files use explicit include directories and a verified backend.
  • Generated output is written to a new path, checked, and only then moved into place.
  • A failed generation cannot overwrite the previous output, and no service or system configuration was changed.