Skip to content

Commit b50c676

Browse files
committedNov 17, 2017
add parse-c support for unions
1 parent d108689 commit b50c676

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed
 

‎src/parsec.cpp

+18-8
Original file line numberDiff line numberDiff line change
@@ -680,11 +680,10 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
680680
const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty);
681681
switch (elaborated_ty->getKeyword()) {
682682
case ETK_Struct:
683-
return trans_qual_type(c, elaborated_ty->getNamedType(), source_loc);
684683
case ETK_Enum:
684+
case ETK_Union:
685685
return trans_qual_type(c, elaborated_ty->getNamedType(), source_loc);
686686
case ETK_Interface:
687-
case ETK_Union:
688687
case ETK_Class:
689688
case ETK_Typename:
690689
case ETK_None:
@@ -2946,15 +2945,24 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
29462945

29472946
const char *raw_name = decl_name(record_decl);
29482947

2949-
if (!record_decl->isStruct()) {
2950-
emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name);
2948+
const char *container_kind_name;
2949+
ContainerKind container_kind;
2950+
if (record_decl->isUnion()) {
2951+
container_kind_name = "union";
2952+
container_kind = ContainerKindUnion;
2953+
} else if (record_decl->isStruct()) {
2954+
container_kind_name = "struct";
2955+
container_kind = ContainerKindStruct;
2956+
} else {
2957+
emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct or union", raw_name);
29512958
c->decl_table.put(record_decl->getCanonicalDecl(), nullptr);
29522959
return nullptr;
29532960
}
29542961

29552962
bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0;
29562963
Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
2957-
Buf *full_type_name = (bare_name == nullptr) ? nullptr : buf_sprintf("struct_%s", buf_ptr(bare_name));
2964+
Buf *full_type_name = (bare_name == nullptr) ?
2965+
nullptr : buf_sprintf("%s_%s", container_kind_name, buf_ptr(bare_name));
29582966

29592967
RecordDecl *record_def = record_decl->getDefinition();
29602968
if (record_def == nullptr) {
@@ -2970,14 +2978,15 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
29702978
const FieldDecl *field_decl = *it;
29712979

29722980
if (field_decl->isBitField()) {
2973-
emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield",
2981+
emit_warning(c, field_decl->getLocation(), "%s %s demoted to opaque type - has bitfield",
2982+
container_kind_name,
29742983
is_anonymous ? "(anon)" : buf_ptr(bare_name));
29752984
return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
29762985
}
29772986
}
29782987

29792988
AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl);
2980-
struct_node->data.container_decl.kind = ContainerKindStruct;
2989+
struct_node->data.container_decl.kind = container_kind;
29812990
struct_node->data.container_decl.layout = ContainerLayoutExtern;
29822991

29832992
// TODO handle attribute packed
@@ -3004,7 +3013,8 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
30043013

30053014
if (field_node->data.struct_field.type == nullptr) {
30063015
emit_warning(c, field_decl->getLocation(),
3007-
"struct %s demoted to opaque type - unresolved type",
3016+
"%s %s demoted to opaque type - unresolved type",
3017+
container_kind_name,
30083018
is_anonymous ? "(anon)" : buf_ptr(bare_name));
30093019

30103020
return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);

‎test/parsec.zig

+15
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,21 @@ pub fn addCases(cases: &tests.ParseCContext) {
857857
\\ (*(??x)) = 1;
858858
\\}
859859
);
860+
861+
cases.add("simple union",
862+
\\union Foo {
863+
\\ int x;
864+
\\ double y;
865+
\\};
866+
,
867+
\\pub const union_Foo = extern union {
868+
\\ x: c_int,
869+
\\ y: f64,
870+
\\};
871+
,
872+
\\pub const Foo = union_Foo;
873+
);
874+
860875
}
861876

862877

0 commit comments

Comments
 (0)
Please sign in to comment.