# ClangQL and running SQL against a C or C++ syntax tree

> ClangQL is a Rust command line tool that lets you run SQL-like queries against C and C++ source by parsing it with LibClang and exposing the resulting syntax tree as queryable tables, using the GitQL SDK for the query engine. The interesting part is that the same SQL surface you would use on a database now works on code, and the interesting constraint is that the whole approach depends on having a specific LibClang version installed on the machine.

**AmrDeveloper/ClangQL** —  ClangQL is a tool that allow you to run SQL-like query on C/C++ Code instead of database files using the GitQL SDK

- Repository: https://github.com/AmrDeveloper/ClangQL
- Website: https://amrdeveloper.github.io/ClangQL/
- Stars: 538 · Forks: 12
- Language: Rust
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/amrdeveloper-clangql

## The idea: a query language over source code

ClangQL is a tool that allows you to run SQL-like queries on C and C++ code instead of on database files, using the GitQL SDK. The Cargo manifest describes it as a tool to run SQL-like queries on your C/C++ abstract syntax tree, and the topics make the same point from the other direction with ast, clang, cpp, llvm, llvm-clang, llvm-frontend and parser.

The framing is the whole idea. A C++ codebase is a graph of declarations, and the usual way to interrogate one is to write a script using the language's own tooling, or to grep, or to write a bespoke analyser. ClangQL takes the database route: parse the code into a syntax tree with LibClang, expose that tree as a set of tables with rows and columns, and let a query engine run ordinary SQL over it.

The consequence is that the familiar syntax carries over. The sample queries show constants and string functions first, which is how a SQL dialect is usually introduced:

```sql
SELECT 1
SELECT 1 + 2
SELECT LEN("Clang Query Language")
SELECT "One" IN ("One", "Two", "Three")
SELECT "Clang Query Language" LIKE "%Query%"
```

And then the queries get specific to code. Functions and globals are the two tables shown, and the interesting part is the matcher syntax in the WHERE clause:

```sql
SELECT name, source_loc FROM functions WHERE m_function(ast_function, m_constructor());
```

The m_function predicate takes a function kind and a set of matchers, so a single query can select constructors, copy constructors, move constructors or pure virtual functions, each of which has its own sample in the documentation. The (m_public() && m_constructor()) form in another sample combines matchers with a logical and, so the language can express conjunctions of properties rather than a single property at a time.

The primary language is Rust, the licence is MIT, the default branch is master, the homepage is amrdeveloper.github.io/ClangQL, and the recent releases are 0.11.0 from 2025-11-10, 0.10.0 from 2025-03-26 and 0.9.0 from 2025-01-12. The last push was on 2026-04-21, and the repository is not archived.

## The tables you can query

The samples show two table families, and the shape of the queries tells you what each one holds.

The functions table has a name, a source location, a return type, and a set of properties that can be matched. Counting by return type is the canonical aggregate query:

```sql
SELECT COUNT(name) from functions WHERE return_type = "int"
```

The globals table works the same way, with a name, a type and properties:

```sql
SELECT * FROM globals
SELECT COUNT(name) from globals WHERE type = "int"
SELECT * FROM globals WHERE is_volatile
```

That last query is a good example of the style. is_volatile is a boolean property of a global, and the WHERE clause tests it directly without a comparison, which is what you would expect from a query language that has absorbed a type system with real booleans rather than SQL's convention of treating them as integers.

Deduplication and renaming are available too, since the samples include a DISTINCT form with an alias:

```sql
SELECT DISTINCT name AS function_name FROM functions
```

Which is a normal thing to want when you are asking how many distinct functions a project defines and some of them share a name across namespaces or overloads.

The documentation also shows a query analysis flag, and the help output lists -a, --analysis for printing the query analysis. That is a debugging aid for the query itself rather than for the code, and its presence tells you the engine is doing real planning work on the query rather than translating it into a scan.

The samples directory in the repository contains a Main.cpp file The documentation site is built with mkdocs, and there is a mkdocs.yml at the root, so the full table schema and the matcher catalogue live there rather than in the readme.

## Installing it and the LibClang requirement

There are three ways to get ClangQL, and one prerequisite that applies to all of them.

The prerequisite comes first, in the download section: building from source or installing from Cargo.io requires LibClang 17 to be installed. It is not optional, and it is not bundled.

From Cargo.io:

```bash
cargo install clangql
```

From Homebrew:

```bash
brew install clangql
```

Or from source:

```bash
git clone https://github.com/AmrDeveloper/clangql.git
cd clangql
cargo build
```

The Homebrew route is interesting because it is the one that likely handles LibClang for you, and the Cargo route is the one that most often does not.

The dependency list in the Cargo manifest explains where the parsing and the querying come from. The GitQL family provides the query engine and the language: gitql-core, gitql-std, gitql-cli, gitql-ast, gitql-parser and gitql-engine, at versions ranging from 0.20.0 to 0.43.0. On top of that sits clang-sys at 1.8.1 with the clang_18_0 feature enabled, which is the Rust binding to the LibClang C API, and dyn-clone for the cloneable trait objects the engine needs.

One detail is worth flagging because it is a common source of confusion. The manifest enables the clang_18_0 feature of clang-sys, while the readme says LibClang 17 is required. Those are not the same version number, and the feature flag in clang-sys selects the API version the bindings are compiled against, while the readme is telling you which LibClang you need installed. If the two do not line up on your machine, that is where the build failure will be, and it will look like a linking error rather than a version problem.

