├── .clang-format ├── .clang-tidy ├── .gitignore ├── CMakeLists.txt ├── CPPLINT.cfg ├── LICENSE ├── README.md ├── clang-expand.cpp ├── cmake └── modules │ └── FindLLVM.cmake ├── docker-compose.yaml ├── docker ├── .dockerignore ├── build.sh ├── debian.Dockerfile ├── fedora.Dockerfile ├── opensuse.Dockerfile └── ubuntu.Dockerfile ├── docs └── Doxyfile ├── extra └── clang-expand.gif ├── include └── clang-expand │ ├── common │ ├── assignee-data.hpp │ ├── call-data.hpp │ ├── canonical-location.hpp │ ├── context-data.hpp │ ├── declaration-data.hpp │ ├── definition-data.hpp │ ├── definition-rewriter.hpp │ ├── location.hpp │ ├── offset.hpp │ ├── query.hpp │ ├── range.hpp │ └── routines.hpp │ ├── definition-search │ ├── action.hpp │ ├── consumer.hpp │ ├── match-handler.hpp │ └── tool-factory.hpp │ ├── options.hpp │ ├── result.hpp │ ├── search.hpp │ └── symbol-search │ ├── action.hpp │ ├── consumer.hpp │ ├── macro-search.hpp │ ├── match-handler.hpp │ └── tool-factory.hpp ├── source ├── CMakeLists.txt ├── common │ ├── assignee-data.cpp │ ├── call-data.cpp │ ├── canonical-location.cpp │ ├── declaration-data.cpp │ ├── definition-data.cpp │ ├── definition-rewriter.cpp │ ├── location.cpp │ ├── offset.cpp │ ├── range.cpp │ └── routines.cpp ├── definition-search │ ├── action.cpp │ ├── consumer.cpp │ ├── match-handler.cpp │ └── tool-factory.cpp ├── result.cpp ├── search.cpp └── symbol-search │ ├── action.cpp │ ├── consumer.cpp │ ├── macro-search.cpp │ ├── match-handler.cpp │ └── tool-factory.cpp └── third-party └── json.hpp /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | Standard: Cpp11 3 | BasedOnStyle: Google 4 | 5 | AllowAllParametersOfDeclarationOnNextLine: true 6 | AllowShortBlocksOnASingleLine: false 7 | AllowShortCaseLabelsOnASingleLine: true 8 | AllowShortFunctionsOnASingleLine: false 9 | AllowShortIfStatementsOnASingleLine: true 10 | AllowShortLoopsOnASingleLine: true 11 | 12 | AlignOperands: true 13 | AlignConsecutiveAssignments: false 14 | 15 | BinPackArguments: false 16 | BinPackParameters: false 17 | BreakConstructorInitializersBeforeComma: true 18 | ColumnLimit: 80 19 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 20 | ConstructorInitializerIndentWidth: 0 21 | ContinuationIndentWidth: 4 22 | Cpp11BracedListStyle: true 23 | DerivePointerAlignment: false 24 | IndentCaseLabels: true 25 | IndentWidth: 2 26 | MaxEmptyLinesToKeep: 2 27 | NamespaceIndentation: None 28 | PointerAlignment: Left 29 | SpacesBeforeTrailingComments: 2 30 | TabWidth: 2 31 | UseTab: Never 32 | 33 | PenaltyExcessCharacter: 1000000 34 | PenaltyReturnTypeOnItsOwnLine: 100 35 | PenaltyBreakBeforeFirstCallParameter: 10000 36 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | # Note: there must be no spaces before the '-', so put the comma first. 3 | Checks: ' 4 | * 5 | ,-google-runtime-references 6 | ,-llvm-namespace-comment 7 | ,-google-readability-namespace-comments 8 | ,-readability-braces-around-statements 9 | ,-readability-implicit-bool-cast 10 | ,-cppcoreguidelines-pro-bounds-array-to-pointer-decay 11 | ,-llvm-include-order 12 | ,-readability-named-parameter 13 | ' # End Checks 14 | 15 | WarningsAsErrors: '' 16 | HeaderFilterRegex: 'include/clang-expand/.*' 17 | ... 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Own 2 | *.dSYM 3 | build/ 4 | .clang_complete 5 | docs/html/ 6 | bin/ 7 | 8 | # Created by https://www.gitignore.io/api/c++,emacs 9 | 10 | ### C++ ### 11 | # Prerequisites 12 | *.d 13 | 14 | # Compiled Object files 15 | *.slo 16 | *.lo 17 | *.o 18 | *.obj 19 | 20 | # Precompiled Headers 21 | *.gch 22 | *.pch 23 | 24 | # Compiled Dynamic libraries 25 | *.so 26 | *.dylib 27 | *.dll 28 | 29 | # Fortran module files 30 | *.mod 31 | *.smod 32 | 33 | # Compiled Static libraries 34 | *.lai 35 | *.la 36 | *.a 37 | *.lib 38 | 39 | # Executables 40 | *.exe 41 | *.out 42 | *.app 43 | 44 | ### Emacs ### 45 | # -*- mode: gitignore; -*- 46 | *~ 47 | \#*\# 48 | /.emacs.desktop 49 | /.emacs.desktop.lock 50 | *.elc 51 | auto-save-list 52 | tramp 53 | .\#* 54 | 55 | # Org-mode 56 | .org-id-locations 57 | *_archive 58 | 59 | # flymake-mode 60 | *_flymake.* 61 | 62 | # eshell files 63 | /eshell/history 64 | /eshell/lastdir 65 | 66 | # elpa packages 67 | /elpa/ 68 | 69 | # reftex files 70 | *.rel 71 | 72 | # AUCTeX auto folder 73 | /auto/ 74 | 75 | # cask packages 76 | .cask/ 77 | dist/ 78 | 79 | # Flycheck 80 | flycheck_*.el 81 | 82 | # server auth directory 83 | /server/ 84 | 85 | # projectiles files 86 | .projectile 87 | 88 | # directory configuration 89 | .dir-locals.el 90 | 91 | # End of https://www.gitignore.io/api/c++,emacs 92 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ########################################################### 2 | ## CMAKE SETUP 3 | ########################################################### 4 | 5 | cmake_minimum_required(VERSION 3.5) 6 | project(clang-expand) 7 | 8 | ########################################################### 9 | ## DOCUMENTATION 10 | ########################################################### 11 | 12 | # Add a target to generate documentation with Doxygen. 13 | find_package(Doxygen) 14 | if(DOXYGEN_FOUND) 15 | # Replace all variables of the form @@ inside the Doxyfile 16 | configure_file( 17 | ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile 18 | ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY 19 | ) 20 | add_custom_target( 21 | docs 22 | ${DOXYGEN_EXECUTABLE} 23 | ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 24 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/docs 25 | COMMENT "Generating API documentation with Doxygen" VERBATIM 26 | ) 27 | endif() 28 | 29 | ########################################################### 30 | ## DEPENDENCIES 31 | ########################################################### 32 | 33 | set(CMAKE_MODULE_PATH 34 | ${CMAKE_MODULE_PATH} 35 | "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/") 36 | 37 | set(CLANG_LIBS 38 | clangAST 39 | clangASTMatchers 40 | clangAnalysis 41 | clangBasic 42 | clangDriver 43 | clangEdit 44 | clangFrontend 45 | clangFrontendTool 46 | clangLex 47 | clangParse 48 | clangSema 49 | clangEdit 50 | clangRewrite 51 | clangRewriteFrontend 52 | clangSerialization 53 | clangTooling 54 | clangToolingCore 55 | ) 56 | 57 | if (NOT CMAKE_HOST_APPLE) 58 | set(CLANG_LIBS -Wl,--start-group ${CLANG_LIBS} -Wl,--end-group) 59 | endif() 60 | 61 | find_package(LLVM REQUIRED) 62 | 63 | include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) 64 | include_directories(SYSTEM ${CLANG_INCLUDE_DIRS}) 65 | 66 | # Third Party 67 | include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}) 68 | 69 | # Also contains clang libraries 70 | link_directories(${LLVM_LIBRARY_DIRS}) 71 | set(CMAKE_EXE_LINKER_FLAGS ${LLVM_LD_FLAGS_STRING}) 72 | 73 | ########################################################### 74 | ## COMPILER FLAGS 75 | ########################################################### 76 | 77 | set(CXX_STANDARD_REQUIRED ON) 78 | 79 | list(REMOVE_ITEM LLVM_CXX_FLAGS 80 | ${LLVM_INCLUDE_DIRS} # Already included 81 | "-DNDEBUG" 82 | "-std=c++11" # Want our own standard 83 | "-std=c++1y" 84 | "-stdlib=libc++" 85 | "-fno-rtti-DLLVM_BUILD_GLOBAL_ISEL" # Weird bugs on Debian 86 | "-fdata-sections-O3" 87 | "-fdata-sections-O2") 88 | 89 | if (NOT ${CMAKE_CXX_COMPILER} MATCHES "clang.*") 90 | # These seem to be clang-specific 91 | list(REMOVE_ITEM LLVM_CXX_FLAGS 92 | "-Wcovered-switch-default" 93 | "-Wstring-conversion") 94 | endif() 95 | 96 | set(EXTRA_FLAGS 97 | -Os 98 | -O3 99 | -fdata-sections 100 | -std=c++14 101 | -fno-rtti 102 | -DLLVM_BUILD_GLOBAL_ISEL 103 | -DJSON_NOEXCEPTION) 104 | set(ALL_FLAGS ${WARNINGS} ${LLVM_CXX_FLAGS} ${EXTRA_FLAGS}) 105 | 106 | add_compile_options(${ALL_FLAGS}) 107 | 108 | ########################################################### 109 | ## INCLUDES 110 | ########################################################### 111 | 112 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) 113 | 114 | ########################################################### 115 | ## SOURCES 116 | ########################################################### 117 | 118 | add_subdirectory(source) 119 | 120 | ########################################################### 121 | ## TARGETS 122 | ########################################################### 123 | 124 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY 125 | ${CMAKE_BINARY_DIR}/bin/${CLANG_EXPAND_OS_NAME}) 126 | message(STATUS "Binaries will land in ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") 127 | 128 | add_executable(clang-expand clang-expand.cpp) 129 | target_link_libraries(clang-expand 130 | clang-expand-library 131 | ${CLANG_LIBS} 132 | ${LLVM_LIBS}) 133 | 134 | ########################################################### 135 | ## DOCKER 136 | ########################################################### 137 | 138 | find_program(DOCKER_COMPOSE NAMES docker-compose) 139 | if (DOCKER_COMPOSE) 140 | message(STATUS "Found docker-compose at ${DOCKER_COMPOSE}") 141 | add_custom_target( 142 | docker 143 | COMMAND docker-compose up 144 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ 145 | COMMENT "Building clang-expand with docker" VERBATIM 146 | ) 147 | message(STATUS "Enabled 'docker' target for building binaries") 148 | endif() 149 | 150 | ########################################################### 151 | ## TOOLS <3 152 | ########################################################### 153 | 154 | # IWYU 155 | option(CLANG_EXPAND_IWYU OFF) 156 | 157 | if(${CLANG_EXPAND_IWYU}) 158 | find_program(iwyu_path NAMES include-what-you-use iwyu) 159 | if(iwyu_path) 160 | message(STATUS "Found include-what-you-use, integrating with target") 161 | set_property(TARGET clang-expand 162 | PROPERTY CXX_INCLUDE_WHAT_YOU_USE ${iwyu_path}) 163 | else() 164 | message(WARNING "Could not find include-what-you-use, skipping") 165 | endif() 166 | endif() 167 | -------------------------------------------------------------------------------- /CPPLINT.cfg: -------------------------------------------------------------------------------- 1 | # cpplint configuration 2 | 3 | filter=-build/include_order 4 | filter=-build/c++11 5 | filter=-legal/copyright 6 | filter=-runtime/references 7 | filter=-whitespace/operators 8 | filter=-whitespace/line_length 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2017 Peter Goldsborough 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | the Software, and to permit persons to whom the Software is furnished to do so, 9 | subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # :dragon: clang-expand 2 | 3 |

