| ... | ... | @@ -105,6 +105,18 @@ static AstNode *create_prefix_node(Context *c, PrefixOp op, AstNode *child_node) |
| 105 | 105 | return node; |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | static 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 | |
| 108 | 120 | static const char *decl_name(const Decl *decl) { |
| 109 | 121 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); |
| 110 | 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 | 398 | add_typedef_node(c, type_name, make_qual_type_node(c, child_qt, typedef_decl)); |
| 387 | 399 | } |
| 388 | 400 | |
| 401 | static 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 | |
| 389 | 406 | static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 390 | 407 | Buf bare_name = BUF_INIT; |
| 391 | 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 | 420 | if (!enum_def) { |
| 404 | 421 | // this is a type that we can point to but that's it, same as `struct Foo;`. |
| 405 | 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), |
| 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)); |
| 409 | 424 | return; |
| 410 | 425 | } |
| 411 | 426 | |
| ... | ... | @@ -427,32 +442,29 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 427 | 442 | emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(type_name)); |
| 428 | 443 | return; |
| 429 | 444 | } |
| 430 | | AstNode *field_node = create_node(c, NodeTypeStructField); |
| 431 | 445 | Buf enum_val_name = BUF_INIT; |
| 432 | 446 | buf_init_from_str(&enum_val_name, decl_name(enum_const)); |
| 433 | 447 | |
| 448 | Buf field_name = BUF_INIT; |
| 449 | |
| 434 | 450 | if (buf_starts_with_buf(&enum_val_name, &bare_name)) { |
| 435 | 451 | Buf *slice = buf_slice(&enum_val_name, buf_len(&bare_name), buf_len(&enum_val_name)); |
| 436 | 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 | 454 | } 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)); |
| 441 | 457 | } |
| 442 | 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 | } |
| 445 | 461 | |
| 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")); |
| 451 | 463 | node->data.struct_decl.fields.append(field_node); |
| 452 | 464 | |
| 453 | 465 | // in C each enum value is in the global namespace. so we put them there too. |
| 454 | 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 | 468 | AstNode *var_node = create_var_decl_node(c, buf_ptr(&enum_val_name), field_access_node); |
| 457 | 469 | var_decls.append(var_node); |
| 458 | 470 | } |
| ... | ... | @@ -469,9 +481,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 469 | 481 | |
| 470 | 482 | // make an alias without the "enum_" prefix. this will get emitted at the |
| 471 | 483 | // 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)); |
| 475 | 485 | } |
| 476 | 486 | |
| 477 | 487 | 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 | 500 | if (!record_def) { |
| 491 | 501 | // this is a type that we can point to but that's it, such as `struct Foo;`. |
| 492 | 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), |
| 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)); |
| 496 | 504 | return; |
| 497 | 505 | } |
| 498 | 506 | |
| 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 | } |
| 500 | 511 | |
| 501 | | /* |
| 502 | 512 | AstNode *node = create_node(c, NodeTypeStructDecl); |
| 503 | 513 | buf_init_from_buf(&node->data.struct_decl.name, type_name); |
| 504 | 514 | |
| ... | ... | @@ -506,9 +516,34 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) { |
| 506 | 516 | node->data.struct_decl.visib_mod = VisibModExport; |
| 507 | 517 | node->data.struct_decl.directives = create_empty_directives(c); |
| 508 | 518 | |
| 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 | 541 | normalize_parent_ptrs(node); |
| 510 | 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 | } |
| 513 | 548 | |
| 514 | 549 | static bool decl_visitor(void *context, const Decl *decl) { |