# Clang Tool Refactoring [TOC] ## Caveats * The current workflow requires git. * This doesn't work on Windows... yet. I'm hoping to have a proof-of-concept working on Windows as well ~~in a month~~ several centuries from now. ## Prerequisites Everything needed should be in a default Chromium checkout using gclient. `third_party/llvm-build/Release+Asserts/bin` should be in your `$PATH`. ## Writing the Tool An example clang tool is being implemented in https://codereview.chromium.org/12746010/. Other useful resources might be the [basic tutorial for Clang's AST matchers](http://clang.llvm.org/docs/LibASTMatchersTutorial.html) or the [AST matcher reference](http://clang.llvm.org/docs/LibASTMatchersReference.html). Build your tool by running the following command (requires cmake version 2.8.10 or later): ```shell tools/clang/scripts/update.sh --force-local-build --without-android \ --with-chrome-tools ``` `` is a semicolon delimited list of subdirectories in `tools/clang` to build. The resulting binary will end up in `third_party/llvm-build/Release+Asserts/bin`. For example, to build the Chrome plugin and the empty\_string tool, run the following: ```shell tools/clang/scripts/update.sh --force-local-build --without-android \ --with-chrome-tools "plugins;empty_string" ``` When writing AST matchers, the following can be helpful to see what clang thinks the AST is: ```shell clang++ -cc1 -ast-dump foo.cc ``` ## Running the tool First, you'll need to generate the compilation database with the following command: ```shell cd $HOME/src/chrome/src ninja -C out/Debug -t compdb cc cxx objc objcxx > \ out/Debug/compile_commands.json ``` This will dump the command lines used to build the C/C++ modules in all of Chromium into the resulting file. Then run the following command to run your tool across all Chromium code: ```shell # Make sure all chromium targets are built to avoid missing generated # dependencies ninja -C out/Debug tools/clang/scripts/run_tool.py \ ... ``` ``, ``, etc are optional arguments you use to filter the files that will be rewritten. For example, if you only want to run the `empty-string` tool on files in `chrome/browser/extensions` and `sync`, you'd do something like: ```shell tools/clang/scripts/run_tool.py empty_string out/Debug \ chrome/browser/extensions sync ``` ## Limitations Since the compile database is generated by ninja, that means that files that aren't compiled on that platform won't be processed. That means if you want to apply a change across all Chromium platforms, you'll have to run the tool once on each platform. ## Testing `test_tool.py` is the test harness for running tests. To use it, simply run: ```shell test_tool.py ``` Note that name of the built tool and the subdirectory it lives in at `tools/clang` must match. What the test harness does is find all files that match the pattern `*-original.cc` in your tool's tests subdirectory. It then runs the tool across those files and compares it to the expected result, stored in `*-expected.cc`