1 module d.llvm.constant;
2 
3 import d.llvm.codegen;
4 
5 import d.ir.expression;
6 
7 import util.visitor;
8 
9 import llvm.c.core;
10 
11 struct ConstantGen {
12 	private CodeGen pass;
13 	alias pass this;
14 	
15 	this(CodeGen pass) {
16 		this.pass = pass;
17 	}
18 	
19 	// XXX: This should be removed at some point, but to ease transition.
20 	LLVMValueRef visit(Expression e) {
21 		if (auto ce = cast(CompileTimeExpression) e) {
22 			return visit(ce);
23 		}
24 		
25 		assert(0, "Expected a compile time expression, not " ~ typeid(e).toString());
26 	}
27 	
28 	LLVMValueRef visit(CompileTimeExpression e) {
29 		return this.dispatch!(function LLVMValueRef(Expression e) {
30 			import source.exception;
31 			throw new CompileException(
32 				e.location,
33 				typeid(e).toString() ~ " is not supported",
34 			);
35 		})(e);
36 	}
37 	
38 	LLVMValueRef visit(BooleanLiteral bl) {
39 		import d.llvm.type;
40 		return LLVMConstInt(TypeGen(pass).visit(bl.type), bl.value, false);
41 	}
42 	
43 	LLVMValueRef visit(IntegerLiteral il) {
44 		import d.ir.type, d.llvm.type;
45 		return LLVMConstInt(
46 			TypeGen(pass).visit(il.type),
47 			il.value,
48 			il.type.builtin.isSigned(),
49 		);
50 	}
51 	
52 	LLVMValueRef visit(FloatLiteral fl) {
53 		import d.llvm.type;
54 		return LLVMConstReal(TypeGen(pass).visit(fl.type), fl.value);
55 	}
56 	
57 	// XXX: character types in backend ?
58 	LLVMValueRef visit(CharacterLiteral cl) {
59 		import d.llvm.type;
60 		return LLVMConstInt(TypeGen(pass).visit(cl.type), cl.value, false);
61 	}
62 	
63 	LLVMValueRef visit(NullLiteral nl) {
64 		import d.llvm.type;
65 		return LLVMConstNull(TypeGen(pass).visit(nl.type));
66 	}
67 	
68 	LLVMValueRef visit(StringLiteral sl) {
69 		return buildDString(sl.value);
70 	}
71 	
72 	LLVMValueRef visit(VoidInitializer v) {
73 		import d.llvm.type;
74 		return LLVMGetUndef(TypeGen(pass).visit(v.type));
75 	}
76 	
77 	LLVMValueRef visit(CompileTimeTupleExpression e) {
78 		import std.algorithm, std.array;
79 		auto elts = e.values.map!(v => visit(v)).array();
80 		
81 		import d.llvm.type;
82 		auto t = TypeGen(pass).visit(e.type);
83 		
84 		switch(LLVMGetTypeKind(t)) with(LLVMTypeKind) {
85 			case Struct :
86 				return LLVMConstNamedStruct(
87 					t,
88 					elts.ptr,
89 					cast(uint) elts.length,
90 				);
91 			
92 			case Array :
93 				return LLVMConstArray(
94 					LLVMGetElementType(t),
95 					elts.ptr,
96 					cast(uint) elts.length,
97 				);
98 			
99 			default :
100 				break;
101 		}
102 		
103 		assert(0, "Invalid type tuple.");
104 	}
105 }