The release profile is tuned for a command line tool: codegen-units set to 1 and link time optimisation enabled, which trades build time for a faster binary, and the package is categorised as a command-line utility.

## Running it, and the output formats

The command line is short, and the flags divide into three groups: where to look, what to run, and how to print.

```
ClangQL is a SQL like query language to run on local files
Usage: ClangQL [OPTIONS]

Options:
  -f,  --files <paths>        Path for local files to run query on
  -s,  --script <file>        Script file contains one or more query
  -q,  --query <GQL Query>    ClangQL query to run on selected files
```

So the input side is -f for the paths of the local files to run the query on, -s for a script file that contains one or more queries, and -q for a single query given on the command line. The three of them are alternatives rather than a pipeline, and a script file holding several queries is how you would run a batch of questions over a codebase.

The output side is where a query language earns its keep in a build pipeline. There is -o, --output to set the output format to render, json or csv, and -p, --pagination to enable printing results with pagination, with -ps, --pagesize setting the page size and a default of 10.

JSON and CSV output are the ones that matter for automation, and the presence of a paginated render mode suggests the tool is designed to be used interactively as well as in scripts, with a terminal table for a human and machine-readable output for a pipeline.

Then there are the informational flags: -a for printing the query analysis, -h for help and -v for the current version.

The versioning scheme is worth a small note for anyone tracking it. The recent releases are 0.11.0, 0.10.0 and 0.9.0. The Cargo keywords still list both gitql and clangql, and there is a CHANGELOG.md at the root for the history.

## Where ClangQL is the wrong tool

Three limits follow from the design, and they are worth weighing before you build a query library on top of it.

The first is that the input must compile. The tree comes from LibClang, which is a real C++ parser with real semantic analysis, and code that does not parse produces no tree. For a codebase with template metaprogramming, platform-specific headers or generated code that only exists in a build tree, that rules out large parts of the source. A tool that could work on unparseable text would have to be a different kind of tool.

The second is the LibClang coupling. Because the tool depends on a specific LibClang version being present, and because it binds through clang-sys, the tool inherits the version management of LLVM. That is a real operational commitment for a command line utility, and it is why the Homebrew install is probably the sane choice for a team that does not already have a pinned LLVM.

The third is what the schema covers. The tables shown are functions and globals, and the properties are the ones the tool's own model defines. If your question is about inheritance hierarchies, template instantiations, macro expansion, include graphs or type aliasing, you need to check the documentation for whether the corresponding table exists, because the SQL surface is only as wide as the schema the tool built. This is the point where a bespoke LibClang script or a different tool wins.

The alternative worth comparing against is a language server. A language server such as clangd works from the same parsed code and is built for interactive, editor-driven exploration. The difference in approach is that a language server is built for interactive, editor-driven exploration with incremental updates, while ClangQL is built for repeatable batch queries over a whole tree with output you can pipe into a script or a report. If you want one answer about one function while editing, a language server is the better fit. If you want a quarterly report of every pure virtual constructor in a codebase, ClangQL is.

A third option is writing the analyser directly against the Clang Python bindings, which gives complete freedom over what you extract and avoids the fixed schema, at the cost of writing the traversal yourself every time.

## Conclusion

ClangQL is a good fit for a developer who wants to answer structural questions about a C or C++ codebase with a query instead of a script, because the Clang syntax tree is exposed as ordinary SQL tables and the familiar SELECT, WHERE, COUNT and DISTINCT syntax carries over unchanged. It is a poor fit if you need to analyse code that does not compile, since the tree comes from a real parser, and a poor fit for a codebase you cannot compile with the required LibClang version, because the build and the runtime both need it. Before adopting, check that LibClang 17 is installed and reachable, and read the samples rather than assuming the schema, since the available tables and their properties are defined by the tool rather than by SQL itself.

## FAQ

### What is ClangQL and what can you query with it?

ClangQL is a Rust command line tool that runs SQL-like queries against C and C++ code rather than database files, using the GitQL SDK for the query engine and LibClang to produce the syntax tree. The documented tables include functions and globals, with properties such as return_type, type and is_volatile.

### How do I install ClangQL?

With `cargo install clangql`, with `brew install clangql`, or by cloning the repository and running `cargo build`. Building from source or installing from Cargo.io requires LibClang 17 to be installed on the machine.

### How do I run a query against a codebase?

Use -f to point at the local files to query, then -q for a single query or -s for a script file containing one or more queries. Keywords are case-insensitive, in the same way as SQL.

### Can ClangQL output results in a machine-readable format?

Yes. The --output option sets the format to render, json or csv, and the --pagination option enables paginated output with a configurable page size that defaults to 10. There is also an --analysis flag to print the query analysis.

### What is the m_function matcher used for?

It filters functions by kind in the WHERE clause, with matchers for constructors, copy constructors, move constructors, pure virtual functions and public functions, and matchers can be combined with a logical and inside a single query.

### What licence is ClangQL released under?

MIT, with the copyright held by Amr Hesham and the licence text in the readme and the file at the repository root. The most recent release is 0.11.0 from 2025-11-10, and the last push was on 2026-04-21.

## Sources

- [AmrDeveloper/ClangQL on GitHub](https://github.com/AmrDeveloper/ClangQL)
- [License: MIT](https://github.com/AmrDeveloper/ClangQL/blob/master/LICENSE)
- [Project website](https://amrdeveloper.github.io/ClangQL/)
- [README](https://github.com/AmrDeveloper/ClangQL/blob/master/README.md)
- [Releases](https://github.com/AmrDeveloper/ClangQL/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/amrdeveloper-clangql
