| ... | @@ -121,6 +121,17 @@ static AstNode *create_struct_field_node(Context *c, const char *name, AstNode * | ... | @@ -121,6 +121,17 @@ static AstNode *create_struct_field_node(Context *c, const char *name, AstNode * |
| 121 | return node; | 121 | return node; |
| 122 | } | 122 | } |
| 123 | | 123 | |
| | 124 | static AstNode *create_param_decl_node(Context *c, const char *name, AstNode *type_node, bool is_noalias) { |
| | 125 | assert(type_node); |
| | 126 | AstNode *node = create_node(c, NodeTypeParamDecl); |
| | 127 | buf_init_from_str(&node->data.param_decl.name, name); |
| | 128 | node->data.param_decl.type = type_node; |
| | 129 | node->data.param_decl.is_noalias = is_noalias; |
| | 130 | |
| | 131 | normalize_parent_ptrs(node); |
| | 132 | return node; |
| | 133 | } |
| | 134 | |
| 124 | static AstNode *create_num_lit_unsigned(Context *c, uint64_t x) { | 135 | static AstNode *create_num_lit_unsigned(Context *c, uint64_t x) { |
| 125 | AstNode *node = create_node(c, NodeTypeNumberLiteral); | 136 | AstNode *node = create_node(c, NodeTypeNumberLiteral); |
| 126 | node->data.number_literal.kind = NumLitUInt; | 137 | node->data.number_literal.kind = NumLitUInt; |
| ... | @@ -255,6 +266,12 @@ static AstNode *make_type_node(Context *c, const Type *ty, const Decl *decl, | ... | @@ -255,6 +266,12 @@ static AstNode *make_type_node(Context *c, const Type *ty, const Decl *decl, |
| 255 | const PointerType *pointer_ty = static_cast<const PointerType*>(ty); | 266 | const PointerType *pointer_ty = static_cast<const PointerType*>(ty); |
| 256 | QualType child_qt = pointer_ty->getPointeeType(); | 267 | QualType child_qt = pointer_ty->getPointeeType(); |
| 257 | AstNode *type_node = make_qual_type_node(c, child_qt, decl); | 268 | AstNode *type_node = make_qual_type_node(c, child_qt, decl); |
| | 269 | if (child_qt.getTypePtr()->getTypeClass() == Type::Paren) { |
| | 270 | const ParenType *paren_type = static_cast<const ParenType *>(child_qt.getTypePtr()); |
| | 271 | if (paren_type->getInnerType()->getTypeClass() == Type::FunctionProto) { |
| | 272 | return create_prefix_node(c, PrefixOpMaybe, type_node); |
| | 273 | } |
| | 274 | } |
| 258 | return pointer_to_type(c, type_node, child_qt.isConstQualified()); | 275 | return pointer_to_type(c, type_node, child_qt.isConstQualified()); |
| 259 | } | 276 | } |
| 260 | case Type::Typedef: | 277 | case Type::Typedef: |
| ... | @@ -311,8 +328,32 @@ static AstNode *make_type_node(Context *c, const Type *ty, const Decl *decl, | ... | @@ -311,8 +328,32 @@ static AstNode *make_type_node(Context *c, const Type *ty, const Decl *decl, |
| 311 | } | 328 | } |
| 312 | } | 329 | } |
| 313 | case Type::FunctionProto: | 330 | case Type::FunctionProto: |
| 314 | emit_warning(c, decl, "ignoring function type"); | 331 | { |
| 315 | return nullptr; | 332 | const FunctionProtoType *fn_proto_ty = static_cast<const FunctionProtoType*>(ty); |
| | 333 | AstNode *node = create_node(c, NodeTypeFnProto); |
| | 334 | buf_resize(&node->data.fn_proto.name, 0); |
| | 335 | node->data.fn_proto.is_extern = true; |
| | 336 | node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic(); |
| | 337 | node->data.fn_proto.return_type = make_qual_type_node(c, fn_proto_ty->getReturnType(), decl); |
| | 338 | |
| | 339 | if (!node->data.fn_proto.return_type) { |
| | 340 | return nullptr; |
| | 341 | } |
| | 342 | |
| | 343 | int arg_count = fn_proto_ty->getNumParams(); |
| | 344 | for (int i = 0; i < arg_count; i += 1) { |
| | 345 | QualType qt = fn_proto_ty->getParamType(i); |
| | 346 | bool is_noalias = qt.isRestrictQualified(); |
| | 347 | AstNode *type_node = make_qual_type_node(c, qt, decl); |
| | 348 | if (!type_node) { |
| | 349 | return nullptr; |
| | 350 | } |
| | 351 | node->data.fn_proto.params.append(create_param_decl_node(c, "", type_node, is_noalias)); |
| | 352 | } |
| | 353 | |
| | 354 | normalize_parent_ptrs(node); |
| | 355 | return node; |
| | 356 | } |
| 316 | case Type::Record: | 357 | case Type::Record: |
| 317 | { | 358 | { |
| 318 | const RecordType *record_ty = static_cast<const RecordType*>(ty); | 359 | const RecordType *record_ty = static_cast<const RecordType*>(ty); |
| ... | @@ -356,6 +397,11 @@ static AstNode *make_type_node(Context *c, const Type *ty, const Decl *decl, | ... | @@ -356,6 +397,11 @@ static AstNode *make_type_node(Context *c, const Type *ty, const Decl *decl, |
| 356 | uint64_t size = const_arr_ty->getSize().getLimitedValue(); | 397 | uint64_t size = const_arr_ty->getSize().getLimitedValue(); |
| 357 | return create_array_type_node(c, child_type_node, size, false); | 398 | return create_array_type_node(c, child_type_node, size, false); |
| 358 | } | 399 | } |
| | 400 | case Type::Paren: |
| | 401 | { |
| | 402 | const ParenType *paren_ty = static_cast<const ParenType *>(ty); |
| | 403 | return make_qual_type_node(c, paren_ty->getInnerType(), decl); |
| | 404 | } |
| 359 | case Type::BlockPointer: | 405 | case Type::BlockPointer: |
| 360 | case Type::LValueReference: | 406 | case Type::LValueReference: |
| 361 | case Type::RValueReference: | 407 | case Type::RValueReference: |
| ... | @@ -368,7 +414,6 @@ static AstNode *make_type_node(Context *c, const Type *ty, const Decl *decl, | ... | @@ -368,7 +414,6 @@ static AstNode *make_type_node(Context *c, const Type *ty, const Decl *decl, |
| 368 | case Type::ExtVector: | 414 | case Type::ExtVector: |
| 369 | case Type::FunctionNoProto: | 415 | case Type::FunctionNoProto: |
| 370 | case Type::UnresolvedUsing: | 416 | case Type::UnresolvedUsing: |
| 371 | case Type::Paren: | | |
| 372 | case Type::Adjusted: | 417 | case Type::Adjusted: |
| 373 | case Type::Decayed: | 418 | case Type::Decayed: |
| 374 | case Type::TypeOfExpr: | 419 | case Type::TypeOfExpr: |
| ... | @@ -423,23 +468,19 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { | ... | @@ -423,23 +468,19 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 423 | int arg_count = fn_decl->getNumParams(); | 468 | int arg_count = fn_decl->getNumParams(); |
| 424 | for (int i = 0; i < arg_count; i += 1) { | 469 | for (int i = 0; i < arg_count; i += 1) { |
| 425 | const ParmVarDecl *param = fn_decl->getParamDecl(i); | 470 | const ParmVarDecl *param = fn_decl->getParamDecl(i); |
| 426 | AstNode *param_decl_node = create_node(c, NodeTypeParamDecl); | | |
| 427 | const char *name = decl_name(param); | 471 | const char *name = decl_name(param); |
| 428 | if (strlen(name) == 0) { | 472 | if (strlen(name) == 0) { |
| 429 | name = buf_ptr(buf_sprintf("arg%d", i)); | 473 | name = buf_ptr(buf_sprintf("arg%d", i)); |
| 430 | } | 474 | } |
| 431 | buf_init_from_str(&param_decl_node->data.param_decl.name, name); | | |
| 432 | QualType qt = param->getOriginalType(); | 475 | QualType qt = param->getOriginalType(); |
| 433 | param_decl_node->data.param_decl.is_noalias = qt.isRestrictQualified(); | 476 | bool is_noalias = qt.isRestrictQualified(); |
| 434 | param_decl_node->data.param_decl.type = make_qual_type_node(c, qt, fn_decl); | 477 | AstNode *type_node = make_qual_type_node(c, qt, fn_decl); |
| 435 | if (!param_decl_node->data.param_decl.type) { | 478 | if (!type_node) { |
| 436 | emit_warning(c, param, "skipping function %s, unresolved param type\n", | 479 | emit_warning(c, param, "skipping function %s, unresolved param type\n", name); |
| 437 | buf_ptr(&node->data.fn_proto.name)); | | |
| 438 | return; | 480 | return; |
| 439 | } | 481 | } |
| 440 | | 482 | |
| 441 | normalize_parent_ptrs(param_decl_node); | 483 | node->data.fn_proto.params.append(create_param_decl_node(c, name, type_node, is_noalias)); |
| 442 | node->data.fn_proto.params.append(param_decl_node); | | |
| 443 | } | 484 | } |
| 444 | | 485 | |
| 445 | if (fn_decl->isNoReturn()) { | 486 | if (fn_decl->isNoReturn()) { |
| ... | @@ -512,6 +553,11 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { | ... | @@ -512,6 +553,11 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 512 | node->data.struct_decl.visib_mod = VisibModExport; | 553 | node->data.struct_decl.visib_mod = VisibModExport; |
| 513 | node->data.struct_decl.directives = create_empty_directives(c); | 554 | node->data.struct_decl.directives = create_empty_directives(c); |
| 514 | | 555 | |
| | 556 | // eagerly put the name in the table, but we need to remember to remove it if it fails |
| | 557 | // boy it would be nice to have defer here wouldn't it |
| | 558 | c->enum_type_table.put(bare_name, true); |
| | 559 | |
| | 560 | |
| 515 | ZigList<AstNode *> var_decls = {0}; | 561 | ZigList<AstNode *> var_decls = {0}; |
| 516 | int i = 0; | 562 | int i = 0; |
| 517 | for (auto it = enum_def->enumerator_begin(), | 563 | for (auto it = enum_def->enumerator_begin(), |
| ... | @@ -520,6 +566,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { | ... | @@ -520,6 +566,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 520 | { | 566 | { |
| 521 | const EnumConstantDecl *enum_const = *it; | 567 | const EnumConstantDecl *enum_const = *it; |
| 522 | if (enum_const->getInitExpr()) { | 568 | if (enum_const->getInitExpr()) { |
| | 569 | c->enum_type_table.remove(bare_name); |
| 523 | emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(bare_name)); | 570 | emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(bare_name)); |
| 524 | return; | 571 | return; |
| 525 | } | 572 | } |
| ... | @@ -549,8 +596,6 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { | ... | @@ -549,8 +596,6 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 549 | var_decls.append(var_node); | 596 | var_decls.append(var_node); |
| 550 | } | 597 | } |
| 551 | | 598 | |
| 552 | c->enum_type_table.put(bare_name, true); | | |
| 553 | | | |
| 554 | normalize_parent_ptrs(node); | 599 | normalize_parent_ptrs(node); |
| 555 | c->root->data.root.top_level_decls.append(node); | 600 | c->root->data.root.top_level_decls.append(node); |
| 556 | | 601 | |
| ... | @@ -594,6 +639,10 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) { | ... | @@ -594,6 +639,10 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) { |
| 594 | node->data.struct_decl.visib_mod = VisibModExport; | 639 | node->data.struct_decl.visib_mod = VisibModExport; |
| 595 | node->data.struct_decl.directives = create_empty_directives(c); | 640 | node->data.struct_decl.directives = create_empty_directives(c); |
| 596 | | 641 | |
| | 642 | // eagerly put the name in the table, but we need to remember to remove it if it fails |
| | 643 | // boy it would be nice to have defer here wouldn't it |
| | 644 | c->struct_type_table.put(bare_name, true); |
| | 645 | |
| 597 | for (auto it = record_def->field_begin(), | 646 | for (auto it = record_def->field_begin(), |
| 598 | it_end = record_def->field_end(); | 647 | it_end = record_def->field_end(); |
| 599 | it != it_end; ++it) | 648 | it != it_end; ++it) |
| ... | @@ -601,12 +650,14 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) { | ... | @@ -601,12 +650,14 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) { |
| 601 | const FieldDecl *field_decl = *it; | 650 | const FieldDecl *field_decl = *it; |
| 602 | | 651 | |
| 603 | if (field_decl->isBitField()) { | 652 | if (field_decl->isBitField()) { |
| | 653 | c->struct_type_table.remove(bare_name); |
| 604 | emit_warning(c, field_decl, "skipping struct %s - has bitfield\n", buf_ptr(bare_name)); | 654 | emit_warning(c, field_decl, "skipping struct %s - has bitfield\n", buf_ptr(bare_name)); |
| 605 | return; | 655 | return; |
| 606 | } | 656 | } |
| 607 | | 657 | |
| 608 | AstNode *type_node = make_qual_type_node(c, field_decl->getType(), field_decl); | 658 | AstNode *type_node = make_qual_type_node(c, field_decl->getType(), field_decl); |
| 609 | if (!type_node) { | 659 | if (!type_node) { |
| | 660 | c->struct_type_table.remove(bare_name); |
| 610 | emit_warning(c, field_decl, "skipping struct %s - unhandled type\n", buf_ptr(bare_name)); | 661 | emit_warning(c, field_decl, "skipping struct %s - unhandled type\n", buf_ptr(bare_name)); |
| 611 | return; | 662 | return; |
| 612 | } | 663 | } |
| ... | @@ -615,7 +666,6 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) { | ... | @@ -615,7 +666,6 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) { |
| 615 | node->data.struct_decl.fields.append(field_node); | 666 | node->data.struct_decl.fields.append(field_node); |
| 616 | } | 667 | } |
| 617 | | 668 | |
| 618 | c->struct_type_table.put(bare_name, true); | | |
| 619 | normalize_parent_ptrs(node); | 669 | normalize_parent_ptrs(node); |
| 620 | c->root->data.root.top_level_decls.append(node); | 670 | c->root->data.root.top_level_decls.append(node); |
| 621 | | 671 | |