1 module d.semantic.sizeof;
2 
3 import d.semantic.semantic;
4 
5 import d.ir.symbol;
6 import d.ir.type;
7 
8 // Conflict with Interface in object.di
9 alias Interface = d.ir.symbol.Interface;
10 
11 struct SizeofVisitor {
12 	private SemanticPass pass;
13 	alias pass this;
14 
15 	this(SemanticPass pass) {
16 		this.pass = pass;
17 	}
18 
19 	uint visit(Type t) {
20 		return t.accept(this);
21 	}
22 
23 	uint visit(BuiltinType t) {
24 		return (t == BuiltinType.Null) ? getPointerSize() : getSize(t);
25 	}
26 
27 	uint visitPointerOf(Type t) {
28 		return getPointerSize();
29 	}
30 
31 	uint visitSliceOf(Type t) {
32 		return 2 * getPointerSize();
33 	}
34 
35 	uint visitArrayOf(uint size, Type t) {
36 		return size * visit(t);
37 	}
38 
39 	uint visit(Struct s) {
40 		scheduler.require(s, Step.Signed);
41 		return dataLayout.getSize(Type.get(s));
42 	}
43 
44 	uint visit(Class c) {
45 		return getPointerSize();
46 	}
47 
48 	uint visit(Enum e) {
49 		scheduler.require(e);
50 		return visit(e.type);
51 	}
52 
53 	uint visit(TypeAlias a) {
54 		scheduler.require(a);
55 		return visit(a.type);
56 	}
57 
58 	uint visit(Interface i) {
59 		return 2 * getPointerSize();
60 	}
61 
62 	uint visit(Union u) {
63 		scheduler.require(u, Step.Signed);
64 		return dataLayout.getSize(Type.get(u));
65 	}
66 
67 	uint visit(Function f) {
68 		assert(0, "context.sizeof is not implemented.");
69 	}
70 
71 	uint visit(Type[] seq) {
72 		assert(0, "sequence.sizeof is not implemented.");
73 	}
74 
75 	uint visit(FunctionType f) {
76 		auto ptrSize = getPointerSize();
77 		return (f.contexts.length > 0) ? 2 * ptrSize : ptrSize;
78 	}
79 
80 	uint visit(Pattern p) {
81 		assert(0, "Pattern has no size.");
82 	}
83 
84 	import d.ir.error;
85 	uint visit(CompileError e) {
86 		import source.exception;
87 		throw new CompileException(e.location, e.message);
88 	}
89 
90 	private uint getPointerSize() {
91 		return visit(pass.object.getSizeT().type);
92 	}
93 }