[cfe-dev] Determining macros used in a function or SourceRange (using clang plugin)

Alex L via cfe-dev cfe-dev at lists.llvm.org
Fri Sep 23 15:33:35 PDT 2016

Hi Eric,

Yes, you can iterate the source range of a declaration like a function. But
I don't think you need to, as you can iterate macro expansions and check if
they were expanded inside the source range of the function. The following
piece of code illustrates this approach (assuming you have a declaration
Decl and a source manager reference SM):

  SourceLocation Start = Decl->getLocStart();
  SourceLocation End = Decl->getLocEnd();
  for (unsigned I = 0, E = SM.local_sloc_entry_size(); I != E; ++I) {
    const SrcMgr::SLocEntry &Entry = SM.getLocalSLocEntry(I);
    if (Entry.isExpansion() && Entry.getExpansion().isMacroBodyExpansion())
      SourceLocation Loc = Entry.getExpansion().getExpansionLocStart();
      if (Start < Loc && Loc < End) {
         // This Macro expansion is inside the body of the function (Decl).

You can get the name of the macro that is expanded inside a function by
looking at the first token that's at the location 'Loc' i.e. at the
starting location of the expansion.

I hope that helps,

On 23 September 2016 at 14:20, Eric Bayer via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> Hi,
> I have a project that I've been working on to determine dependencies in
> code and mock/stub them.  Mostly I'm using a recursive visitor to datamine
> these things.  I would really like to be able to figure out what macros are
> used in a function as well (or SourceRange would be even more helpful.)
>  Just to be clear I'm doing this as a clang frontend plugin (currently
> stopping at syntax check).  I know that I can capture these PPCallbacks and
> store away their SourceLocations etc during preprocessing, but based on
> what is done in error messages I would imagine that the information is
> there somewhere already... I'd rather not reinvent the wheel if something
> else will work already.
> For example:
> #define BAR "%s"
> #define FOO(x) printf( BAR, x )
> #define DOY 3
> void func1() {
>     const char *lvar="func1";
>     FOO(lvar);
> }
> void func2() {
>     printf("%d", DOY);
> }
> What I want to be able to do is isolate func1() and determine that FOO and
> BAR were both used and what macro they were pointing to at the time they
> were used.  What I'm hoping is that there is way to iterate the SourceRange
> to find where the text pieces came from (with enough info to know what the
> macro name/definition was).  I didn't see an obvious way to do this.  Then
> again, maybe I'm going down the wrong path and there's an entirely easier
> direction?
> Anyhow, even some hints in the right direction would be greatly
> appreciated.
> Thanks in advance,
>    -Eric
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160923/051bbbb3/attachment.html>

More information about the cfe-dev mailing list