Question about writing a refactoring tool

I’m interested in writing a simple refactor that will find all uses of a symbol Foo and replace it with either true or false, then simplify the conditional constructs in which they appeared. For example, if I have some code:

if (!Foo)
// Do thing A
// Do thing B

And I run the tool to replace Foo with True, I would expect my refactor to transform the above block into:

// Do thing B

Similarly, if the code was:

if (Foo || Bar)
// Do thing

and I replace Foo with true, I would expect it to transform the code into:

if (Bar)
// Do thing

I’ve got a simple refactoring command integrated into clang-refactor, but it currently doesn’t do anything other than appear in the --help output. I’ve got a couple of questions:

  1. What is the difference between clang-tidy and clang-refactor? Conceptually I get it, clang-refactor is for “larger” stuff, but why? What about clang-refactor makes it more suitable for large refactors? I’m already a little familiar with the ASTMatcher interface, and it seems like clang-refactor doesn’t make use of it, so using clang-refactor I’m sort of at ground 0 with very few examples to go off of, whereas if I were using clang-tidy I would be able to make faster progress because I’m already a little familiar with it.

  2. What does USR mean? I see references to this acronym all over the place in the implementation of the local-rename command, but it’s not explained anywhere.

  3. Does the refactoring tooling in general contain sufficient information for me be able to accomplish the specific refactor I’m looking into? And are there any other examples of refactors people have written besides local-rename and extract?

Hi Zachary,

To get started, you can probably ignore clang-refactor. Internally it
uses the same/similar API as clang-tidy, but the later has much more
material available.

For example, I found as a
great overview; after that, you can just use clang-query / API docs to
figure out the details. That all talks about clang-tidy.



+1 You can pro-actively run clang-tidy over your code base and apply the edits to get the result you want. That is, it’s not just for giving diagnostics, suggestions, etc. in an IDE setting.

As for sophistication – yes, clang-tidy and clang Tooling more generally have been used for very sophisticated edits. To get a sense, I’d recommend looking at the clang-tidy check tests. They are lit tests, so essentially each test is example code with the expected fixes:

A possibly-relevant example:

and it’s corresponding code:

You might also find the Clang Transformer is an easier interface to writing the refactoring. You can find that here:

And it ties into clang-tidy here:

For example,

If you find you’re interested in clang-transformer, please let me know and I can send along a tutorial which I’m working on but haven’t yet published upstream.