[cfe-dev] Check if a location comes from begin/end of macro argument expansion

Argyrios Kyrtzidis kyrtzidis at apple.com
Mon Oct 15 10:19:37 PDT 2012


On Oct 13, 2012, at 6:32 AM, Abramo Bagnara <abramo.bagnara at bugseng.com> wrote:

> Il 11/10/2012 20:35, Argyrios Kyrtzidis ha scritto:
>> Hi Abramo,
>> 
>> On Oct 10, 2012, at 2:36 PM, Abramo Bagnara <abramo.bagnara at bugseng.com> wrote:
>> 
>>> 
>>> I'm struggling to find a way to detect if a given macro expanded
>>> location is at the begin (or the end) of a macro argument expansion.
>>> 
>>> e.g. in this program
>>> 
>>> #define M(z) 0 + z + 0
>>> #define N(x) M((x))
>>> void h() {
>>> N(1);
>>> }
>>> 
>>> I'd need to detect that source location of integer literal 1 is at the
>>> begin (and the end) of expansion of argument x of macro N.
>>> 
>>> I think we should have enough info to do that (I've been able to reach a
>>> similar result concerning macro expansion begin/end), but I'm still
>>> unable to achieve always the correct final result.
>> 
>> This is not simple/easy to do currently.
>> 
>> I think you can take advantage of the fact that the spelling location of a macro function expansion will always contain the parens, e.g. you'll be able to lex "MACRONAME ( .... )" (similar to how Preprocessor::ReadFunctionLikeMacroArgs does it) and get the token locations between the parens.
>> In your example you'll get the token locations for:
>> 'N' '(' '1' ')'   
>> and
>> 'M' '(' '(' 'x' ')' ')'
>> 
>> you'll be able to lex the spelling locations and apply the offsets to the the actual locations in the expanded range of the macro contents.
>> After that you should be able to figure out if the location of '1' came from what token location inside the macro arguments. Also a bonus advantage will be being able to determine which exactly argument index it came from.
>> 
>> Did this make sense ?
>> 
> 
> Perhaps I've found a simpler solution: looking for consecutive SLocEntry
> for the same macro argument expansion (I can detect if they come from
> the same macro argument expansion using immediate expansion start
> location) I can know the range of expanded argument.
> 
> This is a dump of macro related SLocEntry (@ is an abbreviation for the
> some big number prefix).
> 
> #define M(z) z
> #define N(x) M((x))
> void h() {
>  N(M(1)+M(2));
> }
> 
> 4: macro @637- at 643 exp:50-61 sloc:30 text:M((x))  N
> 5: macro @644- at 645 exp:52-55 sloc:15 text:z       M1
> 6: arg @646- at 647 exp:@644- at 644 sloc:54 text:1)    M1.z
> 7: macro @648- at 649 exp:57-60 sloc:15 text:z       M2
> 8: arg @650- at 651 exp:@648- at 648 sloc:59 text:2)    M2.z
> 9: arg @652- at 653 exp:@640- at 640 sloc:@646 text:1)  N.x
> 10: arg @654- at 655 exp:@640- at 640 sloc:56 text:+M   N.x
> 11: arg @656- at 657 exp:@640- at 640 sloc:@650 text:2) N.x
> 12: macro @658- at 659 exp:@637- at 642 sloc:15 text:z  M
> 13: arg @660- at 678 exp:@658- at 658 sloc:@639 text:(x))|z|1)|z|2)|1)|+M|2) M.z
> 14: arg @679- at 680 exp:@658- at 658 sloc:@641 text:)) M.z
> 
> @660 @673 @675 @677 @679
>  (    1    +    2    )
> 
> From the SLocEntries above we can known that N.x expansion location
> ranges is from @652 to @657, while M.z is from @660 to @680.
> 
> This might work? What do you think about?

Yes, I think this should work.

> 
> -- 
> Abramo Bagnara
> 
> BUGSENG srl - http://bugseng.com
> mailto:abramo.bagnara at bugseng.com




More information about the cfe-dev mailing list