[cfe-dev] Source to source transformations questions in branches/tooling

Philip Dunstan phil at philipdunstan.com
Sun Jun 24 07:53:40 PDT 2012


I've been trying some source to source transformations using the
matcher/callback framework in the tooling branch. They are mostly working
but I have a couple of questions and would like some feedback on whether I
am doing everything as intended. Will you please help me?

There are two transformations I am trying to make: adding the override
keyword to virtual functions where we can and replacing shared_ptr by
value function parameters with const references. I have attached the two
cpp files to this post. They are also available from

Adds the override specifier to functions that override virtual
functions from a base class and don't already have the override specifier.

I have written the following matcher to find candidates functions.
        AST_MATCHER(clang::CXXMethodDecl, IsOverrideMissing)
            // does this virtual function override a virtual function from
a base class
            return (Node.isVirtual() && (Node.size_overridden_methods() >
0) && !Node.hasAttr<OverrideAttr>());

In my callback however I don't know how to find the right source location
to insert the override keyword. If there is no body I can use the end of
the function declaration. However if there is a body I don't know how to
get the end of the declaration section before the body. For example in the
following example I want to insert the keyword before the comment. How do I
get the source location of this point?
        void f() const // overrides a base class virtual function

Replace function parameters that specify a shared_ptr instance by
value with shared_ptr by const reference.

Should I be changing the type from shared_ptr<X> to const shared_ptr<X>& or
is there a way to do this by modifying the AST to make the parameter const
and by reference and then re-emit the source?

I have this working for normal functions, methods and template functions
where instantiations of that template exist. What type of matcher should I
write  to match a template function that doesn't have an instantiation.
eg template <typename T> f(shared_ptr<T>);

Additional Questions:

It appears that I need to specify all of the system c++ include files when
I run the tool on a file, but I don't need to provide them when I compile
the with the clang compiler that I have built from the tooling branch. Is
this expected behavior?
replace-shared_ptr-parameters input.cpp -- -std=c++11 -Wall -g -O0
-I/usr/include/c++/4.6 -I/usr/include/c++/4.6/x86_64-linux-gnu
-I/usr/include/c++/4.6/backward -I/usr/lib/gcc/x86_64-linux-gnu/4.6/include
-I/usr/local/include -I/usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed
-I/usr/include/x86_64-linux-gnu -I/usr/include

I'd like to run these tools over our complete code base where the changes
will affect both header and source files. What is the recommended way to
limit changes to only my files and not system header files? I expect I can
limit them to the main file specified by the source manager, however I
assume that this would prevent changes to my header files.

How do I prevent a change from being made multiple times while in the same
translation unit compilation? eg as a result of template or macro
instantiations or multiple header includes. Is there a recommended way to
solve this or is it up to the callback to be safe in the case that it is
run twice on the same piece of code?

Thanks for the excellent work you guys are doing,
Philip Dunstan
phil at philipdunstan.com

View this message in context: http://clang-developers.42468.n3.nabble.com/Source-to-source-transformations-questions-in-branches-tooling-tp4024920.html
Sent from the Clang Developers mailing list archive at Nabble.com.

More information about the cfe-dev mailing list