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)...@@ -105,6 +105,18 @@ static AstNode *create_prefix_node(Context *c, PrefixOp op, AstNode *child_node)
105 return node;105 return node;
106}106}
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
108static const char *decl_name(const Decl *decl) {120static const char *decl_name(const Decl *decl) {
109 const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);121 const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);
110 return (const char *)named_decl->getName().bytes_begin();122 return (const char *)named_decl->getName().bytes_begin();
...@@ -386,6 +398,11 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)...@@ -386,6 +398,11 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)
386 add_typedef_node(c, type_name, make_qual_type_node(c, child_qt, typedef_decl));398 add_typedef_node(c, type_name, make_qual_type_node(c, child_qt, typedef_decl));
387}399}
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
389static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {406static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
390 Buf bare_name = BUF_INIT;407 Buf bare_name = BUF_INIT;
391 buf_init_from_str(&bare_name, decl_name(enum_decl));408 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) {...@@ -403,9 +420,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
403 if (!enum_def) {420 if (!enum_def) {
404 // this is a type that we can point to but that's it, same as `struct Foo;`.421 // this is a type that we can point to but that's it, same as `struct Foo;`.
405 add_typedef_node(c, type_name, create_symbol_node(c, "u8"));422 add_typedef_node(c, type_name, create_symbol_node(c, "u8"));
406 AstNode *alias_node = create_var_decl_node(c, buf_ptr(&bare_name),423 add_alias(c, buf_ptr(&bare_name), buf_ptr(type_name));
407 create_symbol_node(c, buf_ptr(type_name)));
408 c->aliases.append(alias_node);
409 return;424 return;
410 }425 }
411426
...@@ -427,32 +442,29 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {...@@ -427,32 +442,29 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
427 emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(type_name));442 emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(type_name));
428 return;443 return;
429 }444 }
430 AstNode *field_node = create_node(c, NodeTypeStructField);
431 Buf enum_val_name = BUF_INIT;445 Buf enum_val_name = BUF_INIT;
432 buf_init_from_str(&enum_val_name, decl_name(enum_const));446 buf_init_from_str(&enum_val_name, decl_name(enum_const));
433447
448 Buf field_name = BUF_INIT;
449
434 if (buf_starts_with_buf(&enum_val_name, &bare_name)) {450 if (buf_starts_with_buf(&enum_val_name, &bare_name)) {
435 Buf *slice = buf_slice(&enum_val_name, buf_len(&bare_name), buf_len(&enum_val_name));451 Buf *slice = buf_slice(&enum_val_name, buf_len(&bare_name), buf_len(&enum_val_name));
436 if (valid_symbol_starter(buf_ptr(slice)[0])) {452 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);
438 } else {454 } else {
439 buf_resize(&field_node->data.struct_field.name, 0);455 buf_resize(&field_name, 0);
440 buf_appendf(&field_node->data.struct_field.name, "_%s", buf_ptr(slice));456 buf_appendf(&field_name, "_%s", buf_ptr(slice));
441 }457 }
442 } else {458 } 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);
444 }460 }
445461
446 field_node->data.struct_field.directives = create_empty_directives(c);462 AstNode *field_node = create_struct_field_node(c, buf_ptr(&field_name), create_symbol_node(c, "void"));
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);
451 node->data.struct_decl.fields.append(field_node);463 node->data.struct_decl.fields.append(field_node);
452464
453 // in C each enum value is in the global namespace. so we put them there too.465 // in C each enum value is in the global namespace. so we put them there too.
454 AstNode *field_access_node = create_field_access_node(c, buf_ptr(type_name),466 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));
456 AstNode *var_node = create_var_decl_node(c, buf_ptr(&enum_val_name), field_access_node);468 AstNode *var_node = create_var_decl_node(c, buf_ptr(&enum_val_name), field_access_node);
457 var_decls.append(var_node);469 var_decls.append(var_node);
458 }470 }
...@@ -469,9 +481,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {...@@ -469,9 +481,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
469481
470 // make an alias without the "enum_" prefix. this will get emitted at the482 // make an alias without the "enum_" prefix. this will get emitted at the
471 // end if it doesn't conflict with anything else483 // 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)));484 add_alias(c, buf_ptr(&bare_name), buf_ptr(type_name));
473 c->aliases.append(alias_node);
474
475}485}
476486
477static void visit_record_decl(Context *c, const RecordDecl *record_decl) {487static 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) {...@@ -490,15 +500,15 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) {
490 if (!record_def) {500 if (!record_def) {
491 // this is a type that we can point to but that's it, such as `struct Foo;`.501 // this is a type that we can point to but that's it, such as `struct Foo;`.
492 add_typedef_node(c, type_name, create_symbol_node(c, "u8"));502 add_typedef_node(c, type_name, create_symbol_node(c, "u8"));
493 AstNode *alias_node = create_var_decl_node(c, buf_ptr(&bare_name),503 add_alias(c, buf_ptr(&bare_name), buf_ptr(type_name));
494 create_symbol_node(c, buf_ptr(type_name)));
495 c->aliases.append(alias_node);
496 return;504 return;
497 }505 }
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 /*
502 AstNode *node = create_node(c, NodeTypeStructDecl);512 AstNode *node = create_node(c, NodeTypeStructDecl);
503 buf_init_from_buf(&node->data.struct_decl.name, type_name);513 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) {...@@ -506,9 +516,34 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) {
506 node->data.struct_decl.visib_mod = VisibModExport;516 node->data.struct_decl.visib_mod = VisibModExport;
507 node->data.struct_decl.directives = create_empty_directives(c);517 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);
509 normalize_parent_ptrs(node);541 normalize_parent_ptrs(node);
510 c->root->data.root.top_level_decls.append(node);542 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));
512}547}
513548
514static bool decl_visitor(void *context, const Decl *decl) {549static bool decl_visitor(void *context, const Decl *decl) {
test/run_tests.cpp+11
...@@ -1828,6 +1828,17 @@ pub const Foo = enum_Foo;)OUTPUT");...@@ -1828,6 +1828,17 @@ pub const Foo = enum_Foo;)OUTPUT");
1828void foo(void *restrict bar, void *restrict);1828void foo(void *restrict bar, void *restrict);
1829 )SOURCE", R"OUTPUT(pub const c_void = u8;1829 )SOURCE", R"OUTPUT(pub const c_void = u8;
1830pub extern fn foo(noalias bar: ?&c_void, noalias arg1: ?&c_void);)OUTPUT");1830pub 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");
1831}1842}
18321843
1833static void print_compiler_invocation(TestCase *test_case) {1844static void print_compiler_invocation(TestCase *test_case) {