4 | 5 |

6 | A clang tool for happy refactoring without source-code gymnastics. 7 |

8 | license Docker Pulls Github All Releases GitHub release 9 |

10 | 11 | ## Overview 12 | 13 | I recently overheard the following conversation on my way to work, that may seem familiar to you: 14 | 15 | > __Gandalf__: It is important to refactor your code and keep functions concise and coherent. 16 | > __Harry Potter__: Yeah, sure, but I hate having to jump around between files to get the full picture of what my code is doing. One function = one place to look. 17 | > __Obi Wan Kenobi__: Use the force, Harry. 18 | > __Batman__: He means *clang-expand* :sparkles: 19 | 20 | Inspired by Gandalf's words, I set out to find a solution to Harry's problem and 21 | built *clang-expand*. Point it at a function invocation in your source code and 22 | tell it where to look for stuff, and it will find the correct definition of that 23 | particular (template) function, method, operator overload or even constructor 24 | and "expand" it into the current scope. *Expanding* means it will: 25 | 26 | 1. Replace parameters with respective argument expressions. That is, for a 27 | function `f(int x)` that you call with `f(5)`, clang-expand will rewrite every 28 | occurrence of `x` inside `f` to `5`. Note that since clang-expand uses clang, it 29 | actually understands C++ and knows what occurrences of `x` are parameter 30 | references and what aren't. Default arguments are replaced as well. 31 | 32 |

