...but that is still not working when macros are involved (getLocForEndOfToken(l) returns an invalid loc if l points into a macro expansion). What I want to do is remove the second (zero-valued) argument from all calls to f in
#define FOO "foo"
#define ZERO 0
f("foo", 0);
f(FOO, ZERO);
assert(f("foo", 0));
assert(f(FOO, ZERO));
(where "assert" is the std macro), i.e., end up with
#define FOO "foo"
#define ZERO 0
f("foo");
f(FOO);
assert(f("foo"));
assert(f(FOO));
But in the cases where the first argument uses the macro FOO,
getLocForEndOfToken(e->getArg(0)->getLocEnd())
would return an invalid loc, and
getLocForEndOfToken(SM.getSpellingLoc(e->getArg(0)->getLocEnd()))
would return the end of the
#define FOO "foo"
line. (And determining the end of the range to be removed, e->getArg(1)->getLocEnd(), has a similar problem if the second argument uses the macro ZERO.)
What I think I need is the location l1 of the punctuation ("," in this caes) preceeding the second argument and the location l2 of the punctuation (")" in this case) following it. Then, for each of the two lN, if spellN = SM.getSpellingLoc(lN) is contained in SM.getExpansionRange(lN), I (hope) it would be sound to drop the range from spell1 to before spell2. (This would miss cases like
#define COMMA ,
#define RPAREN )
f("foo" COMMA 0 RPAREN
but that's more acceptable for my use case than missing any of the cases given previously.) At least, that's my understanding so far (which might well be completely off track, though).
Input appreciated,
Stephan