[cfe-dev] Range of getTypeSourceInfo for VarDecl

Manuel Klimek klimek at google.com
Sun Jul 6 09:14:39 PDT 2014


On Thu, Jul 3, 2014 at 4:52 PM, Alex Horn <alex.horn at cs.ox.ac.uk> wrote:

> Hello,
>
> I'd like to rewrite a variable declaration such as "unsigned int x" to
> "BAR<unsigned int> x". For this, I've had a peak at the auto rewriter
> and I managed to get the simpler case "int x" to work just fine. But
> for types such as "unsigned int x" it won't work (it will rewrite to
> "BAR<unsigned> int x").
>

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
http://reviews.llvm.org/diffusion/L/browse/cfe/trunk/lib/Tooling/Refactoring.cpp;212403$125
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).


>
> The current code looks as follows where Result is of type
> MatchFinder::MatchResult:
>
>   const VarDecl *V = ...
>   SourceLocation Loc = V->getLocation();
>   SourceManager &SM = *Result.SourceManager;
>   TypeLoc TL = V->getTypeSourceInfo()->getTypeLoc();
>
>   // Likely problematic ...
>   SourceRange SR = TL.getSourceRange();
>   CharSourceRange Range = Lexer::makeFileCharRange(
>       CharSourceRange::getTokenRange(SR), SM, LO);


Why do you need the lexer? Won't CharSourceRange::getTokenRange(SR) do what
you want?


>   const LangOptions& LO = Result.Context->getLangOpts();
>
>   Replace.insert(tooling::Replacement(SM, Range.getBegin(), 0, "Bar<"));
>   Replace.insert(tooling::Replacement(SM, Range.getEnd(), 0, ">"));
>

Otherwise this looks about right.


>
> As indicated, the problem has likely to do with a wrong assumption
> about the lexemes. I've tried various things to avoid the Lexer
> including using V->getSourceRange() and  V->getType().getAsString()
> instead. This works OK for cases like "int x" and the seemingly more
> complicated case "unsigned int x" but it breaks for declarations with
> initializers, e.g.  "unsigned int x = 42".
>
> It almost would seem as if it is preferable to use
> V->getType().getAsString() to handle cases such as "int y[5]" which
> should be rewritten to "BAR<int [5]> y". But I would be already happy
> if I would get the "unsigned int x" case to work before considering
> more complicated cases.
>
> Any hints on how one might go about rewriting these kind of variable
> declarations would be much appreciated.
>
> With kind regards,
> Alex
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140706/d9c7148a/attachment.html>


More information about the cfe-dev mailing list