[cfe-dev] Question about anonymous structs/unions

Mikhail Ramalho via cfe-dev cfe-dev at lists.llvm.org
Thu Nov 24 11:26:50 PST 2016


Hi all,

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.

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:

typedef struct {
  int x;
  union {
    int a;
    int b;
  };
} A;

never becomes this:

typedef struct {
  int x;
  int a;
  int b;
} A;

(maybe because of layout restrictions?)

And for nested anonymous structs/unions, a memberExpr is created for each
level. For example:

typedef struct {
    bool is_float;
    struct {
       int a;
       short b;
       union {
         int c;
         short d;
         struct {
           float f;
         };
       };
       struct {
         float g;
       };
    };
} mychoice_t;

int as_float(mychoice_t* ch)
{
   return ch->f;
}

Clang generates:

|-FunctionDecl 0x6061390 <line:22:1, line:25:1> line:22:5 as_float 'int
(mychoice_t *)'
| |-ParmVarDecl 0x6061288 <col:14, col:26> col:26 used ch 'mychoice_t *'
| `-CompoundStmt 0x6061600 <line:23:1, line:25:1>
|   `-ReturnStmt 0x60615e8 <line:24:4, col:15>
|     `-ImplicitCastExpr 0x60615d0 <col:11, col:15> 'int'
<FloatingToIntegral>
|       `-ImplicitCastExpr 0x60615b8 <col:11, col:15> 'float'
<LValueToRValue>
|         `-MemberExpr 0x6061580 <col:11, col:15> 'float' lvalue .f
0x60609d0
|           `-MemberExpr 0x6061548 <col:11, col:15> 'struct
mychoice_t::(anonymous at
/home/mramalho/esbmc/regression/llvm/struct_union/main.c:12:10)' lvalue .
0x6060a70
|             `-MemberExpr 0x6061510 <col:11, col:15> 'union
mychoice_t::(anonymous at
/home/mramalho/esbmc/regression/llvm/struct_union/main.c:9:8)' lvalue .
0x6060b60
|               `-MemberExpr 0x60614c0 <col:11, col:15> 'struct
mychoice_t::(anonymous at
/home/mramalho/esbmc/regression/llvm/struct_union/main.c:6:5)' lvalue ->
0x6060ef0
|                 `-ImplicitCastExpr 0x60614a8 <col:11> 'mychoice_t *'
<LValueToRValue>
|                   `-DeclRefExpr 0x6061480 <col:11> 'mychoice_t *' lvalue
ParmVar 0x6061288 'ch' 'mychoice_t *'


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?

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.

Thank you,

-- 

Mikhail Ramalho.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20161124/5c9a962a/attachment.html>


More information about the cfe-dev mailing list