authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 14:49:34-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 14:49:34-07:00
log47c3a30310b142dea390afaf4063a8b078a34f0d
tree83dbd3fddda14da47897a599cfd9f6e34652de7a
parenta09b5055585a869bf5af522d19836e3f2c25fc5b

parseh understands simple structs


2 files changed, 69 insertions(+), 23 deletions(-)

src/parseh.cpp+58-23
......@@ -105,6 +105,18 @@ static AstNode *create_prefix_node(Context *c, PrefixOp op, AstNode *child_node)
105105 return node;
106106}
107107
108static AstNode *create_struct_field_node(Context *c, const char *name, AstNode *type_node) {
109 assert(type_node);
110 AstNode *node = create_node(c, NodeTypeStructField);
111 buf_init_from_str(&node->data.struct_field.name, name);
112 node->data.struct_field.directives = create_empty_directives(c);
113 node->data.struct_field.visib_mod = VisibModPub;
114 node->data.struct_field.type = type_node;
115
116 normalize_parent_ptrs(node);
117 return node;
118}
119
108120static const char *decl_name(const Decl *decl) {
109121 const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);
110122 return (const char *)named_decl->getName().bytes_begin();
......@@ -386,6 +398,11 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)
386398 add_typedef_node(c, type_name, make_qual_type_node(c, child_qt, typedef_decl));
387399}
388400
401static void add_alias(Context *c, const char *new_name, const char *target_name) {
402 AstNode *alias_node = create_var_decl_node(c, new_name, create_symbol_node(c, target_name));
403 c->aliases.append(alias_node);
404}
405
389406static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
390407 Buf bare_name = BUF_INIT;
391408 buf_init_from_str(&bare_name, decl_name(enum_decl));
......@@ -403,9 +420,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
403420 if (!enum_def) {
404421 // this is a type that we can point to but that's it, same as `struct Foo;`.
405422 add_typedef_node(c, type_name, create_symbol_node(c, "u8"));
406 AstNode *alias_node = create_var_decl_node(c, buf_ptr(&bare_name),
407 create_symbol_node(c, buf_ptr(type_name)));
408 c->aliases.append(alias_node);
423 add_alias(c, buf_ptr(&bare_name), buf_ptr(type_name));
409424 return;
410425 }
411426
......@@ -427,32 +442,29 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
427442 emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(type_name));
428443 return;
429444 }
430 AstNode *field_node = create_node(c, NodeTypeStructField);
431445 Buf enum_val_name = BUF_INIT;
432446 buf_init_from_str(&enum_val_name, decl_name(enum_const));
433447
448 Buf field_name = BUF_INIT;
449
434450 if (buf_starts_with_buf(&enum_val_name, &bare_name)) {
435451 Buf *slice = buf_slice(&enum_val_name, buf_len(&bare_name), buf_len(&enum_val_name));
436452 if (valid_symbol_starter(buf_ptr(slice)[0])) {
437 buf_init_from_buf(&field_node->data.struct_field.name, slice);
453 buf_init_from_buf(&field_name, slice);
438454 } else {
439 buf_resize(&field_node->data.struct_field.name, 0);
440 buf_appendf(&field_node->data.struct_field.name, "_%s", buf_ptr(slice));
455 buf_resize(&field_name, 0);
456 buf_appendf(&field_name, "_%s", buf_ptr(slice));
441457 }
442458 } else {
443 buf_init_from_buf(&field_node->data.struct_field.name, &enum_val_name);
459 buf_init_from_buf(&field_name, &enum_val_name);
444460 }
445461
446 field_node->data.struct_field.directives = create_empty_directives(c);
447 field_node->data.struct_field.visib_mod = VisibModPub;
448 field_node->data.struct_field.type = create_symbol_node(c, "void");
449
450 normalize_parent_ptrs(field_node);
462 AstNode *field_node = create_struct_field_node(c, buf_ptr(&field_name), create_symbol_node(c, "void"));
451463 node->data.struct_decl.fields.append(field_node);
452464
453465 // in C each enum value is in the global namespace. so we put them there too.
454466 AstNode *field_access_node = create_field_access_node(c, buf_ptr(type_name),
455 buf_ptr(&field_node->data.struct_field.name));
467 buf_ptr(&field_name));
456468 AstNode *var_node = create_var_decl_node(c, buf_ptr(&enum_val_name), field_access_node);
457469 var_decls.append(var_node);
458470 }
......@@ -469,9 +481,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
469481
470482 // make an alias without the "enum_" prefix. this will get emitted at the
471483 // end if it doesn't conflict with anything else
472 AstNode *alias_node = create_var_decl_node(c, buf_ptr(&bare_name), create_symbol_node(c, buf_ptr(type_name)));
473 c->aliases.append(alias_node);
474
484 add_alias(c, buf_ptr(&bare_name), buf_ptr(type_name));
475485}
476486
477487static void visit_record_decl(Context *c, const RecordDecl *record_decl) {
......@@ -490,15 +500,15 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) {
490500 if (!record_def) {
491501 // this is a type that we can point to but that's it, such as `struct Foo;`.
492502 add_typedef_node(c, type_name, create_symbol_node(c, "u8"));
493 AstNode *alias_node = create_var_decl_node(c, buf_ptr(&bare_name),
494 create_symbol_node(c, buf_ptr(type_name)));
495 c->aliases.append(alias_node);
503 add_alias(c, buf_ptr(&bare_name), buf_ptr(type_name));
496504 return;
497505 }
498506
499 emit_warning(c, record_decl, "skipping record %s, TODO", buf_ptr(&bare_name));
507 if (!record_def->isStruct()) {
508 emit_warning(c, record_decl, "skipping record %s, not a struct", buf_ptr(&bare_name));
509 return;
510 }
500511
501 /*
502512 AstNode *node = create_node(c, NodeTypeStructDecl);
503513 buf_init_from_buf(&node->data.struct_decl.name, type_name);
504514
......@@ -506,9 +516,34 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) {
506516 node->data.struct_decl.visib_mod = VisibModExport;
507517 node->data.struct_decl.directives = create_empty_directives(c);
508518
519 for (auto it = record_def->field_begin(),
520 it_end = record_def->field_end();
521 it != it_end; ++it)
522 {
523 const FieldDecl *field_decl = *it;
524
525 if (field_decl->isBitField()) {
526 emit_warning(c, field_decl, "skipping struct %s - has bitfield\n", buf_ptr(&bare_name));
527 return;
528 }
529
530 AstNode *type_node = make_qual_type_node(c, field_decl->getType(), field_decl);
531 if (!type_node) {
532 emit_warning(c, field_decl, "skipping struct %s - unhandled type\n", buf_ptr(&bare_name));
533 return;
534 }
535
536 AstNode *field_node = create_struct_field_node(c, decl_name(field_decl), type_node);
537 node->data.struct_decl.fields.append(field_node);
538 }
539
540 c->type_table.put(type_name, true);
509541 normalize_parent_ptrs(node);
510542 c->root->data.root.top_level_decls.append(node);
511 */
543
544 // make an alias without the "struct_" prefix. this will get emitted at the
545 // end if it doesn't conflict with anything else
546 add_alias(c, buf_ptr(&bare_name), buf_ptr(type_name));
512547}
513548
514549static bool decl_visitor(void *context, const Decl *decl) {
test/run_tests.cpp+11
......@@ -1828,6 +1828,17 @@ pub const Foo = enum_Foo;)OUTPUT");
18281828void foo(void *restrict bar, void *restrict);
18291829 )SOURCE", R"OUTPUT(pub const c_void = u8;
18301830pub extern fn foo(noalias bar: ?&c_void, noalias arg1: ?&c_void);)OUTPUT");
1831
1832 add_parseh_case("simple struct", R"SOURCE(
1833struct Foo {
1834 int x;
1835 char *y;
1836};
1837 )SOURCE", R"OUTPUT(export struct struct_Foo {
1838 x: c_int,
1839 y: ?&u8,
1840}
1841pub const Foo = struct_Foo;)OUTPUT");
18311842}
18321843
18331844static void print_compiler_invocation(TestCase *test_case) {