[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