nlohmann has customization points for exception throws. we can use these instead and wrap json exceptions at the source instead of playing a game of whack-a-mole with json errors all over the tree. since nlohmann needs macros set to achieve this we can no longer precompile its headers *and* must forbid including it anywhere without the proper defines or ordering of include directives will break lix with ODR violations, if we see them at all before we get another json-related bug report. a new lint will be in charge of ensuring this doesn't happen. we also re-allow direct calls to nlohmann json parsing since error handling is no longer a problem. we will keep the wrapper for more convenient error context handling though. fixes #1092 Change-Id: I54ecc14f5bec5e2177729b41c3703216e76cc6a3
Clang tidy lints for Lix
This is a skeleton of a clang-tidy lints library for Lix.
Currently there is one check (which is already obsolete as it has served its
goal and is there as an example), HasPrefixSuffixCheck.
Running fixes/checks
One file:
ninja -C build && clang-tidy --checks='-*,lix-*' --load=build/liblix-clang-tidy.so -p ../../build -header-filter '\.\./lix/.*\.h' --fix ../../lix/libcmd/installables.cc
Several files, in parallel:
ninja -C build && run-clang-tidy -checks='-*,lix-*' -load=build/liblix-clang-tidy.so -p ../../build -header-filter '\.\./lix/.*\.h' -fix ../../lix | tee -a clang-tidy-result
Resources
- https://firefox-source-docs.mozilla.org/code-quality/static-analysis/writing-new/clang-query.html
- https://clang.llvm.org/docs/LibASTMatchersReference.html
- https://devblogs.microsoft.com/cppblog/exploring-clang-tooling-part-3-rewriting-code-with-clang-tidy/
Developing new checks
Put something like so in myquery.txt:
set traversal IgnoreUnlessSpelledInSource
# ^ Ignore implicit AST nodes. May need to use AsIs depending on how you are
# working.
set bind-root true
# ^ true unless you use any .bind("foo") commands
set print-matcher true
enable output dump
match callExpr(callee(functionDecl(hasName("hasPrefix"))), optionally(hasArgument( 0, cxxConstructExpr(hasDeclaration(functionDecl(hasParameter(0, parmVarDecl(hasType(asString("const char *"))).bind("meow2"))))))))
Then run, e.g. clang-query --preload hasprefix.query -p compile_commands.json lix/libcmd/installables.cc.
With this you can iterate a query before writing it in C++ and suffering from C++.
Tips and tricks for the C++
There is a function dump() on many things that will dump to stderr. Also
llvm::errs() lets you print to stderr.
When I wrote HasPrefixSuffixCheck, I was not really able to figure out how
the structured replacement system was supposed to work. In principle you can
describe the replacement with a nice DSL. Look up the Stencil system in Clang
for details.