<div style="font-family: arial, helvetica, sans-serif"><font size="2">Hi Philip,<br><br><div class="gmail_quote">On Sun, Jun 24, 2012 at 4:53 PM, Philip Dunstan <span dir="ltr"><<a href="mailto:phil@philipdunstan.com" target="_blank">phil@philipdunstan.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
I've been trying some source to source transformations using the<br>
matcher/callback framework in the tooling branch. They are mostly working<br>
but I have a couple of questions and would like some feedback on whether I<br>
am doing everything as intended. Will you please help me?<br>
<br>
There are two transformations I am trying to make: adding the override<br>
keyword to virtual functions where we can and replacing shared_ptr by<br>
value function parameters with const references. I have attached the two<br>
cpp files to this post. They are also available from<br>
<a href="https://bitbucket.org/phildunstan/clang_tools/src/5d63a291d377/add-override-specifier" target="_blank">https://bitbucket.org/phildunstan/clang_tools/src/5d63a291d377/add-override-specifier</a><br>
<a href="https://bitbucket.org/phildunstan/clang_tools/src/5d63a291d377/replace-shared_ptr-parameters" target="_blank">https://bitbucket.org/phildunstan/clang_tools/src/5d63a291d377/replace-shared_ptr-parameters</a><br>
<br>
<br>
add-override-specifier.cpp<br>
Adds the override specifier to functions that override virtual<br>
functions from a base class and don't already have the override specifier.<br>
<br>
I have written the following matcher to find candidates functions.<br>
AST_MATCHER(clang::CXXMethodDecl, IsOverrideMissing)<br>
{<br>
// does this virtual function override a virtual function from<br>
a base class<br>
return (Node.isVirtual() && (Node.size_overridden_methods() ><br>
0) && !Node.hasAttr<OverrideAttr>());<br>
}<br>
<br>
In my callback however I don't know how to find the right source location<br>
to insert the override keyword. If there is no body I can use the end of<br>
the function declaration. However if there is a body I don't know how to<br>
get the end of the declaration section before the body. For example in the<br>
following example I want to insert the keyword before the comment. How do I<br>
get the source location of this point?<br>
void f() const // overrides a base class virtual function<br>
{<br>
}<br></blockquote><div><br></div><div>You could put the attribute to the location of the function's body (FunctionDecl::getBody()->getLocStart()). This only works if the function has a body but would be very similar to the end of a body-less FunctionDecl. It does not play nicely with code styles where you put the open brace on a new line, though. You could move back one character (SourceLocation::getLocWithOffset(-1)). That would effectively not add the attribute if you have trailing single line comments like the one above. It might be possible to use Lexer::GetBeginningOfToken() on to move to the front of such a single-line comment, but that would need some experimenting.</div>
<div><br></div><div>It might be preferable to know the end of the function's parameter list (or the location of both parenthesis), but I think this information is currently not stored in the AST and cannot be easily calculated for functions without parameters :-(. We could open a bug for this.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
replace-shared_ptr-parameters.cpp<br>
Replace function parameters that specify a shared_ptr instance by<br>
value with shared_ptr by const reference.<br>
<br>
Should I be changing the type from shared_ptr<X> to const shared_ptr<X>& or<br>
is there a way to do this by modifying the AST to make the parameter const<br>
and by reference and then re-emit the source?<br>
<br>
I have this working for normal functions, methods and template functions<br>
where instantiations of that template exist. What type of matcher should I<br>
write to match a template function that doesn't have an instantiation.<br>
eg template <typename T> f(shared_ptr<T>);<br>
<br>
<br>
Additional Questions:<br>
<br>
It appears that I need to specify all of the system c++ include files when<br>
I run the tool on a file, but I don't need to provide them when I compile<br>
the with the clang compiler that I have built from the tooling branch. Is<br>
this expected behavior?<br>
replace-shared_ptr-parameters input.cpp -- -std=c++11 -Wall -g -O0<br>
-I/usr/include/c++/4.6 -I/usr/include/c++/4.6/x86_64-linux-gnu<br>
-I/usr/include/c++/4.6/backward -I/usr/lib/gcc/x86_64-linux-gnu/4.6/include<br>
-I/usr/local/include -I/usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed<br>
-I/usr/include/x86_64-linux-gnu -I/usr/include<br>
<br>
I'd like to run these tools over our complete code base where the changes<br>
will affect both header and source files. What is the recommended way to<br>
limit changes to only my files and not system header files? I expect I can<br>
limit them to the main file specified by the source manager, however I<br>
assume that this would prevent changes to my header files.<br>
<br>
How do I prevent a change from being made multiple times while in the same<br>
translation unit compilation? eg as a result of template or macro<br>
instantiations or multiple header includes. Is there a recommended way to<br>
solve this or is it up to the callback to be safe in the case that it is<br>
run twice on the same piece of code?<br>
<br>
<br>
Thanks for the excellent work you guys are doing,<br>
Phil<br>
--<br>
Philip Dunstan<br>
<a href="mailto:phil@philipdunstan.com">phil@philipdunstan.com</a><br>
<a href="http://www.philipdunstan.com" target="_blank">www.philipdunstan.com</a><br>
<br>
<br>
--<br>
View this message in context: <a href="http://clang-developers.42468.n3.nabble.com/Source-to-source-transformations-questions-in-branches-tooling-tp4024920.html" target="_blank">http://clang-developers.42468.n3.nabble.com/Source-to-source-transformations-questions-in-branches-tooling-tp4024920.html</a><br>
Sent from the Clang Developers mailing list archive at Nabble.com.<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
</blockquote></div><br></font></div>