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)
25 			? getPointerSize()
26 			: getSize(t);
27 	}
28 	
29 	uint visitPointerOf(Type t) {
30 		return getPointerSize();
31 	}
32 	
33 	uint visitSliceOf(Type t) {
34 		return 2 * getPointerSize();
35 	}
36 	
37 	uint visitArrayOf(uint size, Type t) {
38 		return size * visit(t);
39 	}
40 	
41 	uint visit(Struct s) {
42 		scheduler.require(s, Step.Signed);
43 		return dataLayout.getSize(Type.get(s));
44 	}
45 	
46 	uint visit(Class c) {
47 		return getPointerSize();
48 	}
49 	
50 	uint visit(Enum e) {
51 		scheduler.require(e);
52 		return visit(e.type);
53 	}
54 	
55 	uint visit(TypeAlias a) {
56 		scheduler.require(a);
57 		return visit(a.type);
58 	}
59 	
60 	uint visit(Interface i) {
61 		return 2 * getPointerSize();
62 	}
63 	
64 	uint visit(Union u) {
65 		scheduler.require(u, Step.Signed);
66 		return dataLayout.getSize(Type.get(u));
67 	}
68 	
69 	uint visit(Function f) {
70 		assert(0, "context.sizeof is not implemented.");
71 	}
72 	
73 	uint visit(Type[] seq) {
74 		assert(0, "sequence.sizeof is not implemented.");
75 	}
76 	
77 	uint visit(FunctionType f) {
78 		auto ptrSize = getPointerSize();
79 		return (f.contexts.length > 0)
80 			? 2 * ptrSize
81 			: ptrSize;
82 	}
83 	
84 	uint visit(Pattern p) {
85 		assert(0, "Pattern has no size.");
86 	}
87 	
88 	import d.ir.error;
89 	uint visit(CompileError e) {
90 		import source.exception;
91 		throw new CompileException(e.location, e.message);
92 	}
93 	
94 	private uint getPointerSize() {
95 		return visit(pass.object.getSizeT().type);
96 	}
97 }
98