[cfe-dev] Help with replacements on macros

scott constable via cfe-dev cfe-dev at lists.llvm.org
Wed Jun 29 22:02:14 PDT 2016


Hi All,

I have an AST matcher which has successfully matched all "if" statements in
a large program:

StatementMatcher CondMatcher =
ifStmt(hasCondition(expr().bind("condition")));

My goal is to use libtooling replacements to refactor all "if" conditions
<cond> into my_func(<cond>). For instance,

if (true) { ... }

should refactor to

if (my_func(true)) { ... }

The only time I run into trouble is when I try to refactor complex macros.
For instance, take the following code:

#define GUARD2 GUARD1(999)
#define GUARD1(X) if (1 | X) { return 11; }

int main() {
  GUARD2
  return 0;
}

My AST matcher successfully grabs the expanded if statement's condition. To
perform my replacement, I would like to obtain the following source
locations:

#define GUARD2 GUARD1(999)
#define GUARD1(X) if (<LBegin>1 | X<LEnd>) { return 11; }

int main() {
  GUARD2
  return 0;
}

but if I do something like

SourceLocation LBegin =
MySourceManager.getSpellingLoc(Condition->getBeginLoc());
SourceLocation LEnd =
MySourceManager.getSpellingLoc(Condition->getEndLoc());
LEnd = Lexer::getLocForEndOfToken(LEnd, 0, MySourceManager, opts);

then the source locations are as follows:

#define GUARD2 GUARD1(999<LEnd>)
#define GUARD1(X) if (<LBegin>1 | X) { return 11; }

int main() {
  GUARD2
  return 0;
}

And thus the replacements turn out as

1 #define GUARD2 GUARD1(999))
2 #define GUARD1(X) if (my_func(1 | X) { return 11; }
3
4 int main() {
5   GUARD2
6   return 0;
7 }

which is incorrect. Note the extra parenthesis in line 1, and missing
parenthesis in line 2. Any help at all would be very much appreciated.

Thanks in advance,

Scott Constable
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160629/4dec5198/attachment.html>


More information about the cfe-dev mailing list