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