OLD | NEW |
1 # Clang Tool Refactoring | 1 # Clang Tool Refactoring |
2 | 2 |
3 [TOC] | 3 [TOC] |
4 | 4 |
5 ## Introduction | 5 ## Introduction |
6 | 6 |
7 Clang tools can help with global refactorings of Chromium code. Clang tools can | 7 Clang tools can help with global refactorings of Chromium code. Clang tools can |
8 take advantage of clang's AST to perform refactorings that would be impossible | 8 take advantage of clang's AST to perform refactorings that would be impossible |
9 with a traditional find-and-replace regexp: | 9 with a traditional find-and-replace regexp: |
10 | 10 |
(...skipping 21 matching lines...) Expand all Loading... |
32 | 32 |
33 ## Writing the tool | 33 ## Writing the tool |
34 | 34 |
35 LLVM uses C++11 and CMake. Source code for Chromium clang tools lives in | 35 LLVM uses C++11 and CMake. Source code for Chromium clang tools lives in |
36 [//tools/clang](https://chromium.googlesource.com/chromium/src/tools/clang/+/mas
ter). | 36 [//tools/clang](https://chromium.googlesource.com/chromium/src/tools/clang/+/mas
ter). |
37 It is generally easiest to use one of the already-written tools as the base for | 37 It is generally easiest to use one of the already-written tools as the base for |
38 writing a new tool. | 38 writing a new tool. |
39 | 39 |
40 Chromium clang tools generally follow this pattern: | 40 Chromium clang tools generally follow this pattern: |
41 | 41 |
42 1. Instantiate a [`clang::ast_matchers::MatchFinder`]( | 42 1. Instantiate a [`clang::ast_matchers::MatchFinder`](http://clang.llvm.org/dox
ygen/classclang_1_1ast__matchers_1_1MatchFinder.html). |
43 http://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder.htm
l). | 43 2. Call `addMatcher()` to register [`clang::ast_matchers::MatchFinder::MatchCal
lback`](http://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder
_1_1MatchCallback.html) |
44 2. Call `addMatcher()` to register [`clang::ast_matchers::MatchFinder::MatchCal
lback`]( | 44 actions to execute when [matching](http://clang.llvm.org/docs/LibASTMatchers
Reference.html) |
45 http://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder_1_1
MatchCallback.html) actions to execute when [matching](http://clang.llvm.org/doc
s/LibASTMatchersReference.html) the AST. | 45 the AST. |
46 3. Create a new `clang::tooling::FrontendActionFactory` from the `MatchFinder`. | 46 3. Create a new `clang::tooling::FrontendActionFactory` from the `MatchFinder`. |
47 4. Run the action across the specified files with | 47 4. Run the action across the specified files with |
48 [`clang::tooling::ClangTool::run`](http://clang.llvm.org/doxygen/classclang_
1_1tooling_1_1ClangTool.html#acec91f63b45ac7ee2d6c94cb9c10dab3). | 48 [`clang::tooling::ClangTool::run`](http://clang.llvm.org/doxygen/classclang_
1_1tooling_1_1ClangTool.html#acec91f63b45ac7ee2d6c94cb9c10dab3). |
49 5. Serialize generated [`clang::tooling::Replacement`]( | 49 5. Serialize generated [`clang::tooling::Replacement`](http://clang.llvm.org/do
xygen/classclang_1_1tooling_1_1Replacement.html)s |
50 http://clang.llvm.org/doxygen/classclang_1_1tooling_1_1Replacement.html)s to | 50 to `stdout`. |
51 `stdout`. | |
52 | 51 |
53 Other useful references when writing the tool: | 52 Other useful references when writing the tool: |
54 | 53 |
55 * [Clang doxygen reference](http://clang.llvm.org/doxygen/index.html) | 54 * [Clang doxygen reference](http://clang.llvm.org/doxygen/index.html) |
56 * [Tutorial for building tools using LibTooling and LibASTMatchers](http://cla
ng.llvm.org/docs/LibASTMatchersTutorial.html) | 55 * [Tutorial for building tools using LibTooling and LibASTMatchers](http://cla
ng.llvm.org/docs/LibASTMatchersTutorial.html) |
57 | 56 |
58 ### Edit serialization format | 57 ### Edit serialization format |
59 ``` | 58 ``` |
60 ==== BEGIN EDITS ==== | 59 ==== BEGIN EDITS ==== |
61 r:::path/to/file1:::offset1:::length1:::replacement text | 60 r:::path/to/file1:::offset1:::length1:::replacement text |
(...skipping 16 matching lines...) Expand all Loading... |
78 knows to translate `\0` back to newlines when applying edits. | 77 knows to translate `\0` back to newlines when applying edits. |
79 * When removing an element from a 'list' (e.g. function parameters, | 78 * When removing an element from a 'list' (e.g. function parameters, |
80 initializers), the tool should emit a deletion for just the element. The | 79 initializers), the tool should emit a deletion for just the element. The |
81 script understands how to extend the deletion to remove commas, etc. as | 80 script understands how to extend the deletion to remove commas, etc. as |
82 needed. | 81 needed. |
83 | 82 |
84 TODO: Document more about `SourceLocation` and how spelling loc differs from | 83 TODO: Document more about `SourceLocation` and how spelling loc differs from |
85 expansion loc, etc. | 84 expansion loc, etc. |
86 | 85 |
87 ### Why not RefactoringTool? | 86 ### Why not RefactoringTool? |
88 While clang has a [`clang::tooling::RefactoringTool`]( | 87 While clang has a [`clang::tooling::RefactoringTool`](http://clang.llvm.org/doxy
gen/classclang_1_1tooling_1_1RefactoringTool.html) |
89 http://clang.llvm.org/doxygen/classclang_1_1tooling_1_1RefactoringTool.html) to | 88 to automatically apply the generated replacements and save the results, it |
90 automatically apply the generated replacements and save the results, it doesn't | 89 doesn't work well for Chromium: |
91 work well for Chromium: | |
92 | 90 |
93 * Clang tools run actions serially, so runtime scales poorly to tens of | 91 * Clang tools run actions serially, so runtime scales poorly to tens of |
94 thousands of files. | 92 thousands of files. |
95 * A parsing error in any file (quite common in NaCl source) prevents any of | 93 * A parsing error in any file (quite common in NaCl source) prevents any of |
96 the generated replacements from being applied. | 94 the generated replacements from being applied. |
97 | 95 |
98 ## Building | 96 ## Building |
99 Synopsis: | 97 Synopsis: |
| 98 |
100 ```shell | 99 ```shell |
101 tools/clang/scripts/update.py --force-local-build --without-android \ | 100 tools/clang/scripts/update.py --force-local-build --without-android \ |
102 --tools blink_gc_plugin plugins rewrite_to_chrome_style | 101 --tools blink_gc_plugin plugins rewrite_to_chrome_style |
103 ``` | 102 ``` |
| 103 |
104 Running this command builds the [Oilpan plugin](https://chromium.googlesource.co
m/chromium/src/+/master/tools/clang/blink_gc_plugin/), | 104 Running this command builds the [Oilpan plugin](https://chromium.googlesource.co
m/chromium/src/+/master/tools/clang/blink_gc_plugin/), |
105 the [Chrome style | 105 the [Chrome style |
106 plugin](https://chromium.googlesource.com/chromium/src/+/master/tools/clang/plug
ins/), | 106 plugin](https://chromium.googlesource.com/chromium/src/+/master/tools/clang/plug
ins/), |
107 and the [Blink to Chrome style rewriter](https://chromium.googlesource.com/chrom
ium/src/+/master/tools/clang/rewrite_to_chrome_style/). Additional arguments to
`--tools` should be the name of | 107 and the [Blink to Chrome style rewriter](https://chromium.googlesource.com/chrom
ium/src/+/master/tools/clang/rewrite_to_chrome_style/). Additional arguments to
`--tools` should be the name of |
108 subdirectories in | 108 subdirectories in |
109 [//tools/clang](https://chromium.googlesource.com/chromium/src/+/master/tools/cl
ang). | 109 [//tools/clang](https://chromium.googlesource.com/chromium/src/+/master/tools/cl
ang). |
110 Generally, `--tools` should always include `blink_gc_plugin` and `plugins`: othe
rwise, Chromium won't build. | 110 Generally, `--tools` should always include `blink_gc_plugin` and `plugins`: othe
rwise, Chromium won't build. |
111 | 111 |
112 ## Running | 112 ## Running |
113 First, build all chromium targets to avoid failures due to missing dependecies | 113 First, build all chromium targets to avoid failures due to missing dependecies |
114 that are generated as part of the build: | 114 that are generated as part of the build: |
| 115 |
115 ```shell | 116 ```shell |
116 ninja -C out/Debug | 117 ninja -C out/Debug |
117 ``` | 118 ``` |
118 | 119 |
119 Then run the actual tool: | 120 Then run the actual tool: |
120 ``` | 121 ``` |
121 tools/clang/scripts/run_tool.py <toolname> \ | 122 tools/clang/scripts/run_tool.py <toolname> \ |
122 --generate-compdb | 123 --generate-compdb |
123 out/Debug <path 1> <path 2> ... | 124 out/Debug <path 1> <path 2> ... |
124 ``` | 125 ``` |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 Synposis: | 164 Synposis: |
164 ```shell | 165 ```shell |
165 test_tool.py <tool name> | 166 test_tool.py <tool name> |
166 ``` | 167 ``` |
167 | 168 |
168 The name of the tool binary and the subdirectory for the tool in | 169 The name of the tool binary and the subdirectory for the tool in |
169 `//tools/clang` must match. The test runner finds all files that match the | 170 `//tools/clang` must match. The test runner finds all files that match the |
170 pattern `//tools/clang/<tool name>/tests/*-original.cc`, runs the tool across | 171 pattern `//tools/clang/<tool name>/tests/*-original.cc`, runs the tool across |
171 those files, and compared it to the `*-expected.cc` version. If there is a | 172 those files, and compared it to the `*-expected.cc` version. If there is a |
172 mismatch, the result is saved in `*-actual.cc`. | 173 mismatch, the result is saved in `*-actual.cc`. |
OLD | NEW |