[cfe-dev] Preprocessor lexer sometimes goes too far?
Vladimir Kirillov
proger at uaoug.org.ua
Tue Nov 9 08:36:48 PST 2010
Hello, cfe-dev!
Here's an issue:
I have a program with subclasses of ASTConsumer and PPCallbacks, which
are passed to ParseAST().
See the expansions.c attachment which I pass as input to it.
Sometimes I see that the macro expansion callbacks (and, respectively,
macro expansion actions) are happening way before the respective code
gets processed. (See gdb output below)
How can this behaviour be explained? Is this some kind of optimization
side effect or something?
My program relies on the expansion order so this is critical to me to
gather relations between expanded macros and the declarations they
expanded.
(gdb) i b
Num Type Disp Enb Address What
2 breakpoint keep y 0x0a59b839 in clang::Preprocessor::EnterMacro(clang::Token&, clang::SourceLocation, clang::MacroArgs*) at PPLexerChange.cpp:146
3 breakpoint keep y 0x0a59b19f in clang::Preprocessor::HandleEndOfTokenLexer(clang::Token&) at PPLexerChange.cpp:269
5 breakpoint keep n 0x0a23385c in clang::Parser::ParseDeclGroup(clang::Parser::ParsingDeclSpec&, unsigned int, bool, clang::SourceLocation*)
at ParseDecl.cpp:418
135 main(int argc, char **argv)
(gdb) c
Continuing.
processing: tests/expansions.c
preprocessing: tests/expansions.c
defined macro: LIST_ENTRY
defined macro: DLIST
defined macro: DFUN
expansion: LIST_ENTRY
Breakpoint 2, clang::Preprocessor::EnterMacro (this=0x7f946a00, Tok=@0xcfbc6afc, ILEnd={ID = 209}, Args=0x7d0fe200) at PPLexerChange.cpp:146
146 PushIncludeMacroStack();
(gdb)
Continuing.
Breakpoint 3, clang::Preprocessor::HandleEndOfTokenLexer (this=0x7f946a00, Result=@0xcfbc6afc) at PPLexerChange.cpp:269 269 assert(CurTokenLexer && !CurPPLexer &&
(gdb)
Continuing.
tests/expansions.c:6:8 HandleTagDeclDefinition Record
field: p type: void * Pointer
field: d1_next type: struct data1 * Pointer
tests/expansions.c:6:8 HandleTopLevelDecl Record
tests/expansions.c:11:8 HandleTagDeclDefinition Record
field: data type: int Builtin
expansion: DLIST
>>> Here, the DLIST expansion goes ahead the HandleTopLevelDecl
>>> ParseTopLevelDecl() has not returned here yet. why?
Breakpoint 2, clang::Preprocessor::EnterMacro (this=0x7f946a00, Tok=@0xcfbc6afc, ILEnd={ID = 256}, Args=0x7d0fea80) at PPLexerChange.cpp:146
146 PushIncludeMacroStack();
(gdb) c
Continuing.
tests/expansions.c:11:8 HandleTopLevelDecl Record
tests/expansions.c:15:1 <Spelling=<scratch space>:4:1> HandleTopLevelDecl Var
global:struct data1 a2
Breakpoint 3, clang::Preprocessor::HandleEndOfTokenLexer (this=0x7f946a00, Result=@0xcfbc6afc) at PPLexerChange.cpp:269
269 assert(CurTokenLexer && !CurPPLexer &&
(gdb) c
Continuing.
expansion: DLIST
Breakpoint 2, clang::Preprocessor::EnterMacro (this=0x7f946a00, Tok=@0xcfbc6afc, ILEnd={ID = 269}, Args=0x7d0fe200) at PPLexerChange.cpp:146
146 PushIncludeMacroStack();
(gdb) c
Continuing.
tests/expansions.c:15:1 <Spelling=<scratch space>:4:1> HandleTopLevelDecl Var
global:struct data2 a1
tests/expansions.c:16:1 <Spelling=<scratch space>:4:1> HandleTopLevelDecl Var
global:struct data2 a1
Breakpoint 3, clang::Preprocessor::HandleEndOfTokenLexer (this=0x7f946a00, Result=@0xcfbc6afc) at PPLexerChange.cpp:269
269 assert(CurTokenLexer && !CurPPLexer &&
(gdb) c
Continuing.
expansion: DFUN
Breakpoint 2, clang::Preprocessor::EnterMacro (this=0x7f946a00, Tok=@0xcfbc6afc, ILEnd={ID = 280}, Args=0x7d0fea80) at PPLexerChange.cpp:146
146 PushIncludeMacroStack();
(gdb) c
Continuing.
tests/expansions.c:16:1 <Spelling=<scratch space>:4:1> HandleTopLevelDecl Var
global:struct data1 a2
>>> Here, the second DFUN expansion goes ahead the second struct
>>> declaration.
Breakpoint 3, clang::Preprocessor::HandleEndOfTokenLexer (this=0x7f946a00, Result=@0xcfbc6afc) at PPLexerChange.cpp:269
269 assert(CurTokenLexer && !CurPPLexer &&
(gdb) c
Continuing.
expansion: DFUN
Breakpoint 2, clang::Preprocessor::EnterMacro (this=0x7f946a00, Tok=@0xcfbc6afc, ILEnd={ID = 289}, Args=0x7d0fe200) at PPLexerChange.cpp:146
146 PushIncludeMacroStack();
-------------- next part --------------
#define LIST_ENTRY(t, f) struct t *f##_next
#define DLIST(n, k) struct data##n a##k; \
struct data##k a##n
#define DFUN(n) int proc##n(struct data##n *)
struct data1 {
void *p;
LIST_ENTRY(data1, d1);
};
struct data2 {
int data;
};
DLIST(1, 2);
DLIST(2, 1);
DFUN(1);
DFUN(2);
More information about the cfe-dev
mailing list