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
#define __MATH_PRECNAME(name) name##f
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.