Lately I've been working with Clang, and for certain purposes, I need to know when a typedef macro is used.
As far as I know, both ast-dump for the following codes are exactly the same for the variable declaration :
#define SIZE_MAX 16
int my_array[SIZE_MAX];
and
int my_array[16];
AST-dump is the following :
VarDecl 0x1dbc370 <test.cpp:2:1, col:21> my_array 'int [16]'
Of course, I know that a typedef is just an alias, but when SIZE_MAX
is parsed, there must be some kind of redirection to get the 16
value.
So, how can I distinguish when a macro is called, and when it is not ?
Yes, you can.
In Clang, the AST nodes are tagged with a SourceLocation which, as the description in the link implies, encodes both its spelling location and its instantiation location .
Therefore, using the SourceLocation
of a node in combination with a SourceManager
, you should not only be able to know whether something came from a macro-expansion, or not, but in case it does you should also be able to retrieve the expansion stack...
... which is what happens in diagnostics :
#define ARRAY_SIZE 0
int Array[ARRAY_SIZE] = {};
yields:
main.cpp:3:11: warning: zero size arrays are an extension [-Wzero-length-array]
int Array[ARRAY_SIZE] = {};
^~~~~~~~~~
main.cpp:1:20: note: expanded from macro 'ARRAY_SIZE'
#define ARRAY_SIZE 0
^
1 warning generated.
Have a look at http://llvm.org/svn/llvm-project/cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp and notably:
static StringRef getImmediateMacroName(SourceLocation Loc,
const SourceManager &SM,
const LangOptions &LangOpts) {
assert(Loc.isMacroID() && "Only reasonble to call this on macros");
// Walk past macro argument expanions.
while (SM.isMacroArgExpansion(Loc))
Loc = SM.getImmediateExpansionRange(Loc).first;
(copied verbatim, with the typo in the comment)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.