[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cfe-dev
Subject:    [cfe-dev] Question about anonymous structs/unions
From:       Mikhail Ramalho via cfe-dev <cfe-dev () lists ! llvm ! org>
Date:       2016-11-24 19:26:50
Message-ID: CAORA-9b1orBtMqA0nhFTr8uaK3oLTVpQ3=w7nrS-RonK9NTVzw () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


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.

[Attachment #5 (text/html)]

<div dir="ltr">Hi all,<div><br></div><div>I&#39;m using libTooling to build the AST \
of a program, convert to an internal format and used to analyse a program, but \
I&#39;m facing a problem and would like to know how clang solves the \
issue.</div><div><br></div><div>It&#39;s about anonymous structs and unions. For \
example, I noticed that clang doesn&#39;t &#39;flat&#39; 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-&gt;f;</div><div>}  \
</div></div><div><br></div><div>Clang \
generates:</div><div><br></div><div><div>|-FunctionDecl 0x6061390 &lt;line:22:1, \
line:25:1&gt; line:22:5 as_float &#39;int (mychoice_t *)&#39;</div><div>| \
|-ParmVarDecl 0x6061288 &lt;col:14, col:26&gt; col:26 used ch &#39;mychoice_t \
*&#39;</div><div>| `-CompoundStmt 0x6061600 &lt;line:23:1, line:25:1&gt;</div><div>|  \
`-ReturnStmt 0x60615e8 &lt;line:24:4, col:15&gt;</div><div>|       `-ImplicitCastExpr \
0x60615d0 &lt;col:11, col:15&gt; &#39;int&#39; &lt;FloatingToIntegral&gt;</div><div>| \
`-ImplicitCastExpr 0x60615b8 &lt;col:11, col:15&gt; &#39;float&#39; \
&lt;LValueToRValue&gt;</div><div>|             `-MemberExpr 0x6061580 &lt;col:11, \
col:15&gt; &#39;float&#39; lvalue .f 0x60609d0</div><div>|                \
`-MemberExpr 0x6061548 &lt;col:11, col:15&gt; &#39;struct mychoice_t::(anonymous at \
/home/mramalho/esbmc/regression/llvm/struct_union/main.c:12:10)&#39; lvalue . \
0x6060a70</div><div>|                   `-MemberExpr 0x6061510 &lt;col:11, col:15&gt; \
&#39;union mychoice_t::(anonymous at \
/home/mramalho/esbmc/regression/llvm/struct_union/main.c:9:8)&#39; lvalue . \
0x6060b60</div><div>|                      `-MemberExpr 0x60614c0 &lt;col:11, \
col:15&gt; &#39;struct mychoice_t::(anonymous at \
/home/mramalho/esbmc/regression/llvm/struct_union/main.c:6:5)&#39; lvalue -&gt; \
0x6060ef0</div><div>|                         `-ImplicitCastExpr 0x60614a8 \
&lt;col:11&gt; &#39;mychoice_t *&#39; &lt;LValueToRValue&gt;</div><div>|              \
`-DeclRefExpr 0x6061480 &lt;col:11&gt; &#39;mychoice_t *&#39; lvalue ParmVar \
0x6061288 &#39;ch&#39; &#39;mychoice_t \
*&#39;</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&#39;m trying to find answers on clang&#39;s source code but \
I&#39;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>


[Attachment #6 (text/plain)]

_______________________________________________
cfe-dev mailing list
cfe-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic