1 module d.semantic.type; 2 3 import d.semantic.semantic; 4 5 import d.ast.identifier; 6 import d.ast.type; 7 8 import d.ir.type; 9 10 struct TypeVisitor { 11 private SemanticPass pass; 12 alias pass this; 13 14 private TypeQualifier qualifier; 15 16 this(SemanticPass pass, TypeQualifier qualifier = TypeQualifier.Mutable) { 17 this.pass = pass; 18 this.qualifier = qualifier; 19 } 20 21 import d.ast.declaration; 22 TypeVisitor withStorageClass(StorageClass stc) { 23 return TypeVisitor( 24 pass, stc.hasQualifier ? qualifier.add(stc.qualifier) : qualifier); 25 } 26 27 Type visit(AstType t) { 28 return t.accept(this).qualify(t.qualifier); 29 } 30 31 ParamType visit(ParamAstType t) { 32 return visit(t.getType()).getParamType(t.paramKind); 33 } 34 35 Type visit(BuiltinType t) { 36 return Type.get(t, qualifier); 37 } 38 39 Type visit(Identifier i) { 40 import d.semantic.identifier; 41 return 42 IdentifierResolver(pass).build(i).apply!(delegate Type(identified) { 43 static if (is(typeof(identified) : Type)) { 44 return identified.qualify(qualifier); 45 } else { 46 import d.ir.error; 47 return getError(identified, i.location, 48 i.toString(pass.context) ~ " (" 49 ~ typeid(identified).toString() 50 ~ ") isn't an type").type; 51 } 52 })(); 53 } 54 55 Type visitPointerOf(AstType t) { 56 return visit(t).getPointer(qualifier); 57 } 58 59 Type visitSliceOf(AstType t) { 60 return visit(t).getSlice(qualifier); 61 } 62 63 Type visitArrayOf(AstExpression size, AstType t) { 64 auto type = visit(t); 65 66 import d.semantic.expression; 67 return buildArray(ExpressionVisitor(pass).visit(size), type); 68 } 69 70 import d.ir.expression; 71 private Type buildArray(Expression size, Type t) { 72 import d.semantic.caster, d.semantic.expression; 73 auto s = evalIntegral(buildImplicitCast( 74 pass, size.location, pass.object.getSizeT().type, size)); 75 76 assert(s <= uint.max, "Array larger than uint.max are not supported"); 77 return t.getArray(cast(uint) s, qualifier); 78 } 79 80 Type visitMapOf(AstType key, AstType t) { 81 visit(t); 82 visit(key); 83 assert(0, "Map are not implemented."); 84 } 85 86 Type visitBracketOf(Identifier ikey, AstType t) { 87 auto type = visit(t); 88 89 import d.semantic.identifier, d.ir.symbol; 90 return IdentifierResolver(pass).build(ikey) 91 .apply!(delegate Type(identified) { 92 alias T = typeof(identified); 93 static if (is(T : Type)) { 94 assert(0, "Not implemented."); 95 } else static if (is(T : Expression)) { 96 return buildArray(identified, type); 97 } else if (auto v = cast(ValueTemplateParameter) identified) { 98 return Pattern(type, v).getType(); 99 } else { 100 import d.ir.error; 101 return getError( 102 identified, ikey.location, ikey.toString(pass.context) 103 ~ " isn't an type or an expression").type; 104 } 105 })(); 106 } 107 108 Type visit(FunctionAstType t) { 109 auto ctxCount = t.contexts.length; 110 auto f = t.getFunction(); 111 112 ParamType[] paramTypes; 113 paramTypes.length = f.parameters.length; 114 115 auto oldQualifier = qualifier; 116 scope(exit) qualifier = oldQualifier; 117 118 foreach (i; 0 .. ctxCount) { 119 paramTypes[i] = visit(f.parameters[i]); 120 } 121 122 qualifier = TypeQualifier.Mutable; 123 124 auto returnType = visit(t.returnType); 125 foreach (i; ctxCount .. paramTypes.length) { 126 paramTypes[i] = visit(f.parameters[i]); 127 } 128 129 return FunctionType(t.linkage, returnType, paramTypes, t.isVariadic) 130 .getDelegate(ctxCount).getType(oldQualifier); 131 } 132 133 import d.ast.expression; 134 Type visit(AstExpression e) { 135 import d.semantic.expression; 136 return ExpressionVisitor(pass).visit(e).type.qualify(qualifier); 137 } 138 139 Type visitTypeOfReturn() { 140 assert(0, "typeof(return) is not implemented."); 141 } 142 }