Have you ever wanted to identify a list of files that would need modifications to adopt a new API? Clang-Query can make this much easier. I recently wanted to introduce a set of helper functions to simplfy an aspect of compressor configuation in LibPressio. But first, I needed to know what modules were effected.
Clang-query needs a compilation database which can be produced by tools such as bear
(if you have a Autotools or Makefile based project) or more sophisticated build systems such as cmake
, meson
or bazel
.
After we have these, the files are just JSON, so we can produce a list of files that are effected using jq
and reduce the set considered using the select
function.
jq '.[].file | select(test("src/plugins/"))' ./build/compile_commands.json
However clang-query
needs relative paths (This seems like a bug to me, but 🤷) so we can convert them using | xargs realpath --relative-to .
clang-query -p ./build/compile_commands.json $( jq '.[].file | select(test("src/plugins/"))' ./build/compile_commands.json | xargs realpath --relative-to . )
Clang-query will then construct a C++ AST for each of the files which we can then query.
I knew that the effected modules would provide a definition of a method called set_name_impl
and would exist in a certain source directory. The corresponding match expression is
cxxMethodDecl(hasName("set_name_impl"), isExpansionInMainFile())
which in turn returns all of the files that should be effected. However, the method that needs to be actually needs to be modified is get_configuration_impl
and we want to see if we missed any places that need to be modified, so we can look for the old pattern:
set traversal IgnoreUnlessSpelledInSource
set bind-root false
match cxxMethodDecl(hasName("get_configuration_impl"), hasDescendant(cxxMemberCallExpr(hasArgument(0, unless(cxxMemberCallExpr(on(memberExpr())))), hasDeclaration(cxxMethodDecl(hasName("copy_from")))).bind("r")), isExpansionInMainFile())
Determing the appropriate matcher can be done iteratively using tab completion, binding, and the dump
output mode.