blob: 48e7c60ad5b9ab03df950a75ab940d18a632a091 [file] [log] [blame] [view]
andybons6eaa0c0d2015-08-26 20:12:521# Clang Tool Refactoring
andybons3322f762015-08-24 21:37:092
andybons6eaa0c0d2015-08-26 20:12:523[TOC]
andybons3322f762015-08-24 21:37:094
andybons6eaa0c0d2015-08-26 20:12:525## Caveats
andybons3322f762015-08-24 21:37:096
andybons6eaa0c0d2015-08-26 20:12:527* The current workflow requires git.
8* This doesn't work on Windows... yet. I'm hoping to have a proof-of-concept
9 working on Windows as well ~~in a month~~ several centuries from now.
10
11## Prerequisites
12
13Everything needed should be in a default Chromium checkout using gclient.
14`third_party/llvm-build/Release+Asserts/bin` should be in your `$PATH`.
15
16## Writing the Tool
17
18An example clang tool is being implemented in
19https://codereview.chromium.org/12746010/. Other useful resources might be the
20[basic tutorial for Clang's AST matchers](http://clang.llvm.org/docs/LibASTMatchersTutorial.html)
21or the
22[AST matcher reference](http://clang.llvm.org/docs/LibASTMatchersReference.html).
23
24Build your tool by running the following command (requires cmake version 2.8.10
25or later):
26
27```shell
Nico Webere250e6a2015-12-02 19:31:5628tools/clang/scripts/update.py --force-local-build --without-android \
andybons6eaa0c0d2015-08-26 20:12:5229--with-chrome-tools <tools>
andybons3322f762015-08-24 21:37:0930```
31
andybons6eaa0c0d2015-08-26 20:12:5232`<tools>` is a semicolon delimited list of subdirectories in `tools/clang` to
33build. The resulting binary will end up in
34`third_party/llvm-build/Release+Asserts/bin`. For example, to build the Chrome
35plugin and the empty\_string tool, run the following:
36
37```shell
Nico Webere250e6a2015-12-02 19:31:5638tools/clang/scripts/update.py --force-local-build --without-android \
andybons6eaa0c0d2015-08-26 20:12:5239--with-chrome-tools "plugins;empty_string"
andybons3322f762015-08-24 21:37:0940```
andybons6eaa0c0d2015-08-26 20:12:5241
42When writing AST matchers, the following can be helpful to see what clang thinks
43the AST is:
44
45```shell
andybons3322f762015-08-24 21:37:0946clang++ -cc1 -ast-dump foo.cc
47```
48
andybons6eaa0c0d2015-08-26 20:12:5249## Running the tool
50
51First, you'll need to generate the compilation database with the following
52command:
53
54```shell
andybons3322f762015-08-24 21:37:0955cd $HOME/src/chrome/src
andybons6eaa0c0d2015-08-26 20:12:5256ninja -C out/Debug -t compdb cc cxx objc objcxx > \
57out/Debug/compile_commands.json
andybons3322f762015-08-24 21:37:0958```
59
andybons6eaa0c0d2015-08-26 20:12:5260This will dump the command lines used to build the C/C++ modules in all of
61Chromium into the resulting file. Then run the following command to run your
62tool across all Chromium code:
63
64```shell
65# Make sure all chromium targets are built to avoid missing generated
66# dependencies
andybons3322f762015-08-24 21:37:0967ninja -C out/Debug
andybons6eaa0c0d2015-08-26 20:12:5268tools/clang/scripts/run_tool.py <toolname> \
69<path/to/directory/with/compile_commands.json> <path 1> <path 2> ...
andybons3322f762015-08-24 21:37:0970```
71
andybons6eaa0c0d2015-08-26 20:12:5272`<path 1>`, `<path 2>`, etc are optional arguments you use to filter the files
73that will be rewritten. For example, if you only want to run the `empty-string`
74tool on files in `chrome/browser/extensions` and `sync`, you'd do something like:
75
76```shell
77tools/clang/scripts/run_tool.py empty_string out/Debug \
78chrome/browser/extensions sync
andybons3322f762015-08-24 21:37:0979```
80
andybons6eaa0c0d2015-08-26 20:12:5281## Limitations
andybons3322f762015-08-24 21:37:0982
andybons6eaa0c0d2015-08-26 20:12:5283Since the compile database is generated by ninja, that means that files that
84aren't compiled on that platform won't be processed. That means if you want to
85apply a change across all Chromium platforms, you'll have to run the tool once
86on each platform.
87
88## Testing
89
andybons3322f762015-08-24 21:37:0990`test_tool.py` is the test harness for running tests. To use it, simply run:
andybons6eaa0c0d2015-08-26 20:12:5291
92```shell
andybons3322f762015-08-24 21:37:0993test_tool.py <tool name>
94```
andybons6eaa0c0d2015-08-26 20:12:5295
96Note that name of the built tool and the subdirectory it lives in at
97`tools/clang` must match. What the test harness does is find all files that
98match the pattern `*-original.cc` in your tool's tests subdirectory. It then
99runs the tool across those files and compares it to the expected result, stored
100in `*-expected.cc`