33 | 34 | 35 | 45 | 46 | 47 | 52 | 60 | 61 |
Given
 36 | template<typename Range>
 37 | void magic(Range& range, int meaning_of_life = 42) {
 38 |   auto iterator = std::find(range.begin(), range.end(), meaning_of_life);
 39 |   if (iterator != range.end()) {
 40 |     range.erase(iterator);
 41 |     std::cout << "Successfully erased all meaning of life\n";
 42 |   }
 43 | }
 44 | 
UnexpandedExpanded
 48 | std::vector v = {1, 42, 3};                                        
 49 | magic(v);
 50 | ^
 51 | 
 53 | std::vector v = {1, 42, 3};
 54 | auto iterator = std::find(v.begin(), v.end(), 42);
 55 | if (iterator != v.end()) {
 56 |   std::cout << "Successfully erased all meaning of life\n";
 57 |   v.erase(iterator);
 58 | }
 59 | 
62 |

63 | 64 | As you can see, clang-expand actually instantiated the template function during 65 | the expansion. This is because on the level that it operates on within the clang 66 | AST, semantic analysis, including template type deduction, are already complete. 67 | This means that calling templates is not a problem for clang-expand. 68 | 69 | 2. If you're assigning the return value of a function you expand to a 70 | variable, clang-expand will replace every `return` statement inside the function 71 | with an assignment. It attempts to do this in a reasonably intelligent way, 72 | constructing the variable with the return value directly if there is only one 73 | `return` and else first declaring the variable and then assigning. The latter 74 | only works if the type of the variable is default-constructible and clang-expand 75 | will refuse to expand otherwise. 76 | 77 | 78 | 79 | 92 | 93 | 94 | 98 | 101 | 102 | 103 | 104 | 108 | 116 | 117 |
Given
 80 | std::string concat(const std::string& first, const std::string& second) {
 81 |   return first + "-"s + second;
 82 | }
 83 | 
