<div dir="ltr">Hi all,<div><br></div><div>I'm using libTooling to build the AST of a program, convert to an internal format and used to analyse a program, but I'm facing a problem and would like to know how clang solves the issue.</div><div><br></div><div>It's about anonymous structs and unions. For example, I noticed that clang doesn't 'flat' any anonymous struct on the AST. By flat, I mean:</div><div><br></div><div><div>typedef struct {</div><div>  int x;</div><div>  union {</div><div>    int a;</div><div>    int b;</div><div>  };</div><div>} A;</div><div><br></div><div>never becomes this:</div><div><br></div><div>typedef struct {</div><div>  int x;</div><div>  int a;</div><div>  int b;</div><div>} A;</div></div><div><br></div><div>(maybe because of layout restrictions?)</div><div><br></div><div>And for nested anonymous structs/unions, a memberExpr is created for each level. For example:</div><div><br></div><div><div>typedef struct {</div><div>    bool is_float;</div><div>    struct {</div><div>       int a;</div><div>       short b;</div><div>       union {</div><div>         int c;</div><div>         short d;</div><div>         struct {</div><div>           float f;</div><div>         };</div><div>       };</div><div>       struct {</div><div>         float g;</div><div>       };</div><div>    };</div><div>} mychoice_t;</div></div><div><br></div><div><div>int as_float(mychoice_t* ch) </div><div>{ </div><div>   return ch->f;</div><div>} </div></div><div><br></div><div>Clang generates:</div><div><br></div><div><div>|-FunctionDecl 0x6061390 <line:22:1, line:25:1> line:22:5 as_float 'int (mychoice_t *)'</div><div>| |-ParmVarDecl 0x6061288 <col:14, col:26> col:26 used ch 'mychoice_t *'</div><div>| `-CompoundStmt 0x6061600 <line:23:1, line:25:1></div><div>|   `-ReturnStmt 0x60615e8 <line:24:4, col:15></div><div>|     `-ImplicitCastExpr 0x60615d0 <col:11, col:15> 'int' <FloatingToIntegral></div><div>|       `-ImplicitCastExpr 0x60615b8 <col:11, col:15> 'float' <LValueToRValue></div><div>|         `-MemberExpr 0x6061580 <col:11, col:15> 'float' lvalue .f 0x60609d0</div><div>|           `-MemberExpr 0x6061548 <col:11, col:15> 'struct mychoice_t::(anonymous at /home/mramalho/esbmc/regression/llvm/struct_union/main.c:12:10)' lvalue . 0x6060a70</div><div>|             `-MemberExpr 0x6061510 <col:11, col:15> 'union mychoice_t::(anonymous at /home/mramalho/esbmc/regression/llvm/struct_union/main.c:9:8)' lvalue . 0x6060b60</div><div>|               `-MemberExpr 0x60614c0 <col:11, col:15> 'struct mychoice_t::(anonymous at /home/mramalho/esbmc/regression/llvm/struct_union/main.c:6:5)' lvalue -> 0x6060ef0</div><div>|                 `-ImplicitCastExpr 0x60614a8 <col:11> 'mychoice_t *' <LValueToRValue></div><div>|                   `-DeclRefExpr 0x6061480 <col:11> 'mychoice_t *' lvalue ParmVar 0x6061288 'ch' 'mychoice_t *'</div></div><div><br></div><div><br></div><div>Does clang create a global scope for types? How does it keep track of different anonymous tags? Does it even need to keep track of them? Is the struct containing f and the struct containing g different for clang?</div><div><br></div><div>I would be great if someone could point me on the right direction here, I'm trying to find answers on clang's source code but I'm getting nowhere. Direction toward some literature about the subject are also welcome.</div><div><br></div><div>Thank you,</div><div><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><br></div><div>Mikhail Ramalho.</div></div></div>
</div></div>