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

Abramo Bagnara abramo.bagnara at bugseng.com
Sat Oct 13 06:32:57 PDT 2012


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?

-- 
Abramo Bagnara

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



More information about the cfe-dev mailing list