[cfe-dev] Range of getTypeSourceInfo for VarDecl

Alex Horn alex.horn at cs.ox.ac.uk
Thu Jul 3 07:52:23 PDT 2014


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").

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);

  const LangOptions& LO = Result.Context->getLangOpts();

  Replace.insert(tooling::Replacement(SM, Range.getBegin(), 0, "Bar<"));
  Replace.insert(tooling::Replacement(SM, Range.getEnd(), 0, ">"));

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



More information about the cfe-dev mailing list