diff options
| author | gingerBill <bill@gingerbill.org> | 2018-11-11 17:08:30 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2018-11-11 17:08:30 +0000 |
| commit | b55b1ffe14bc4a7459cd9b9bdb8b9b0c8f7f8091 (patch) | |
| tree | 77df172a7e387801f9f43999dcc412a6fb5b71be /src | |
| parent | 620d5d34f7c5712be27a92e1ab6ab48119f0a4c6 (diff) | |
`opaque` keyword and type
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_decl.cpp | 3 | ||||
| -rw-r--r-- | src/check_expr.cpp | 12 | ||||
| -rw-r--r-- | src/check_type.cpp | 7 | ||||
| -rw-r--r-- | src/checker.cpp | 6 | ||||
| -rw-r--r-- | src/ir.cpp | 12 | ||||
| -rw-r--r-- | src/ir_print.cpp | 4 | ||||
| -rw-r--r-- | src/parser.cpp | 17 | ||||
| -rw-r--r-- | src/parser.hpp | 4 | ||||
| -rw-r--r-- | src/tokenizer.cpp | 1 | ||||
| -rw-r--r-- | src/types.cpp | 48 |
10 files changed, 110 insertions, 4 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp index de0aa572d..3fb53bb19 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -198,6 +198,9 @@ bool is_type_distinct(Ast *node) { case Ast_DynamicArrayType: case Ast_MapType: return false; + + case Ast_OpaqueType: + return true; } return false; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 6b2a07a86..61bf9eeca 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1911,6 +1911,13 @@ bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) { return true; } + if (is_type_opaque(src)) { + return are_types_identical(dst, src->Opaque.elem); + } + if (is_type_opaque(dst)) { + return are_types_identical(dst->Opaque.elem, src); + } + return false; } @@ -6602,6 +6609,11 @@ gbString write_expr_to_string(gbString str, Ast *node) { str = write_expr_to_string(str, ht->type); case_end; + case_ast_node(ht, OpaqueType, node); + str = gb_string_appendc(str, "opaque "); + str = write_expr_to_string(str, ht->type); + case_end; + case_ast_node(pt, PolyType, node); str = gb_string_append_rune(str, '$'); str = write_expr_to_string(str, pt->type); diff --git a/src/check_type.cpp b/src/check_type.cpp index f38826a25..5bb404ae8 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2341,6 +2341,13 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t return true; case_end; + case_ast_node(ot, OpaqueType, e); + Type *elem = strip_opaque_type(check_type(ctx, ot->type)); + *type = alloc_type_opaque(elem); + set_base_type(named_type, *type); + return true; + case_end; + case_ast_node(at, ArrayType, e); if (at->count != nullptr) { Operand o = {}; diff --git a/src/checker.cpp b/src/checker.cpp index 5daefc896..d289d236c 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1064,6 +1064,10 @@ void add_type_info_type(CheckerContext *c, Type *t) { add_type_info_type(c, bt->BitSet.elem); break; + case Type_Opaque: + add_type_info_type(c, bt->Opaque.elem); + break; + case Type_Union: add_type_info_type(c, t_int); add_type_info_type(c, t_type_info_ptr); @@ -1626,6 +1630,7 @@ void init_core_type_info(Checker *c) { t_type_info_map = find_core_type(c, str_lit("Type_Info_Map")); t_type_info_bit_field = find_core_type(c, str_lit("Type_Info_Bit_Field")); t_type_info_bit_set = find_core_type(c, str_lit("Type_Info_Bit_Set")); + t_type_info_opaque = find_core_type(c, str_lit("Type_Info_Opaque")); t_type_info_named_ptr = alloc_type_pointer(t_type_info_named); t_type_info_integer_ptr = alloc_type_pointer(t_type_info_integer); @@ -1648,6 +1653,7 @@ void init_core_type_info(Checker *c) { t_type_info_map_ptr = alloc_type_pointer(t_type_info_map); t_type_info_bit_field_ptr = alloc_type_pointer(t_type_info_bit_field); t_type_info_bit_set_ptr = alloc_type_pointer(t_type_info_bit_set); + t_type_info_opaque_ptr = alloc_type_pointer(t_type_info_opaque); } void init_mem_allocator(Checker *c) { diff --git a/src/ir.cpp b/src/ir.cpp index 6f1637b7a..39c7eb25c 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -2273,6 +2273,10 @@ irDebugInfo *ir_add_debug_info_type(irModule *module, Type *type, Entity *e, irD return di; } + if (is_type_opaque(type)) { + return ir_add_debug_info_type(module, strip_opaque_type(type), e, scope, file); + } + if (is_type_struct(type) || is_type_union(type) || is_type_enum(type) || is_type_tuple(type)) { if (type->kind == Type_Named) { @@ -9455,10 +9459,14 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), ir_const_i64(t->BitSet.upper)); break; - - + case Type_Opaque: + ir_emit_comment(proc, str_lit("Type_Opaque")); + tag = ir_emit_conv(proc, variant_ptr, t_type_info_opaque_ptr); + ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), ir_get_type_info_ptr(proc, t->Opaque.elem)); + break; } + if (tag != nullptr) { Type *tag_type = type_deref(ir_type(tag)); GB_ASSERT(is_type_named(tag_type)); diff --git a/src/ir_print.cpp b/src/ir_print.cpp index c8b255d2f..1879e6d78 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -512,6 +512,10 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) { ir_print_type(f, m, bit_set_to_int(t)); return; } + + case Type_Opaque: + ir_print_type(f, m, strip_opaque_type(t)); + return; } } diff --git a/src/parser.cpp b/src/parser.cpp index 38678a6dc..e7181bfbb 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -80,6 +80,7 @@ Token ast_token(Ast *node) { case Ast_TypeidType: return node->TypeidType.token; case Ast_HelperType: return node->HelperType.token; case Ast_DistinctType: return node->DistinctType.token; + case Ast_OpaqueType: return node->OpaqueType.token; case Ast_PolyType: return node->PolyType.token; case Ast_ProcType: return node->ProcType.token; case Ast_PointerType: return node->PointerType.token; @@ -319,6 +320,9 @@ Ast *clone_ast(Ast *node) { case Ast_DistinctType: n->DistinctType.type = clone_ast(n->DistinctType.type); break; + case Ast_OpaqueType: + n->OpaqueType.type = clone_ast(n->OpaqueType.type); + break; case Ast_ProcType: n->ProcType.params = clone_ast(n->ProcType.params); n->ProcType.results = clone_ast(n->ProcType.results); @@ -849,6 +853,13 @@ Ast *ast_distinct_type(AstFile *f, Token token, Ast *type) { return result; } +Ast *ast_opaque_type(AstFile *f, Token token, Ast *type) { + Ast *result = alloc_ast_node(f, Ast_OpaqueType); + result->OpaqueType.token = token; + result->OpaqueType.type = type; + return result; +} + Ast *ast_poly_type(AstFile *f, Token token, Ast *type, Ast *specialization) { Ast *result = alloc_ast_node(f, Ast_PolyType); result->PolyType.token = token; @@ -1654,6 +1665,12 @@ Ast *parse_operand(AstFile *f, bool lhs) { return ast_distinct_type(f, token, type); } + case Token_opaque: { + Token token = expect_token(f, Token_opaque); + Ast *type = parse_type(f); + return ast_opaque_type(f, token, type); + } + case Token_Hash: { Token token = expect_token(f, Token_Hash); Token name = expect_token(f, Token_Ident); diff --git a/src/parser.hpp b/src/parser.hpp index 825e26f32..6a59f05a6 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -434,6 +434,10 @@ AST_KIND(_TypeBegin, "", bool) \ Token token; \ Ast *type; \ }) \ + AST_KIND(OpaqueType, "opaque type", struct { \ + Token token; \ + Ast *type; \ + }) \ AST_KIND(PolyType, "polymorphic type", struct { \ Token token; \ Ast * type; \ diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 3ec491fa7..e2a5827ac 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -113,6 +113,7 @@ TOKEN_KIND(Token__KeywordBegin, ""), \ TOKEN_KIND(Token_cast, "cast"), \ TOKEN_KIND(Token_transmute, "transmute"), \ TOKEN_KIND(Token_distinct, "distinct"), \ + TOKEN_KIND(Token_opaque, "opaque"), \ TOKEN_KIND(Token_using, "using"), \ TOKEN_KIND(Token_inline, "inline"), \ TOKEN_KIND(Token_no_inline, "no_inline"), \ diff --git a/src/types.cpp b/src/types.cpp index f5d1bb4a9..74cc264da 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -127,6 +127,7 @@ struct TypeUnion { Scope *scope; \ }) \ TYPE_KIND(Pointer, struct { Type *elem; }) \ + TYPE_KIND(Opaque, struct { Type *elem; }) \ TYPE_KIND(Array, struct { \ Type *elem; \ i64 count; \ @@ -400,6 +401,7 @@ gb_global Type *t_type_info_enum = nullptr; gb_global Type *t_type_info_map = nullptr; gb_global Type *t_type_info_bit_field = nullptr; gb_global Type *t_type_info_bit_set = nullptr; +gb_global Type *t_type_info_opaque = nullptr; gb_global Type *t_type_info_named_ptr = nullptr; gb_global Type *t_type_info_integer_ptr = nullptr; @@ -423,6 +425,7 @@ gb_global Type *t_type_info_enum_ptr = nullptr; gb_global Type *t_type_info_map_ptr = nullptr; gb_global Type *t_type_info_bit_field_ptr = nullptr; gb_global Type *t_type_info_bit_set_ptr = nullptr; +gb_global Type *t_type_info_opaque_ptr = nullptr; gb_global Type *t_allocator = nullptr; gb_global Type *t_allocator_ptr = nullptr; @@ -461,6 +464,19 @@ Type *base_type(Type *t) { return t; } +Type *strip_opaque_type(Type *t) { + for (;;) { + if (t == nullptr) { + break; + } + if (t->kind != Type_Opaque) { + break; + } + t = t->Opaque.elem; + } + return t; +} + Type *base_enum_type(Type *t) { Type *bt = base_type(t); if (bt != nullptr && @@ -486,6 +502,9 @@ Type *core_type(Type *t) { case Type_Enum: t = t->Enum.base_type; continue; + case Type_Opaque: + t = t->Opaque.elem; + continue; } break; } @@ -519,6 +538,12 @@ Type *alloc_type_generic(Scope *scope, i64 id, String name, Type *specialized) { return t; } +Type *alloc_type_opaque(Type *elem) { + Type *t = alloc_type(Type_Opaque); + t->Opaque.elem = elem; + return t; +} + Type *alloc_type_pointer(Type *elem) { Type *t = alloc_type(Type_Pointer); t->Pointer.elem = elem; @@ -819,8 +844,10 @@ bool is_type_tuple(Type *t) { t = base_type(t); return t->kind == Type_Tuple; } - - +bool is_type_opaque(Type *t) { + t = base_type(t); + return t->kind == Type_Opaque; +} bool is_type_uintptr(Type *t) { if (t->kind == Type_Basic) { return (t->Basic.kind == Basic_uintptr); @@ -1212,6 +1239,8 @@ bool type_has_nil(Type *t) { return true; case Type_Struct: return false; + case Type_Opaque: + return true; } return false; } @@ -1257,6 +1286,9 @@ bool is_type_comparable(Type *t) { case Type_BitSet: return true; + + case Type_Opaque: + return is_type_comparable(t->Opaque.elem); } return false; } @@ -1294,6 +1326,12 @@ bool are_types_identical(Type *x, Type *y) { } break; + case Type_Opaque: + if (y->kind == Type_Opaque) { + return are_types_identical(x->Opaque.elem, y->Opaque.elem); + } + break; + case Type_Basic: if (y->kind == Type_Basic) { return x->Basic.kind == y->Basic.kind; @@ -2061,6 +2099,9 @@ i64 type_align_of_internal(Type *t, TypePath *path) { return align; } + case Type_Opaque: + return type_align_of_internal(t->Opaque.elem, path); + case Type_DynamicArray: // data, count, capacity, allocator return build_context.word_size; @@ -2265,6 +2306,9 @@ i64 type_size_of_internal(Type *t, TypePath *path) { case Type_Pointer: return build_context.word_size; + case Type_Opaque: + return type_size_of_internal(t->Opaque.elem, path); + case Type_Array: { i64 count, align, size, alignment; count = t->Array.count; |