84 | std::string concat(const std::string& first, const std::string& second, bool kebab) { 85 | if (kebab) { 86 | return first + "-"s + second; 87 | } else { 88 | return first + std::toupper(second.front(), {}) + second.substr(1); 89 | } 90 | } 91 |
UnexpandedExpanded
 95 | auto kebab = concat("clang", "expand");
 96 |              ^
 97 | 
 99 | std::string kebab = "clang" + "-"s + "expand";
100 | 
UnexpandedExpanded
105 | auto maybeCamel = concat("clang", "expand", flipCoin());
106 |                   ^
107 | 
109 | std::string maybeCamel;
110 | if (flipCoin()) {
111 |   maybeCamel = "clang" + "-"s + "expand";
112 | } else {
113 |   maybeCamel = "clang" + std::toupper("expand".front(), {}) + "expand".substr(1);
114 | }
115 | 
118 | 119 | 3. If you're calling a method, clang-expand will prepend the base to every method or member of referenced inside: 120 | 121 | 122 | 123 | 124 | 129 | 143 | 144 |
UnexpandedExpanded1
125 | std::vector my_vec;                                       
126 | my_vec.emplace_back(42);
127 |        ^
128 | 
130 | std::vector my_vec;                                       
131 | if (my_vec.__end_ < my_vec.__end_cap())
132 | {
133 |     __RAII_IncreaseAnnotator __annotator(*this);
134 |     __alloc_traits::construct(my_vec.__alloc(),
135 |                               _VSTD::__to_raw_pointer(my_vec.__end_),
136 |                               _VSTD::forward<_Args>(42)...);
137 |     __annotator.__done();
138 |     ++my_vec.__end_;
139 | }
140 | else
141 |     my_vec.__emplace_back_slow_path(_VSTD::forward<_Args>(42)...);
142 | 
145 | 146 | 1 *This is the implementation on my system, of course.* 147 | 148 | 4. If the function you're expanding is an operator, clang-expand can handle that just as well: 149 | 150 | 151 | 152 | 160 | 161 | 162 | 168 | 173 | 174 |
Given
153 | struct by_lightning {
154 |   bool operator==(const by_lightning& other) const noexcept {
155 |     return this->circuit == other.circuit;
156 |   }
157 |   short circuit;
158 | };
159 | 
UnexpandedExpanded
163 | by_lightning first{1};                                          
164 | by_lightning second{2};
165 | return first == second;
166 |              ^
167 | 
169 | by_lightning first{1};                                         
170 | by_lightning second{2};
171 | return first.circuit == other.circuit;
172 | 
175 | 176 | 5. Besides expanding functions that are real code, clang-expand can also expand 177 | function-like and *even object-like* macros (that just `#define` something 178 | without being parameterized): 179 | 180 | 181 | 182 | 186 | 187 | 188 | 199 | 208 | 209 |
Given
183 | #define MAX(a, b) (a) > (b) ? (a) : (b)
184 | #define PI 3.14
185 | 
UnexpandedExpanded
189 | double pi_if_a_greater_b(double a, double b) {                 
190 |   auto greater = MAX(a, b);
191 |                  ^
192 |   if (greater == a) {
193 |     return PI;
194 |            ^
195 |   }
196 |   return -1;
197 | }
198 | 
200 | double pi_if_a_greater_b(double a, double b) {                         
201 |   auto greater = a > b ? a : b;
202 |   if (greater == a) {
203 |     return 3.14;
204 |   }
205 |   return -1;
206 | }
207 | 
210 | 211 | 6. clang-expand not only performs substitution for function parameters, it can also substitute type and non-type template parameters! Voilà: 212 | 213 | 214 | 215 | 222 | 223 | 224 | 228 | 232 | 233 |
Given
216 | template <typename Explicit, unsigned number, typename Deduced>
217 | auto my_template(Deduced deduced) {
218 |   using Alias = Explicit;
219 |   return deduced + static_cast<Alias>(number);
220 | }
221 | 
UnexpandedExpanded
225 | my_template<float, 24>(10);                                     
226 | ^
227 | 
229 | using Alias = float;
230 | return 10 + static_cast<Alias>(24);                            
231 | 
234 | 235 | ## Usage 236 | 237 | clang-expand is implemented as a command-line tool targeted at building editor integrations. The tool itself has the following help text (excerpt): 238 | 239 | ``` 240 | $ clang-expand -help 241 | USAGE: clang-expand [options] [... ] 242 | 243 | OPTIONS: 244 | 245 | clang-expand options: 246 | 247 | -call - Whether to return the source range of the call 248 | -column= - The column number of the function to expand 249 | -declaration - Whether to return the original declaration 250 | -definition - Whether to return the original definition 251 | -file= - The source file of the function to expand 252 | -line= - The line number of the function to expand 253 | -rewrite - Whether to generate the rewritten (expanded) definition 254 | ``` 255 | 256 | Basically, you have to pass it any sources you want the tool to look for 257 | definitions in as positional arguments. The `-file`, `-line` and `-column` 258 | options then determine the location of the call to expand. This position has to 259 | be somewhere on the token you want to expand (i.e. not necessarily at the 260 | beginning). The `-file` defaults to the first source if you omit the option. 261 | Additionally, you have to pass any options required to compile the files at the 262 | end, following `--`. For example, given: 263 | 264 | `foo.h`: 265 | ```cpp 266 | int foo(); 267 | ``` 268 | 269 | `foo.cpp`: 270 | ```cpp 271 | int foo() { return 42; } 272 | ``` 273 | 274 | `main.cpp`: 275 | ```cpp 276 | #include "foo.h" 277 | auto main() -> int { 278 | auto x = foo(); 279 | } 280 | ``` 281 | 282 | The following command would do the job: 283 | 284 | ```bash 285 | $ clang-expand main.cpp foo.cpp -line=3 -column=14 -- -I/path/to/include -std=c++14 286 | ``` 287 | 288 | which will output: 289 | 290 | ```json 291 | { 292 | "call": { 293 | "begin": { 294 | "column": 3, 295 | "line": 3 296 | }, 297 | "end": { 298 | "column": 17, 299 | "line": 3 300 | } 301 | }, 302 | "declaration": { 303 | "location": { 304 | "filename": "/path/to/foo.h", 305 | "offset": { 306 | "column": 5, 307 | "line": 1 308 | } 309 | }, 310 | "name": "foo", 311 | "text": "int foo();" 312 | }, 313 | "definition": { 314 | "location": { 315 | "filename": "/path/to/foo.cpp", 316 | "offset": { 317 | "column": 5, 318 | "line": 1 319 | } 320 | }, 321 | "macro": false, 322 | "rewritten": "int x = 42;", 323 | "text": "int foo() { return 42; }" 324 | } 325 | } 326 | ``` 327 | 328 | Yes, JSON! But why so much output? Well, since clang-expand has to find the 329 | declaration and definition of a function you want to expand, it might as well 330 | also return the location and full text for either (because why not). As such, 331 | clang-expand can also be used as a backend for 332 | "go-to-definition"/"show-declaration" functions inside a text editor (though an 333 | indexed-solution like [ctags](https://en.wikipedia.org/wiki/Ctags) is likely 334 | faster for just that). 335 | 336 | For expanding, what's most interesting here is the `call` section and the 337 | `definition.rewritten` field. The former is the entire range (defined by two 338 | `(line, column)` pairs) in the source code that you'll want to replace with the 339 | expansion. The latter is the text to insert instead. 340 | 341 | Even though the overhead to grab information about the definition and 342 | declaration is negligible compared to the entire operation, it may still be 343 | beneficial to turn off retrieval of certain parts of what clang-expand outputs, 344 | or you may simply not need some of the output. This is the case when you're only 345 | interested in expanding for example, where you only need the `call` and 346 | `definition` section. For this reason, the clang-expand tool takes boolean 347 | `-call, -declaration, -definition` and `-rewrite` options. By default, these 348 | flags are all set to `true`, i.e. all of these sections will be included. By 349 | setting them to `-