authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-16 23:54:33-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-16 23:54:33-05:00
logb50c676f760272b014e3c6320b13b979bfc864c7
tree92dd3a4a196a321b70bd11d0976af7c92420ccfc
parentd1086893829d91d0e1335e14b0434a23ff0e8999

add parse-c support for unions


2 files changed, 33 insertions(+), 8 deletions(-)

src/parsec.cpp+18-8
......@@ -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
......@@ -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