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...@@ -680,11 +680,10 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
680 const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty);680 const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty);
681 switch (elaborated_ty->getKeyword()) {681 switch (elaborated_ty->getKeyword()) {
682 case ETK_Struct:682 case ETK_Struct:
683 return trans_qual_type(c, elaborated_ty->getNamedType(), source_loc);
684 case ETK_Enum:683 case ETK_Enum:
684 case ETK_Union:
685 return trans_qual_type(c, elaborated_ty->getNamedType(), source_loc);685 return trans_qual_type(c, elaborated_ty->getNamedType(), source_loc);
686 case ETK_Interface:686 case ETK_Interface:
687 case ETK_Union:
688 case ETK_Class:687 case ETK_Class:
689 case ETK_Typename:688 case ETK_Typename:
690 case ETK_None:689 case ETK_None:
...@@ -2946,15 +2945,24 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {...@@ -2946,15 +2945,24 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
29462945
2947 const char *raw_name = decl_name(record_decl);2946 const char *raw_name = decl_name(record_decl);
29482947
2949 if (!record_decl->isStruct()) {2948 const char *container_kind_name;
2950 emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_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);
2951 c->decl_table.put(record_decl->getCanonicalDecl(), nullptr);2958 c->decl_table.put(record_decl->getCanonicalDecl(), nullptr);
2952 return nullptr;2959 return nullptr;
2953 }2960 }
29542961
2955 bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0;2962 bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0;
2956 Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);2963 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
2959 RecordDecl *record_def = record_decl->getDefinition();2967 RecordDecl *record_def = record_decl->getDefinition();
2960 if (record_def == nullptr) {2968 if (record_def == nullptr) {
...@@ -2970,14 +2978,15 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {...@@ -2970,14 +2978,15 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
2970 const FieldDecl *field_decl = *it;2978 const FieldDecl *field_decl = *it;
29712979
2972 if (field_decl->isBitField()) {2980 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,
2974 is_anonymous ? "(anon)" : buf_ptr(bare_name));2983 is_anonymous ? "(anon)" : buf_ptr(bare_name));
2975 return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);2984 return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
2976 }2985 }
2977 }2986 }
29782987
2979 AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl);2988 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;
2981 struct_node->data.container_decl.layout = ContainerLayoutExtern;2990 struct_node->data.container_decl.layout = ContainerLayoutExtern;
29822991
2983 // TODO handle attribute packed2992 // TODO handle attribute packed
...@@ -3004,7 +3013,8 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {...@@ -3004,7 +3013,8 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
30043013
3005 if (field_node->data.struct_field.type == nullptr) {3014 if (field_node->data.struct_field.type == nullptr) {
3006 emit_warning(c, field_decl->getLocation(),3015 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,
3008 is_anonymous ? "(anon)" : buf_ptr(bare_name));3018 is_anonymous ? "(anon)" : buf_ptr(bare_name));
30093019
3010 return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);3020 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) {...@@ -857,6 +857,21 @@ pub fn addCases(cases: &tests.ParseCContext) {
857 \\ (*(??x)) = 1;857 \\ (*(??x)) = 1;
858 \\}858 \\}
859 );859 );
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
860}875}
861876
862877