Clang, macros and declarations

Hi all,

We are working on a Clang plugin, and we wan to have a way to uniquely identify every declaration in a C++ program. We tried using the following.
(presumed location start, presumed location end, spelling location start, spelling location end, declaration kind)

But we still have a problem.

For example, in /usr/include/x86_64-linux-gnu/bits/cmathcalls.h, line 101 a macro called _MATHCALL is used. If you look at /usr/include/complex.h, line 65 where the macro is defined, you will see that the macro uses other macros inside and create two functions (e.g. cpowf and __cpowf)

I tried using spelling locations, presumed locations, SourceManager::getExpansionLoc on the spelling location. All give the same locations for cpowf and __cpowf.

Is there any way to achieve what I try to do here?

Thanks for your time

If you really need to serialize SourceLocations, you really need to encode
the entire macro expansion stack.
SourceManager::getImmediateMacroCallerLoc might be helpful here.


I don't know if this is the right solution but the C API in Clang has functions to do cross references in the AST. I assume that API uses some unique way to identify the entities.

I'm thinking of clang_getCursorUSR:

Perhaps it's possible to reuse.

Thanks. Yeah, SourceManager::getImmediateMacroCallerLoc is what we though might help to get all the expansion stack and I think it helped in some cases. But now we have the following issue (again from the same math header!). Say you have in file a.cpp

#define __THROW throw ()

#define __MATHCALL(function, args)
__MATHDECL (double,function, args)
#define __MATHDECL(type, function, args)
__MATHDECL_1(type, function, args);
__MATHDECL_1(type, __ ## function, args)
#define __MATHDECL_1(type, function, args)
extern type __MATH_PRECNAME(function) args __THROW

#define __MATH_PRECNAME(name) name
#include “b.h”

#define __MATH_PRECNAME(name) name##f
#include “b.h”

and in b.h

__MATHCALL (cpow, (double __x, double __y));

This will create 4 functions (cpow, __cpow, cpowf, __cpowf). Using SourceManager::getImmediateMacroCallerLoc we are able to differentiate for example cpow and __cpow. But there is still an issue with cpow and cpowf (and with __cpow and __cpowf). Those pairs have the same locations even when getting the whole expansion macro.

Is there anything we can do to handle this case?

I think you also need to track the include stack.
SourceManager::getDecomposedIncludedLoc might be useful here.


Great. The combination of SourceManager::getDecomposedIncludedLoc and SourceManager::getImmediateMacroCallerLoc (in a loop) (along with the spelling location and the presumed location) seems to work for all the cases that I tried. I just accumulate the information in a string and get a hash afterwards.

Thank you for your help.