| ... | @@ -234,6 +234,19 @@ static TypeTableEntry *get_c_void_type(Context *c) { | ... | @@ -234,6 +234,19 @@ static TypeTableEntry *get_c_void_type(Context *c) { |
| 234 | return c->c_void_type; | 234 | return c->c_void_type; |
| 235 | } | 235 | } |
| 236 | | 236 | |
| | 237 | static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) { |
| | 238 | if (!c->c_void_type) { |
| | 239 | return false; |
| | 240 | } |
| | 241 | while (type_entry->id == TypeTableEntryIdTypeDecl) { |
| | 242 | if (type_entry == c->c_void_type) { |
| | 243 | return true; |
| | 244 | } |
| | 245 | type_entry = type_entry->data.type_decl.child_type; |
| | 246 | } |
| | 247 | return false; |
| | 248 | } |
| | 249 | |
| 237 | static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl, | 250 | static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl, |
| 238 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table) | 251 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table) |
| 239 | { | 252 | { |
| ... | @@ -243,7 +256,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const | ... | @@ -243,7 +256,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 243 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); | 256 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); |
| 244 | switch (builtin_ty->getKind()) { | 257 | switch (builtin_ty->getKind()) { |
| 245 | case BuiltinType::Void: | 258 | case BuiltinType::Void: |
| 246 | return c->codegen->builtin_types.entry_void; | 259 | return get_c_void_type(c); |
| 247 | case BuiltinType::Bool: | 260 | case BuiltinType::Bool: |
| 248 | return c->codegen->builtin_types.entry_bool; | 261 | return c->codegen->builtin_types.entry_bool; |
| 249 | case BuiltinType::Char_U: | 262 | case BuiltinType::Char_U: |
| ... | @@ -273,6 +286,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const | ... | @@ -273,6 +286,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 273 | case BuiltinType::Double: | 286 | case BuiltinType::Double: |
| 274 | return c->codegen->builtin_types.entry_f64; | 287 | return c->codegen->builtin_types.entry_f64; |
| 275 | case BuiltinType::LongDouble: | 288 | case BuiltinType::LongDouble: |
| | 289 | return c->codegen->builtin_types.entry_c_long_double; |
| 276 | case BuiltinType::WChar_U: | 290 | case BuiltinType::WChar_U: |
| 277 | case BuiltinType::Char16: | 291 | case BuiltinType::Char16: |
| 278 | case BuiltinType::Char32: | 292 | case BuiltinType::Char32: |
| ... | @@ -322,10 +336,6 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const | ... | @@ -322,10 +336,6 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 322 | } | 336 | } |
| 323 | bool is_const = child_qt.isConstQualified(); | 337 | bool is_const = child_qt.isConstQualified(); |
| 324 | | 338 | |
| 325 | if (child_type->id == TypeTableEntryIdVoid) { | | |
| 326 | child_type = get_c_void_type(c); | | |
| 327 | } | | |
| 328 | | | |
| 329 | TypeTableEntry *non_null_pointer_type = get_pointer_to_type(c->codegen, child_type, is_const); | 339 | TypeTableEntry *non_null_pointer_type = get_pointer_to_type(c->codegen, child_type, is_const); |
| 330 | return get_maybe_type(c->codegen, non_null_pointer_type); | 340 | return get_maybe_type(c->codegen, non_null_pointer_type); |
| 331 | } | 341 | } |
| ... | @@ -421,8 +431,13 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const | ... | @@ -421,8 +431,13 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 421 | } else { | 431 | } else { |
| 422 | fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl); | 432 | fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl); |
| 423 | if (get_underlying_type(fn_type_id.return_type)->id == TypeTableEntryIdInvalid) { | 433 | if (get_underlying_type(fn_type_id.return_type)->id == TypeTableEntryIdInvalid) { |
| | 434 | emit_warning(c, decl, "unresolved function proto return type"); |
| 424 | return c->codegen->builtin_types.entry_invalid; | 435 | return c->codegen->builtin_types.entry_invalid; |
| 425 | } | 436 | } |
| | 437 | // convert c_void to actual void (only for return type) |
| | 438 | if (is_c_void_type(c, fn_type_id.return_type)) { |
| | 439 | fn_type_id.return_type = c->codegen->builtin_types.entry_void; |
| | 440 | } |
| 426 | } | 441 | } |
| 427 | | 442 | |
| 428 | fn_type_id.param_info = allocate<FnTypeParamInfo>(fn_type_id.param_count); | 443 | fn_type_id.param_info = allocate<FnTypeParamInfo>(fn_type_id.param_count); |
| ... | @@ -431,6 +446,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const | ... | @@ -431,6 +446,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 431 | TypeTableEntry *param_type = resolve_qual_type(c, qt, decl); | 446 | TypeTableEntry *param_type = resolve_qual_type(c, qt, decl); |
| 432 | | 447 | |
| 433 | if (get_underlying_type(param_type)->id == TypeTableEntryIdInvalid) { | 448 | if (get_underlying_type(param_type)->id == TypeTableEntryIdInvalid) { |
| | 449 | emit_warning(c, decl, "unresolved function proto parameter type"); |
| 434 | return c->codegen->builtin_types.entry_invalid; | 450 | return c->codegen->builtin_types.entry_invalid; |
| 435 | } | 451 | } |
| 436 | | 452 | |
| ... | @@ -466,6 +482,10 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const | ... | @@ -466,6 +482,10 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 466 | { | 482 | { |
| 467 | const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty); | 483 | const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty); |
| 468 | TypeTableEntry *child_type = resolve_qual_type(c, const_arr_ty->getElementType(), decl); | 484 | TypeTableEntry *child_type = resolve_qual_type(c, const_arr_ty->getElementType(), decl); |
| | 485 | if (child_type->id == TypeTableEntryIdInvalid) { |
| | 486 | emit_warning(c, decl, "unresolved array element type"); |
| | 487 | return child_type; |
| | 488 | } |
| 469 | uint64_t size = const_arr_ty->getSize().getLimitedValue(); | 489 | uint64_t size = const_arr_ty->getSize().getLimitedValue(); |
| 470 | return get_array_type(c->codegen, child_type, size); | 490 | return get_array_type(c->codegen, child_type, size); |
| 471 | } | 491 | } |
| ... | @@ -601,6 +621,10 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) | ... | @@ -601,6 +621,10 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) |
| 601 | // TODO | 621 | // TODO |
| 602 | | 622 | |
| 603 | TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl); | 623 | TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl); |
| | 624 | if (child_type->id == TypeTableEntryIdInvalid) { |
| | 625 | emit_warning(c, typedef_decl, "typedef %s - unresolved child type", buf_ptr(type_name)); |
| | 626 | return; |
| | 627 | } |
| 604 | TypeTableEntry *decl_type = get_typedecl_type(c->codegen, buf_ptr(type_name), child_type); | 628 | TypeTableEntry *decl_type = get_typedecl_type(c->codegen, buf_ptr(type_name), child_type); |
| 605 | add_typedef_node(c, decl_type); | 629 | add_typedef_node(c, decl_type); |
| 606 | } | 630 | } |