[cfe-dev] Get full source of multiple macro definitions using libtooling

Manuel Klimek via cfe-dev cfe-dev at lists.llvm.org
Mon May 9 02:35:50 PDT 2016


On Fri, May 6, 2016 at 9:04 PM John Bartelme via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> Hopefully this is an acceptable list to ask a question about libtooling on:
>
> Ultimately I'm trying to pull out relevant structures from thousands of
> existing c and c++ header files. I've been able to use libtooling to pull
> out a structure and all of the structures/enums/typedefs etc it relies on
> from various different headers. Unfortunately when I get the source range
> backing the Decls it still references the macros defined there in. I'm
> currently trying to find a way to access and print the source of these
> macros but not having much luck when multiple macros are defined.
>
> For example:
>
> #define INT int
> #define UNSIGNED unsigned
> #define NAME name
>
> typedef struct {
>    UNSIGNED long INT NAME;
> } test;
>
> When I get the FieldDecl corresponding to name and get the SourceRange I
> see the spelling location pointing to "#define UNSIGNED unsigned".
>

With that you probably mean the spelling location of the start location? A
SourceRange doesn't have a spelling *location* :)


> I'd like to know how to get to the other macro definition's source
> locations. I know that when I change "UNSIGNED long INT NAME;" to "unsigned
> long INT NAME;" the spelling location will then point to "#define INT int".
>

Again, I'm not sure which location you're using.


> It seems as if declaration names are treated differently though as
> changing to "unsigned long int NAME;" leaves me with no spelling location.
>
> Is there a way to get multiple spelling locations given a SourceRange? Do
> I need to narrow down the source range some other way? I've tried lexing to
> the next token but the doesn't leave me with a new spelling location. I'm
> also going to have to account for macros in arrays such as "int
> bob[MAX_WIDTH][MAX_HEIGHT]" but I'm hoping once I figure out my issues here
> that will become clear. Thanks in advance for any help that can be
> provided.  john
>

All the info is in the SourceRange / SourceLocation; SourceLocation
actually provides all relevant instantiation points.
It depends on:
- which source location you're querying against; if you have the Decl, like
FieldDecl, generally getLocation() will get you the name (that is, the
spelling loc will point at 'name' and the expansion locs will point at the
#define NAME and the NAME; respectively).
- whether you really want a  range; for ranges, there's
Lexer::makeFileCharRange and Lexer::getSourceText for that
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160509/d9b786d9/attachment.html>


More information about the cfe-dev mailing list