[cfe-dev] Using Rewriter to remove a function call argument along with preceding comma?
Stephan Bergmann
sbergman at redhat.com
Tue Jun 18 01:30:27 PDT 2013
On 06/11/2013 11:21 PM, Stephan Bergmann wrote:
> On 06/11/2013 11:13 PM, Argyrios Kyrtzidis wrote:
>> On Jun 11, 2013, at 1:34 PM, Stephan Bergmann <sbergman at redhat.com>
>> wrote:
>>> On 06/07/2013 08:19 PM, Argyrios Kyrtzidis wrote:
>>>> On Jun 7, 2013, at 5:31 AM, Stephan Bergmann <sbergman at redhat.com
>>>> <mailto:sbergman at redhat.com>> wrote:
>>>>> Anyway, what I want to do is a rewriting Clang plugin that removes one
>>>>> argument from specific function calls. But where I'm lost is how to
>>>>> determine the SourceLocation of the comma preceding the given
>>>>> argument, to do something like
>>>>
>>>> You could remove this range:
>>>>
>>>> [loc-for-end-of-token of end location of preceding argument, end
>>>> location of removed argument]
>>>
>>> Yeah, but how do I get that loc-for-end-of-token?
>>
>> See Lexer::getLocForEndOfToken() or
>> Preprocessor::getLocForEndOfToken() (the latter delegates to the former).
>
> Ah, that was the missing link.
...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
More information about the cfe-dev
mailing list