<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Jul 3, 2014 at 4:52 PM, Alex Horn <span dir="ltr"><<a href="mailto:alex.horn@cs.ox.ac.uk" target="_blank">alex.horn@cs.ox.ac.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hello,<br>
<br>
I'd like to rewrite a variable declaration such as "unsigned int x" to<br>
"BAR<unsigned int> x". For this, I've had a peak at the auto rewriter<br>
and I managed to get the simpler case "int x" to work just fine. But<br>
for types such as "unsigned int x" it won't work (it will rewrite to<br>
"BAR<unsigned> int x").<br></blockquote><div><br></div><div>This looks like it might be the old "token vs. location" problem (source ranges point to tokens, and if given a token, the Replacement assumes "start of token"). Usually you need to say Lexer::MeasureTokenLength to get past the end of the token. See <a href="http://reviews.llvm.org/diffusion/L/browse/cfe/trunk/lib/Tooling/Refactoring.cpp;212403$125">http://reviews.llvm.org/diffusion/L/browse/cfe/trunk/lib/Tooling/Refactoring.cpp;212403$125</a> for how it's used. Or you go forward to find the next token (either with the lexer, or by pulling out the first vardecl).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
The current code looks as follows where Result is of type<br>
MatchFinder::MatchResult:<br>
<br>
const VarDecl *V = ...<br>
SourceLocation Loc = V->getLocation();<br>
SourceManager &SM = *Result.SourceManager;<br>
TypeLoc TL = V->getTypeSourceInfo()->getTypeLoc();<br>
<br>
// Likely problematic ...<br>
SourceRange SR = TL.getSourceRange();<br>
CharSourceRange Range = Lexer::makeFileCharRange(<br>
CharSourceRange::getTokenRange(SR), SM, LO); </blockquote><div><br></div><div>Why do you need the lexer? Won't CharSourceRange::getTokenRange(SR) do what you want?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
const LangOptions& LO = Result.Context->getLangOpts();<br>
<br>
Replace.insert(tooling::Replacement(SM, Range.getBegin(), 0, "Bar<"));<br>
Replace.insert(tooling::Replacement(SM, Range.getEnd(), 0, ">"));<br></blockquote><div><br></div><div>Otherwise this looks about right.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
As indicated, the problem has likely to do with a wrong assumption<br>
about the lexemes. I've tried various things to avoid the Lexer<br>
including using V->getSourceRange() and V->getType().getAsString()<br>
instead. This works OK for cases like "int x" and the seemingly more<br>
complicated case "unsigned int x" but it breaks for declarations with<br>
initializers, e.g. "unsigned int x = 42".<br>
<br>
It almost would seem as if it is preferable to use<br>
V->getType().getAsString() to handle cases such as "int y[5]" which<br>
should be rewritten to "BAR<int [5]> y". But I would be already happy<br>
if I would get the "unsigned int x" case to work before considering<br>
more complicated cases.<br>
<br>
Any hints on how one might go about rewriting these kind of variable<br>
declarations would be much appreciated.<br>
<br>
With kind regards,<br>
Alex<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></div></div>