<div style="font-family: arial, helvetica, sans-serif"><font size="2"><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>I'll leave answering that to Daniel. </div><div><br></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></blockquote><div><br></div><div>If you can match the location of the shared_ptr and the type, you can emit a replacement to "const X&" (no need to go through the AST here). Is there a part of the matching that's problematic?</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
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></blockquote><div><br></div><div>Ugh. Templates that are never instantiated anywhere are really hard to handle, as in your example all the types are dependent. -ast-dump-xml and friends also don't really help here. I'll put it on my list to write a tool that helps answer that kind of question.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
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></blockquote><div><br></div><div>Hm, this should work in principle. Can you add '-v' output to both the tool run and the clang run from your self-built clang compiler and attach them?</div>
<div><br></div><div>A different solution would be to use the CompilationDatabase. If your project uses cmake, it works out of the box; if not, the easiest thing is to create a compilation database. See the docs here:</div>
<div><a href="http://clang.llvm.org/docs/JSONCompilationDatabase.html">http://clang.llvm.org/docs/JSONCompilationDatabase.html</a></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<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></blockquote><div><br></div><div>I simply do match on the path / name of the files for that. Usually project files have easily detectable paths.</div><div>Also note that what I do is key whether I want to replace something on the file of the original declaration of the 'thing' I want to replace, so that you don't get inconsistent states.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
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></blockquote><div><br></div><div>That's what the refactoring support in the tooling library is for:</div><div><a href="http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Tooling/Refactoring.h?view=markup">http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Tooling/Refactoring.h?view=markup</a></div>
<div><br></div><div>The idea is that you run over all TUs you want to refactor in the same process. We're working on getting this multi-threaded so that it scales better.</div><div><br></div><div>Another possibility is to output simple diffs from your tool, and use a little python script to slurp in the changes, unique them and apply them (that's what we currently do for really large scale MapReduce style refactorings).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thanks for the excellent work you guys are doing,<br></blockquote><div><br></div><div>Thanks :)</div><div><br></div><div>/Manuel</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

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>