1 /// Copyright: Copyright (c) 2017-2019 Andrey Penechko. 2 /// License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 3 /// Authors: Andrey Penechko. 4 module vox.fe.ast.type.ptr; 5 6 import vox.all; 7 8 @(AstType.type_ptr) 9 struct PtrTypeNode { 10 mixin AstNodeData!(AstType.type_ptr, AstFlags.isType, AstNodeState.name_register_self_done); 11 AstIndex type = CommonAstNodes.type_type; 12 TypeNode* typeNode() return { return cast(TypeNode*)&this; } 13 AstIndex base; 14 IrIndex irType; 15 enum sizealign = SizeAndAlignment(POINTER_SIZE, POINTER_ALIGN_POW); 16 bool isVoidPtr(CompilationContext* context) { 17 return context.getAstType(base).isVoid; 18 } 19 20 IrIndex gen_init_value(CompilationContext* c) 21 { 22 return c.constants.addZeroConstant(gen_ir_type_ptr(&this, c)); 23 } 24 } 25 26 void print_ptr(PtrTypeNode* node, ref AstPrintState state) 27 { 28 state.print("TYPE ", node.typeNode.printer(state.context)); 29 } 30 31 void post_clone_ptr(PtrTypeNode* node, ref CloneState state) 32 { 33 state.fixAstIndex(node.base); 34 } 35 36 void name_register_nested_ptr(PtrTypeNode* node, ref NameRegisterState state) { 37 node.state = AstNodeState.name_register_nested; 38 require_name_register(node.base, state); 39 node.state = AstNodeState.name_register_nested_done; 40 } 41 42 void name_resolve_ptr(PtrTypeNode* node, ref NameResolveState state) 43 { 44 node.state = AstNodeState.name_resolve; 45 require_name_resolve(node.base, state); 46 node.state = AstNodeState.name_resolve_done; 47 } 48 49 void type_check_ptr(PtrTypeNode* node, ref TypeCheckState state) 50 { 51 node.state = AstNodeState.type_check; 52 require_type_check(node.base, state); 53 node.state = AstNodeState.type_check_done; 54 } 55 56 bool same_type_ptr(PtrTypeNode* t1, PtrTypeNode* t2, CompilationContext* context) 57 { 58 return same_type(t1.base, t2.base, context); 59 } 60 61 CommonTypeResult common_type_ptr(PtrTypeNode* node, AstIndex typeBIndex, CompilationContext* c) 62 { 63 TypeNode* typeB = typeBIndex.get_type(c); 64 switch(typeB.astType) with(AstType) 65 { 66 case type_basic: 67 BasicType basicB = typeB.as_basic.basicType; 68 if (basicB == BasicType.t_null) { 69 return CommonTypeResult(c.getAstNodeIndex(node), TypeConvResKind.no_i, TypeConvResKind.override_expr_type_i); 70 } 71 goto default; 72 case type_ptr: 73 if (typeB.as_ptr.base == CommonAstNodes.type_void) { 74 return CommonTypeResult(c.getAstNodeIndex(node), TypeConvResKind.ii_i, TypeConvResKind.no_i); 75 } 76 goto default; 77 default: return CommonTypeResult(CommonAstNodes.type_error); 78 } 79 } 80 81 TypeConvResKind type_conv_ptr(PtrTypeNode* node, AstIndex typeBIndex, ref AstIndex expr, CompilationContext* c) 82 { 83 TypeNode* typeB = typeBIndex.get_type(c); 84 switch(typeB.astType) with(AstType) { 85 case type_basic: 86 auto toBasic = typeB.as_basic.basicType; 87 if (toBasic.isInteger) return TypeConvResKind.ii_e; 88 if (toBasic.isBoolean) return TypeConvResKind.ii_i; 89 return TypeConvResKind.fail; 90 case type_ptr: 91 if (typeB.as_ptr.base == CommonAstNodes.type_void) return TypeConvResKind.ii_i; 92 return TypeConvResKind.ii_e; 93 default: return TypeConvResKind.fail; 94 } 95 } 96 97 IrIndex gen_ir_type_ptr(PtrTypeNode* t, CompilationContext* context) 98 out(res; res.isTypePointer, "Not a pointer type") 99 { 100 if (t.irType.isDefined) return t.irType; 101 IrIndex baseType = t.base.gen_ir_type(context, AllowHeaderOnly.yes); 102 t.irType = context.types.appendPtr(baseType); 103 return t.irType; 104 }