Mercurial > projects > ldc
annotate gen/toir.c @ 54:28e99b04a132 trunk
[svn r58] Fixed cond expression resulting in a non-basic type.
Fixed identity expression for dynamic arrays.
Revamped the system to keep track of lvalues and rvalues and their relations.
Typedef declaration now generate the custom typeinfo.
Other bugfixes.
author | lindquist |
---|---|
date | Wed, 24 Oct 2007 01:37:34 +0200 |
parents | 06ccc817acd4 |
children | 0ccfae271c45 |
rev | line source |
---|---|
1 | 1 // Backend stubs |
2 | |
3 /* DMDFE backend stubs | |
4 * This file contains the implementations of the backend routines. | |
5 * For dmdfe these do nothing but print a message saying the module | |
6 * has been parsed. Substitute your own behaviors for these routimes. | |
7 */ | |
8 | |
9 #include <stdio.h> | |
10 #include <math.h> | |
11 #include <sstream> | |
12 #include <fstream> | |
13 #include <iostream> | |
14 | |
40 | 15 #include "gen/llvm.h" |
1 | 16 |
17 #include "total.h" | |
18 #include "init.h" | |
19 #include "symbol.h" | |
20 #include "mtype.h" | |
21 #include "hdrgen.h" | |
22 #include "port.h" | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
23 |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
24 #include "gen/irstate.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
25 #include "gen/elem.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
26 #include "gen/logger.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
27 #include "gen/tollvm.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
28 #include "gen/runtime.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
29 #include "gen/arrays.h" |
1 | 30 |
31 ////////////////////////////////////////////////////////////////////////////////////////// | |
32 | |
33 elem* DeclarationExp::toElem(IRState* p) | |
34 { | |
35 Logger::print("DeclarationExp::toElem: %s | T=%s\n", toChars(), type->toChars()); | |
36 LOG_SCOPE; | |
37 elem* e = new elem; | |
38 | |
39 // variable declaration | |
40 if (VarDeclaration* vd = declaration->isVarDeclaration()) | |
41 { | |
42 Logger::println("VarDeclaration"); | |
43 | |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
44 // static |
26
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
25
diff
changeset
|
45 if (vd->isDataseg()) |
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
25
diff
changeset
|
46 { |
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
25
diff
changeset
|
47 vd->toObjFile(); |
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
25
diff
changeset
|
48 } |
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
25
diff
changeset
|
49 else |
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
25
diff
changeset
|
50 { |
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
25
diff
changeset
|
51 Logger::println("vdtype = %s", vd->type->toChars()); |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
52 // referenced by nested delegate? |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
53 if (vd->nestedref) { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
54 Logger::println("has nestedref set"); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
55 vd->llvmValue = p->func().decl->llvmNested; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
56 assert(vd->llvmValue); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
57 assert(vd->llvmNestedIndex >= 0); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
58 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
59 // normal stack variable |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
60 else { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
61 // allocate storage on the stack |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
62 const llvm::Type* lltype = LLVM_DtoType(vd->type); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
63 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
64 //allocainst->setAlignment(vd->type->alignsize()); // TODO |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
65 vd->llvmValue = allocainst; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
66 } |
40 | 67 LLVM_DtoInitializer(vd->init); |
26
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
25
diff
changeset
|
68 } |
1 | 69 } |
70 // struct declaration | |
71 else if (StructDeclaration* s = declaration->isStructDeclaration()) | |
72 { | |
73 Logger::println("StructDeclaration"); | |
74 s->toObjFile(); | |
75 } | |
40 | 76 // function declaration |
77 else if (FuncDeclaration* f = declaration->isFuncDeclaration()) | |
78 { | |
79 Logger::println("FuncDeclaration"); | |
80 f->toObjFile(); | |
81 } | |
82 // alias declaration | |
83 else if (AliasDeclaration* a = declaration->isAliasDeclaration()) | |
84 { | |
85 Logger::println("AliasDeclaration"); | |
52 | 86 assert(0); |
87 } | |
88 else if (EnumDeclaration* e = declaration->isEnumDeclaration()) | |
89 { | |
90 // do nothing | |
40 | 91 } |
1 | 92 // unsupported declaration |
93 else | |
94 { | |
95 error("Only Var/Struct-Declaration is supported for DeclarationExp"); | |
52 | 96 assert(0); |
1 | 97 } |
98 return e; | |
99 } | |
100 | |
101 ////////////////////////////////////////////////////////////////////////////////////////// | |
102 | |
103 elem* VarExp::toElem(IRState* p) | |
104 { | |
105 Logger::print("VarExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
106 LOG_SCOPE; | |
107 | |
108 elem* e = new elem; | |
109 | |
110 assert(var); | |
111 if (VarDeclaration* vd = var->isVarDeclaration()) | |
112 { | |
113 Logger::println("VarDeclaration"); | |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
114 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
115 if (vd->nestedref) { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
116 Logger::println("has nested ref"); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
117 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
118 |
40 | 119 // needed to take care of forward references of global variables |
120 if (!vd->llvmTouched && vd->isDataseg()) | |
121 vd->toObjFile(); | |
1 | 122 |
123 if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) | |
124 { | |
125 Logger::println("TypeInfoDeclaration"); | |
126 } | |
127 | |
128 // this must be a dollar expression or some other magic value | |
40 | 129 // or it could be a forward declaration of a global variable |
1 | 130 if (!vd->llvmValue) |
131 { | |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
132 assert(!vd->nestedref); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
133 Logger::println("special - no llvmValue"); |
1 | 134 // dollar |
135 if (!p->arrays.empty()) | |
136 { | |
137 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
6 | 138 //llvm::Value* tmp = new llvm::GetElementPtrInst(p->arrays.back(),zero,zero,"tmp",p->scopebb()); |
139 llvm::Value* tmp = LLVM_DtoGEP(p->arrays.back(),zero,zero,"tmp",p->scopebb()); | |
1 | 140 e->val = new llvm::LoadInst(tmp,"tmp",p->scopebb()); |
141 e->type = elem::VAL; | |
142 } | |
40 | 143 // typeinfo |
144 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) | |
1 | 145 { |
52 | 146 assert(0); |
40 | 147 } |
148 // global forward ref | |
149 else { | |
150 Logger::println("unsupported: %s\n", vd->toChars()); | |
151 assert(0 && "only magic supported is typeinfo"); | |
1 | 152 } |
153 return e; | |
154 } | |
155 | |
156 // function parameter | |
157 if (vd->storage_class & STCparameter) { | |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
158 assert(!vd->nestedref); |
1 | 159 Logger::println("function param"); |
160 if (vd->storage_class & (STCref | STCout)) { | |
161 e->mem = vd->llvmValue; | |
162 e->type = elem::VAR; | |
163 } | |
164 else { | |
40 | 165 if (LLVM_DtoIsPassedByRef(vd->type)) { |
1 | 166 e->mem = vd->llvmValue; |
167 e->type = elem::VAR; | |
168 } | |
169 else { | |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
170 if (llvm::isa<llvm::Argument>(vd->llvmValue)) { |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
171 e->val = vd->llvmValue; |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
172 e->type = elem::VAL; |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
173 e->vardecl = vd; |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
174 } |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
175 else if (llvm::isa<llvm::AllocaInst>(vd->llvmValue)) { |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
176 e->mem = vd->llvmValue; |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
177 e->type = elem::VAR; |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
178 } |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
179 else |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
180 assert(0); |
1 | 181 } |
182 } | |
183 } | |
184 else { | |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
185 // nested variable |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
186 if (vd->nestedref) { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
187 e->mem = LLVM_DtoNestedVariable(vd); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
188 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
189 // normal local variable |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
190 else { |
52 | 191 if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) { |
192 Logger::println("typeinfo varexp"); | |
193 const llvm::Type* vartype = LLVM_DtoType(type); | |
194 if (tid->llvmValue->getType() != llvm::PointerType::get(vartype)) { | |
195 e->mem = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp"); | |
196 } | |
197 else { | |
198 e->mem = tid->llvmValue; | |
199 } | |
200 Logger::cout() << "got:" << '\n' << *tid->llvmValue << "returned:" << '\n' << *e->mem << '\n'; | |
201 } | |
202 else { | |
203 e->mem = vd->llvmValue; | |
204 } | |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
205 } |
1 | 206 e->vardecl = vd; |
207 e->type = elem::VAR; | |
208 } | |
209 } | |
210 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) | |
211 { | |
212 Logger::println("FuncDeclaration"); | |
213 if (fdecl->llvmValue == 0) { | |
214 fdecl->toObjFile(); | |
215 } | |
216 e->val = fdecl->llvmValue; | |
217 e->type = elem::FUNC; | |
218 e->funcdecl = fdecl; | |
219 } | |
220 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) | |
221 { | |
222 // this seems to be the static initialiser for structs | |
40 | 223 Type* sdecltype = LLVM_DtoDType(sdecl->type); |
224 Logger::print("Sym: type=%s\n", sdecltype->toChars()); | |
225 assert(sdecltype->ty == Tstruct); | |
226 TypeStruct* ts = (TypeStruct*)sdecltype; | |
1 | 227 e->mem = ts->llvmInit; |
228 assert(e->mem); | |
229 e->type = elem::VAR; | |
230 } | |
231 else | |
232 { | |
233 assert(0 && "Unimplemented VarExp type"); | |
234 } | |
235 | |
236 assert(e->mem || e->val); | |
237 return e; | |
238 } | |
239 | |
240 ////////////////////////////////////////////////////////////////////////////////////////// | |
241 | |
40 | 242 llvm::Constant* VarExp::toConstElem(IRState* p) |
243 { | |
244 Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | |
245 LOG_SCOPE; | |
246 if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) | |
247 { | |
248 // this seems to be the static initialiser for structs | |
249 Type* sdecltype = LLVM_DtoDType(sdecl->type); | |
250 Logger::print("Sym: type=%s\n", sdecltype->toChars()); | |
251 assert(sdecltype->ty == Tstruct); | |
252 TypeStruct* ts = (TypeStruct*)sdecltype; | |
253 assert(ts->sym->llvmInitZ); | |
254 return ts->sym->llvmInitZ; | |
255 } | |
256 assert(0 && "Only support const var exp is SymbolDeclaration"); | |
257 return NULL; | |
258 } | |
259 | |
260 ////////////////////////////////////////////////////////////////////////////////////////// | |
261 | |
1 | 262 elem* IntegerExp::toElem(IRState* p) |
263 { | |
264 Logger::print("IntegerExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
265 LOG_SCOPE; | |
266 elem* e = new elem; | |
40 | 267 e->val = toConstElem(p); |
268 e->type = elem::CONST; | |
269 return e; | |
270 } | |
271 | |
272 ////////////////////////////////////////////////////////////////////////////////////////// | |
273 | |
274 llvm::Constant* IntegerExp::toConstElem(IRState* p) | |
275 { | |
276 Logger::print("IntegerExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | |
277 LOG_SCOPE; | |
1 | 278 const llvm::Type* t = LLVM_DtoType(type); |
279 if (llvm::isa<llvm::PointerType>(t)) { | |
280 llvm::Constant* i = llvm::ConstantInt::get(LLVM_DtoSize_t(),(uint64_t)value,false); | |
40 | 281 return llvm::ConstantExpr::getIntToPtr(i, t); |
1 | 282 } |
283 else if (llvm::isa<llvm::IntegerType>(t)) { | |
40 | 284 return llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned()); |
1 | 285 } |
40 | 286 assert(0); |
287 return NULL; | |
1 | 288 } |
289 | |
290 ////////////////////////////////////////////////////////////////////////////////////////// | |
291 | |
292 elem* RealExp::toElem(IRState* p) | |
293 { | |
294 Logger::print("RealExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
295 LOG_SCOPE; | |
296 elem* e = new elem; | |
40 | 297 e->val = toConstElem(p); |
298 e->type = elem::CONST; | |
299 return e; | |
300 } | |
301 | |
302 ////////////////////////////////////////////////////////////////////////////////////////// | |
303 | |
304 llvm::Constant* RealExp::toConstElem(IRState* p) | |
305 { | |
306 Logger::print("RealExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | |
307 LOG_SCOPE; | |
6 | 308 const llvm::Type* fty = LLVM_DtoType(type); |
309 if (type->ty == Tfloat32) | |
40 | 310 return llvm::ConstantFP::get(fty,float(value)); |
6 | 311 else if (type->ty == Tfloat64 || type->ty == Tfloat80) |
40 | 312 return llvm::ConstantFP::get(fty,double(value)); |
6 | 313 assert(0); |
40 | 314 return NULL; |
1 | 315 } |
316 | |
317 ////////////////////////////////////////////////////////////////////////////////////////// | |
318 | |
319 elem* NullExp::toElem(IRState* p) | |
320 { | |
321 Logger::print("NullExp::toElem(type=%s): %s\n", type->toChars(),toChars()); | |
322 LOG_SCOPE; | |
323 elem* e = new elem; | |
40 | 324 e->val = toConstElem(p); |
325 e->type = elem::NUL; | |
326 //Logger::cout() << "null value is now " << *e->val << '\n'; | |
327 return e; | |
328 } | |
329 | |
330 ////////////////////////////////////////////////////////////////////////////////////////// | |
331 | |
332 llvm::Constant* NullExp::toConstElem(IRState* p) | |
333 { | |
334 Logger::print("NullExp::toConstElem(type=%s): %s\n", type->toChars(),toChars()); | |
335 LOG_SCOPE; | |
1 | 336 const llvm::Type* t = LLVM_DtoType(type); |
28
1c80c18f3c82
[svn r32] * Fixed problems with arrays members of aggregates
lindquist
parents:
27
diff
changeset
|
337 if (type->ty == Tarray) { |
1c80c18f3c82
[svn r32] * Fixed problems with arrays members of aggregates
lindquist
parents:
27
diff
changeset
|
338 assert(llvm::isa<llvm::StructType>(t)); |
40 | 339 return llvm::ConstantAggregateZero::get(t); |
28
1c80c18f3c82
[svn r32] * Fixed problems with arrays members of aggregates
lindquist
parents:
27
diff
changeset
|
340 } |
40 | 341 else { |
342 return llvm::Constant::getNullValue(t); | |
343 } | |
344 assert(0); | |
345 return NULL; | |
1 | 346 } |
347 | |
348 ////////////////////////////////////////////////////////////////////////////////////////// | |
349 | |
350 elem* StringExp::toElem(IRState* p) | |
351 { | |
52 | 352 Logger::print("StringExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1 | 353 LOG_SCOPE; |
354 | |
40 | 355 Type* dtype = LLVM_DtoDType(type); |
356 | |
357 assert(dtype->next->ty == Tchar && "Only char is supported"); | |
1 | 358 assert(sz == 1); |
359 | |
40 | 360 const llvm::Type* ct = LLVM_DtoType(dtype->next); |
1 | 361 //printf("ct = %s\n", type->next->toChars()); |
362 const llvm::ArrayType* at = llvm::ArrayType::get(ct,len+1); | |
363 | |
364 uint8_t* str = (uint8_t*)string; | |
365 std::string cont((char*)str, len); | |
366 | |
367 llvm::Constant* _init = llvm::ConstantArray::get(cont,true); | |
368 | |
369 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; | |
370 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,"stringliteral",gIR->module); | |
371 | |
21
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
372 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
373 llvm::Constant* idxs[2] = { zero, zero }; |
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
374 llvm::Constant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); |
1 | 375 |
376 elem* e = new elem; | |
377 | |
40 | 378 if (dtype->ty == Tarray) { |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
379 llvm::Constant* clen = llvm::ConstantInt::get(LLVM_DtoSize_t(),len,false); |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
380 if (!p->topexp() || p->topexp()->e2 != this) { |
52 | 381 llvm::Value* tmpmem = new llvm::AllocaInst(LLVM_DtoType(dtype),"tmp",p->topallocapoint()); |
382 LLVM_DtoSetArray(tmpmem, clen, arrptr); | |
383 e->mem = tmpmem; | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
384 } |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
385 else if (p->topexp()->e2 == this) { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
386 llvm::Value* arr = p->topexp()->v; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
387 assert(arr); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
388 LLVM_DtoSetArray(arr, clen, arrptr); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
389 e->inplace = true; |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
390 } |
40 | 391 else |
392 assert(0); | |
1 | 393 } |
40 | 394 else if (dtype->ty == Tsarray) { |
21
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
395 const llvm::Type* dstType = llvm::PointerType::get(llvm::ArrayType::get(ct, len)); |
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
396 e->mem = new llvm::BitCastInst(gvar, dstType, "tmp", gIR->scopebb()); |
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
397 } |
40 | 398 else if (dtype->ty == Tpointer) { |
1 | 399 e->mem = arrptr; |
400 } | |
401 else { | |
402 assert(0); | |
403 } | |
404 | |
405 e->type = elem::VAL; | |
406 | |
407 return e; | |
408 } | |
409 | |
410 ////////////////////////////////////////////////////////////////////////////////////////// | |
411 | |
40 | 412 llvm::Constant* StringExp::toConstElem(IRState* p) |
413 { | |
414 Logger::print("StringExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | |
415 LOG_SCOPE; | |
416 | |
417 uint8_t* str = (uint8_t*)string; | |
418 std::string cont((char*)str, len); | |
419 | |
420 Type* t = LLVM_DtoDType(type); | |
421 | |
422 llvm::Constant* _init = llvm::ConstantArray::get(cont,true); | |
423 if (t->ty == Tsarray) { | |
424 return _init; | |
425 } | |
426 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; | |
427 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,"stringliteral",gIR->module); | |
428 | |
429 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
430 llvm::Constant* idxs[2] = { zero, zero }; | |
431 llvm::Constant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); | |
432 | |
433 if (t->ty == Tpointer) { | |
434 return arrptr; | |
435 } | |
436 | |
437 if (t->ty == Tarray) { | |
438 llvm::Constant* clen = llvm::ConstantInt::get(LLVM_DtoSize_t(),len,false); | |
439 return LLVM_DtoConstantSlice(clen, arrptr); | |
440 } | |
441 | |
442 assert(0); | |
443 return NULL; | |
444 } | |
445 | |
446 ////////////////////////////////////////////////////////////////////////////////////////// | |
447 | |
1 | 448 elem* AssignExp::toElem(IRState* p) |
449 { | |
450 Logger::print("AssignExp::toElem: %s | %s = %s\n", toChars(), e1->type->toChars(), e2->type->toChars()); | |
451 LOG_SCOPE; | |
452 | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
453 p->exps.push_back(IRExp(e1,e2,NULL)); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
454 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
455 elem* l = e1->toElem(p); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
456 p->topexp()->v = l->mem; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
457 elem* r = e2->toElem(p); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
458 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
459 p->exps.pop_back(); |
1 | 460 |
34 | 461 if (l->type == elem::ARRAYLEN) |
462 { | |
463 LLVM_DtoResizeDynArray(l->mem, r->getValue()); | |
464 delete r; | |
465 delete l; | |
466 return 0; | |
467 } | |
468 | |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
469 // handle function argument - allocate temp storage for it :/ annoying |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
470 if (l->mem == 0) { |
34 | 471 assert(l->val); |
472 if (llvm::isa<llvm::Argument>(l->val)) | |
473 LLVM_DtoGiveArgumentStorage(l); | |
474 else { | |
475 Logger::cout() << "here it comes... " << *l->val << '\n'; | |
476 assert(0); | |
477 } | |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
478 } |
1 | 479 //e->val = l->store(r->getValue()); |
480 | |
40 | 481 Type* e1type = LLVM_DtoDType(e1->type); |
482 Type* e2type = LLVM_DtoDType(e2->type); | |
483 TY e1ty = e1type->ty; | |
484 TY e2ty = e2type->ty; | |
1 | 485 |
486 elem* e = new elem; | |
40 | 487 e->type = elem::VAR; |
1 | 488 |
489 // struct | |
490 if (e1ty == Tstruct) { | |
40 | 491 e->mem = l->mem; |
1 | 492 // struct + struct |
493 if (e2ty == Tstruct) { | |
494 // struct literals do the assignment themselvs (in place) | |
495 if (!r->inplace) { | |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
496 LLVM_DtoStructCopy(l->mem,r->getValue()); |
1 | 497 } |
498 else { | |
499 e->inplace = true; | |
500 } | |
501 } | |
502 // struct + const int | |
40 | 503 else if (e2type->isintegral()){ |
1 | 504 IntegerExp* iexp = (IntegerExp*)e2; |
505 assert(iexp->value == 0 && "Only integral struct initializer allowed is zero"); | |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
506 LLVM_DtoStructZeroInit(l->mem); |
1 | 507 } |
508 // :x | |
509 else | |
510 assert(0 && "struct = unknown"); | |
511 } | |
512 else if (e1ty == Tsarray) { | |
40 | 513 assert(0 && "static array not supported"); |
1 | 514 } |
515 else if (e1ty == Tarray) { | |
40 | 516 if (e2type->isscalar() || e2type->ty == Tclass){ |
1 | 517 LLVM_DtoArrayInit(l->mem, r->getValue()); |
518 } | |
519 else if (e2ty == Tarray) { | |
520 //new llvm::StoreInst(r->val,l->val,p->scopebb()); | |
521 if (r->type == elem::NUL) { | |
522 llvm::Constant* c = llvm::cast<llvm::Constant>(r->val); | |
523 assert(c->isNullValue()); | |
524 LLVM_DtoNullArray(l->mem); | |
40 | 525 e->mem = l->mem; |
1 | 526 } |
527 else if (r->type == elem::SLICE) { | |
40 | 528 if (l->type == elem::SLICE) { |
529 LLVM_DtoArrayCopy(l,r); | |
530 e->type = elem::SLICE; | |
531 e->mem = l->mem; | |
532 e->arg = l->arg; | |
533 } | |
534 else { | |
535 LLVM_DtoSetArray(l->mem,r->arg,r->mem); | |
536 e->mem = l->mem; | |
537 } | |
1 | 538 } |
539 else { | |
540 // new expressions write directly to the array reference | |
541 // so do string literals | |
40 | 542 e->mem = l->mem; |
1 | 543 if (!r->inplace) { |
544 assert(r->mem); | |
545 LLVM_DtoArrayAssign(l->mem, r->mem); | |
546 } | |
547 else { | |
548 e->inplace = true; | |
549 } | |
550 } | |
551 } | |
552 else | |
553 assert(0); | |
554 } | |
555 else if (e1ty == Tpointer) { | |
40 | 556 e->mem = l->mem; |
1 | 557 if (e2ty == Tpointer) { |
558 llvm::Value* v = r->field ? r->mem : r->getValue(); | |
559 Logger::cout() << "*=*: " << *v << ", " << *l->mem << '\n'; | |
560 new llvm::StoreInst(v, l->mem, p->scopebb()); | |
561 } | |
562 else | |
563 assert(0); | |
564 } | |
565 else if (e1ty == Tclass) { | |
566 if (e2ty == Tclass) { | |
567 llvm::Value* tmp = r->getValue(); | |
15
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
568 Logger::cout() << "tmp: " << *tmp << " ||| " << *l->mem << '\n'; |
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
569 // assignment to this in constructor special case |
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
570 if (l->isthis) { |
40 | 571 FuncDeclaration* fdecl = p->func().decl; |
15
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
572 // respecify the this param |
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
573 if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar)) |
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
574 fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", p->topallocapoint()); |
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
575 new llvm::StoreInst(tmp, fdecl->llvmThisVar, p->scopebb()); |
40 | 576 e->mem = fdecl->llvmThisVar; |
15
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
577 } |
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
578 // regular class ref -> class ref assignment |
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
579 else { |
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
580 new llvm::StoreInst(tmp, l->mem, p->scopebb()); |
40 | 581 e->mem = l->mem; |
15
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
582 } |
1 | 583 } |
584 else | |
585 assert(0); | |
586 } | |
587 else if (e1ty == Tdelegate) { | |
588 Logger::println("Assigning to delegate"); | |
589 if (e2ty == Tdelegate) { | |
590 if (r->type == elem::NUL) { | |
591 llvm::Constant* c = llvm::cast<llvm::Constant>(r->val); | |
592 if (c->isNullValue()) { | |
593 LLVM_DtoNullDelegate(l->mem); | |
40 | 594 e->mem = l->mem; |
1 | 595 } |
596 else | |
597 assert(0); | |
598 } | |
599 else if (r->inplace) { | |
600 // do nothing | |
601 e->inplace = true; | |
40 | 602 e->mem = l->mem; |
1 | 603 } |
49
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
604 else { |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
605 LLVM_DtoDelegateCopy(l->mem, r->getValue()); |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
606 e->mem = l->mem; |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
607 } |
1 | 608 } |
609 else | |
610 assert(0); | |
611 } | |
612 // !struct && !array && !pointer && !class | |
613 else { | |
614 Logger::cout() << *l->mem << '\n'; | |
615 new llvm::StoreInst(r->getValue(),l->mem,p->scopebb()); | |
40 | 616 e->mem = l->mem; |
1 | 617 } |
618 | |
619 delete r; | |
620 delete l; | |
40 | 621 |
1 | 622 return e; |
623 } | |
624 | |
625 ////////////////////////////////////////////////////////////////////////////////////////// | |
626 | |
627 elem* AddExp::toElem(IRState* p) | |
628 { | |
23 | 629 Logger::print("AddExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1 | 630 LOG_SCOPE; |
631 elem* e = new elem; | |
632 elem* l = e1->toElem(p); | |
633 elem* r = e2->toElem(p); | |
634 | |
40 | 635 Type* t = LLVM_DtoDType(type); |
636 Type* e1type = LLVM_DtoDType(e1->type); | |
637 Type* e2type = LLVM_DtoDType(e2->type); | |
638 | |
639 if (e1type != e2type) { | |
640 if (e1type->ty == Tpointer && e1type->next->ty == Tstruct) { | |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
641 //assert(l->field); |
1 | 642 assert(r->type == elem::CONST); |
643 llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->val); | |
644 | |
40 | 645 TypeStruct* ts = (TypeStruct*)e1type->next; |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
646 std::vector<unsigned> offsets(1,0); |
40 | 647 ts->sym->offsetToIndex(t->next, cofs->getZExtValue(), offsets); |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
648 e->mem = LLVM_DtoGEP(l->getValue(), offsets, "tmp", p->scopebb()); |
1 | 649 e->type = elem::VAR; |
650 e->field = true; | |
651 } | |
652 else if (e1->type->ty == Tpointer) { | |
653 e->val = new llvm::GetElementPtrInst(l->getValue(), r->getValue(), "tmp", p->scopebb()); | |
654 e->type = elem::VAR; | |
655 } | |
656 else { | |
657 assert(0); | |
658 } | |
659 } | |
660 else { | |
661 e->val = llvm::BinaryOperator::createAdd(l->getValue(), r->getValue(), "tmp", p->scopebb()); | |
662 e->type = elem::VAL; | |
663 } | |
664 delete l; | |
665 delete r; | |
666 return e; | |
667 } | |
668 | |
669 ////////////////////////////////////////////////////////////////////////////////////////// | |
670 | |
671 elem* AddAssignExp::toElem(IRState* p) | |
672 { | |
673 Logger::print("AddAssignExp::toElem: %s\n", toChars()); | |
674 LOG_SCOPE; | |
675 | |
676 elem* l = e1->toElem(p); | |
677 elem* r = e2->toElem(p); | |
678 | |
40 | 679 Type* e1type = LLVM_DtoDType(e1->type); |
680 | |
1 | 681 elem* e = new elem; |
682 llvm::Value* val = 0; | |
40 | 683 if (e1type->ty == Tpointer) { |
1 | 684 val = e->mem = new llvm::GetElementPtrInst(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
685 } | |
686 else { | |
687 val = e->val = llvm::BinaryOperator::createAdd(l->getValue(),r->getValue(),"tmp",p->scopebb()); | |
688 } | |
689 | |
690 /*llvm::Value* storeVal = l->storeVal ? l->storeVal : l->val; | |
691 if (llvm::isa<llvm::PointerType>(storeVal->getType()) && storeVal->getType()->getContainedType(0) != tmp->getType()) | |
692 { | |
693 tmp = LLVM_DtoPointedType(storeVal, tmp); | |
694 }*/ | |
695 | |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
696 if (l->mem == 0) |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
697 LLVM_DtoGiveArgumentStorage(l); |
1 | 698 new llvm::StoreInst(val,l->mem,p->scopebb()); |
699 e->type = elem::VAR; | |
700 | |
701 delete l; | |
702 delete r; | |
703 return e; | |
704 } | |
705 | |
706 ////////////////////////////////////////////////////////////////////////////////////////// | |
707 | |
708 elem* MinExp::toElem(IRState* p) | |
709 { | |
710 Logger::print("MinExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
711 LOG_SCOPE; | |
712 elem* e = new elem; | |
713 elem* l = e1->toElem(p); | |
714 elem* r = e2->toElem(p); | |
715 | |
716 llvm::Value* left = l->getValue(); | |
717 if (llvm::isa<llvm::PointerType>(left->getType())) | |
718 left = new llvm::PtrToIntInst(left,LLVM_DtoSize_t(),"tmp",p->scopebb()); | |
719 | |
720 llvm::Value* right = r->getValue(); | |
721 if (llvm::isa<llvm::PointerType>(right->getType())) | |
722 right = new llvm::PtrToIntInst(right,LLVM_DtoSize_t(),"tmp",p->scopebb()); | |
723 | |
724 e->val = llvm::BinaryOperator::createSub(left,right,"tmp",p->scopebb()); | |
725 e->type = elem::VAL; | |
726 | |
727 const llvm::Type* totype = LLVM_DtoType(type); | |
728 if (e->val->getType() != totype) { | |
729 assert(0); | |
730 assert(llvm::isa<llvm::PointerType>(e->val->getType())); | |
731 assert(llvm::isa<llvm::IntegerType>(totype)); | |
732 e->val = new llvm::IntToPtrInst(e->val,totype,"tmp",p->scopebb()); | |
733 } | |
734 | |
735 delete l; | |
736 delete r; | |
737 return e; | |
738 } | |
739 | |
740 ////////////////////////////////////////////////////////////////////////////////////////// | |
741 | |
742 elem* MinAssignExp::toElem(IRState* p) | |
743 { | |
744 Logger::print("MinAssignExp::toElem: %s\n", toChars()); | |
745 LOG_SCOPE; | |
746 | |
747 elem* l = e1->toElem(p); | |
748 elem* r = e2->toElem(p); | |
749 | |
40 | 750 Type* e1type = LLVM_DtoDType(e1->type); |
751 | |
1 | 752 llvm::Value* tmp = 0; |
40 | 753 if (e1type->ty == Tpointer) { |
1 | 754 tmp = r->getValue(); |
755 llvm::Value* zero = llvm::ConstantInt::get(tmp->getType(),0,false); | |
756 tmp = llvm::BinaryOperator::createSub(zero,tmp,"tmp",p->scopebb()); | |
757 tmp = new llvm::GetElementPtrInst(l->getValue(),tmp,"tmp",p->scopebb()); | |
758 } | |
759 else { | |
760 tmp = llvm::BinaryOperator::createSub(l->getValue(),r->getValue(),"tmp",p->scopebb()); | |
761 } | |
762 | |
763 /*llvm::Value* storeVal = l->storeVal ? l->storeVal : l->val; | |
764 if (storeVal->getType()->getContainedType(0) != tmp->getType()) | |
765 { | |
766 tmp = LLVM_DtoPointedType(storeVal, tmp); | |
767 }*/ | |
768 | |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
769 if (l->mem == 0) |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
770 LLVM_DtoGiveArgumentStorage(l); |
1 | 771 new llvm::StoreInst(tmp, l->mem, p->scopebb()); |
772 | |
773 delete l; | |
774 delete r; | |
775 | |
776 elem* e = new elem; | |
777 e->val = tmp; | |
778 e->type = elem::VAR; | |
779 return e; | |
780 } | |
781 | |
782 ////////////////////////////////////////////////////////////////////////////////////////// | |
783 | |
784 elem* MulExp::toElem(IRState* p) | |
785 { | |
786 Logger::print("MulExp::toElem: %s\n", toChars()); | |
787 LOG_SCOPE; | |
788 elem* e = new elem; | |
789 elem* l = e1->toElem(p); | |
790 elem* r = e2->toElem(p); | |
791 llvm::Value* vl = l->getValue(); | |
792 llvm::Value* vr = r->getValue(); | |
793 Logger::cout() << "mul: " << *vl << ", " << *vr << '\n'; | |
794 e->val = llvm::BinaryOperator::createMul(vl,vr,"tmp",p->scopebb()); | |
795 e->type = elem::VAL; | |
796 delete l; | |
797 delete r; | |
798 return e; | |
799 } | |
800 | |
801 ////////////////////////////////////////////////////////////////////////////////////////// | |
802 | |
803 elem* MulAssignExp::toElem(IRState* p) | |
804 { | |
805 Logger::print("MulAssignExp::toElem: %s\n", toChars()); | |
806 LOG_SCOPE; | |
807 | |
808 elem* l = e1->toElem(p); | |
809 elem* r = e2->toElem(p); | |
810 llvm::Value* vl = l->getValue(); | |
811 llvm::Value* vr = r->getValue(); | |
812 Logger::cout() << "mulassign: " << *vl << ", " << *vr << '\n'; | |
813 llvm::Value* tmp = llvm::BinaryOperator::createMul(vl,vr,"tmp",p->scopebb()); | |
814 | |
815 /*llvm::Value* storeVal = l->storeVal ? l->storeVal : l->val; | |
816 if (storeVal->getType()->getContainedType(0) != tmp->getType()) | |
817 { | |
818 tmp = LLVM_DtoPointedType(storeVal, tmp); | |
819 }*/ | |
820 | |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
821 if (l->mem == 0) |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
822 LLVM_DtoGiveArgumentStorage(l); |
1 | 823 new llvm::StoreInst(tmp,l->mem,p->scopebb()); |
824 | |
825 delete l; | |
826 delete r; | |
827 | |
828 elem* e = new elem; | |
829 e->val = tmp; | |
830 e->type = elem::VAR; | |
831 return e; | |
832 } | |
833 | |
834 ////////////////////////////////////////////////////////////////////////////////////////// | |
835 | |
836 elem* DivExp::toElem(IRState* p) | |
837 { | |
838 Logger::print("DivExp::toElem: %s\n", toChars()); | |
839 LOG_SCOPE; | |
840 elem* e = new elem; | |
841 elem* l = e1->toElem(p); | |
842 elem* r = e2->toElem(p); | |
843 | |
40 | 844 Type* t = LLVM_DtoDType(type); |
845 | |
846 if (t->isunsigned()) | |
1 | 847 e->val = llvm::BinaryOperator::createUDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
40 | 848 else if (t->isintegral()) |
1 | 849 e->val = llvm::BinaryOperator::createSDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
40 | 850 else if (t->isfloating()) |
1 | 851 e->val = llvm::BinaryOperator::createFDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
852 else | |
853 assert(0); | |
854 e->type = elem::VAL; | |
855 delete l; | |
856 delete r; | |
857 return e; | |
858 } | |
859 | |
860 ////////////////////////////////////////////////////////////////////////////////////////// | |
861 | |
862 elem* DivAssignExp::toElem(IRState* p) | |
863 { | |
864 Logger::print("DivAssignExp::toElem: %s\n", toChars()); | |
865 LOG_SCOPE; | |
866 | |
867 elem* l = e1->toElem(p); | |
868 elem* r = e2->toElem(p); | |
869 | |
40 | 870 Type* t = LLVM_DtoDType(type); |
871 | |
1 | 872 llvm::Value* tmp; |
40 | 873 if (t->isunsigned()) |
1 | 874 tmp = llvm::BinaryOperator::createUDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
40 | 875 else if (t->isintegral()) |
1 | 876 tmp = llvm::BinaryOperator::createSDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
40 | 877 else if (t->isfloating()) |
1 | 878 tmp = llvm::BinaryOperator::createFDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
879 else | |
880 assert(0); | |
881 | |
882 /*llvm::Value* storeVal = l->storeVal ? l->storeVal : l->val; | |
883 if (storeVal->getType()->getContainedType(0) != tmp->getType()) | |
884 { | |
885 tmp = LLVM_DtoPointedType(storeVal, tmp); | |
886 }*/ | |
887 | |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
888 if (l->mem == 0) |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
889 LLVM_DtoGiveArgumentStorage(l); |
1 | 890 new llvm::StoreInst(tmp,l->mem,p->scopebb()); |
891 | |
892 delete l; | |
893 delete r; | |
894 | |
895 elem* e = new elem; | |
896 e->val = tmp; | |
897 e->type = elem::VAR; | |
898 return e; | |
899 } | |
900 | |
901 ////////////////////////////////////////////////////////////////////////////////////////// | |
902 | |
903 elem* ModExp::toElem(IRState* p) | |
904 { | |
905 Logger::print("ModExp::toElem: %s\n", toChars()); | |
906 LOG_SCOPE; | |
907 elem* e = new elem; | |
908 elem* l = e1->toElem(p); | |
909 elem* r = e2->toElem(p); | |
910 | |
40 | 911 Type* t = LLVM_DtoDType(type); |
912 | |
913 if (t->isunsigned()) | |
1 | 914 e->val = llvm::BinaryOperator::createURem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
40 | 915 else if (t->isintegral()) |
1 | 916 e->val = llvm::BinaryOperator::createSRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
40 | 917 else if (t->isfloating()) |
1 | 918 e->val = llvm::BinaryOperator::createFRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
919 else | |
920 assert(0); | |
921 e->type = elem::VAL; | |
922 delete l; | |
923 delete r; | |
924 return e; | |
925 } | |
926 | |
927 ////////////////////////////////////////////////////////////////////////////////////////// | |
928 | |
929 elem* ModAssignExp::toElem(IRState* p) | |
930 { | |
931 Logger::print("ModAssignExp::toElem: %s\n", toChars()); | |
932 LOG_SCOPE; | |
933 | |
934 elem* l = e1->toElem(p); | |
935 elem* r = e2->toElem(p); | |
936 | |
40 | 937 Type* t = LLVM_DtoDType(type); |
938 | |
1 | 939 llvm::Value* tmp; |
40 | 940 if (t->isunsigned()) |
1 | 941 tmp = llvm::BinaryOperator::createURem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
40 | 942 else if (t->isintegral()) |
1 | 943 tmp = llvm::BinaryOperator::createSRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
40 | 944 else if (t->isfloating()) |
1 | 945 tmp = llvm::BinaryOperator::createFRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
946 else | |
947 assert(0); | |
948 | |
949 /*llvm::Value* storeVal = l->storeVal ? l->storeVal : l->val; | |
950 if (storeVal->getType()->getContainedType(0) != tmp->getType()) | |
951 { | |
952 tmp = LLVM_DtoPointedType(storeVal, tmp); | |
953 }*/ | |
954 | |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
955 if (l->mem == 0) |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
956 LLVM_DtoGiveArgumentStorage(l); |
1 | 957 new llvm::StoreInst(tmp,l->mem,p->scopebb()); |
958 | |
959 delete l; | |
960 delete r; | |
961 | |
962 elem* e = new elem; | |
963 e->val = tmp; | |
964 e->type = elem::VAR; | |
965 return e; | |
966 } | |
967 | |
968 ////////////////////////////////////////////////////////////////////////////////////////// | |
969 | |
970 elem* CallExp::toElem(IRState* p) | |
971 { | |
972 Logger::print("CallExp::toElem: %s\n", toChars()); | |
973 LOG_SCOPE; | |
974 elem* e = new elem; | |
975 elem* fn = e1->toElem(p); | |
976 LINK dlink = LINKdefault; | |
18 | 977 |
1 | 978 bool delegateCall = false; |
979 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false); | |
980 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty,1,false); | |
981 | |
982 // hidden struct return parameter handling | |
983 bool retinptr = false; | |
18 | 984 |
1 | 985 TypeFunction* tf = 0; |
18 | 986 |
40 | 987 Type* e1type = LLVM_DtoDType(e1->type); |
988 | |
1 | 989 // regular functions |
40 | 990 if (e1type->ty == Tfunction) { |
991 tf = (TypeFunction*)e1type; | |
1 | 992 if (tf->llvmRetInPtr) { |
993 retinptr = true; | |
994 } | |
995 dlink = tf->linkage; | |
996 } | |
18 | 997 |
1 | 998 // delegates |
40 | 999 else if (e1type->ty == Tdelegate) { |
1000 Logger::println("delegateTy = %s\n", e1type->toChars()); | |
1001 assert(e1type->next->ty == Tfunction); | |
1002 tf = (TypeFunction*)e1type->next; | |
1 | 1003 if (tf->llvmRetInPtr) { |
1004 retinptr = true; | |
1005 } | |
1006 dlink = tf->linkage; | |
1007 delegateCall = true; | |
1008 } | |
18 | 1009 |
1 | 1010 // invalid |
1011 else { | |
1012 assert(tf); | |
1013 } | |
1014 | |
1015 size_t n = arguments->dim; | |
1016 if (fn->arg || delegateCall) n++; | |
1017 if (retinptr) n++; | |
1018 | |
1019 llvm::Value* funcval = fn->getValue(); | |
18 | 1020 assert(funcval != 0); |
1 | 1021 std::vector<llvm::Value*> llargs(n, 0); |
1022 | |
1023 const llvm::FunctionType* llfnty = 0; | |
18 | 1024 |
1 | 1025 // normal function call |
1026 if (llvm::isa<llvm::FunctionType>(funcval->getType())) { | |
1027 llfnty = llvm::cast<llvm::FunctionType>(funcval->getType()); | |
1028 } | |
1029 // pointer to something | |
1030 else if (llvm::isa<llvm::PointerType>(funcval->getType())) { | |
1031 // pointer to function pointer - I think this not really supposed to happen, but does :/ | |
1032 // seems like sometimes we get a func* other times a func** | |
1033 if (llvm::isa<llvm::PointerType>(funcval->getType()->getContainedType(0))) { | |
1034 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); | |
1035 } | |
1036 // function pointer | |
1037 if (llvm::isa<llvm::FunctionType>(funcval->getType()->getContainedType(0))) { | |
1038 //Logger::cout() << "function pointer type:\n" << *funcval << '\n'; | |
1039 llfnty = llvm::cast<llvm::FunctionType>(funcval->getType()->getContainedType(0)); | |
1040 } | |
1041 // struct pointer - delegate | |
1042 else if (llvm::isa<llvm::StructType>(funcval->getType()->getContainedType(0))) { | |
6 | 1043 funcval = LLVM_DtoGEP(funcval,zero,one,"tmp",p->scopebb()); |
1 | 1044 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); |
1045 const llvm::Type* ty = funcval->getType()->getContainedType(0); | |
1046 llfnty = llvm::cast<llvm::FunctionType>(ty); | |
1047 } | |
1048 // unknown | |
1049 else { | |
1050 Logger::cout() << "what kind of pointer are we calling? : " << *funcval->getType() << '\n'; | |
1051 } | |
1052 } | |
1053 else { | |
1054 Logger::cout() << "what are we calling? : " << *funcval << '\n'; | |
1055 } | |
1056 assert(llfnty); | |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1057 //Logger::cout() << "Function LLVM type: " << *llfnty << '\n'; |
1 | 1058 |
1059 // argument handling | |
1060 llvm::FunctionType::param_iterator argiter = llfnty->param_begin(); | |
1061 int j = 0; | |
1062 | |
44 | 1063 Logger::println("hidden struct return"); |
1064 | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1065 IRExp* topexp = p->topexp(); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1066 |
40 | 1067 // hidden struct return arguments |
1 | 1068 if (retinptr) { |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1069 if (topexp && topexp->e2 == this) { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1070 assert(topexp->v); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1071 assert(llvm::isa<llvm::StructType>(topexp->v->getType()->getContainedType(0))); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1072 llargs[j] = topexp->v; |
40 | 1073 if (LLVM_DtoIsPassedByRef(tf->next)) { |
1 | 1074 e->inplace = true; |
1075 } | |
1076 else | |
1077 assert(0); | |
1078 } | |
1079 else { | |
1080 llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint()); | |
1081 } | |
1082 ++j; | |
1083 ++argiter; | |
1084 e->type = elem::VAR; | |
1085 } | |
1086 else { | |
1087 e->type = elem::VAL; | |
1088 } | |
1089 | |
44 | 1090 Logger::println("this arguments"); |
1091 | |
40 | 1092 // this arguments |
1 | 1093 if (fn->arg) { |
1094 Logger::println("This Call"); | |
1095 if (fn->arg->getType() != argiter->get()) { | |
1096 //Logger::cout() << *fn->thisparam << '|' << *argiter->get() << '\n'; | |
1097 llargs[j] = new llvm::BitCastInst(fn->arg, argiter->get(), "tmp", p->scopebb()); | |
1098 } | |
1099 else { | |
1100 llargs[j] = fn->arg; | |
1101 } | |
1102 ++j; | |
1103 ++argiter; | |
1104 } | |
40 | 1105 // delegate context arguments |
1 | 1106 else if (delegateCall) { |
1107 Logger::println("Delegate Call"); | |
6 | 1108 llvm::Value* contextptr = LLVM_DtoGEP(fn->mem,zero,zero,"tmp",p->scopebb()); |
1 | 1109 llargs[j] = new llvm::LoadInst(contextptr,"tmp",p->scopebb()); |
1110 ++j; | |
1111 ++argiter; | |
1112 } | |
1113 | |
44 | 1114 Logger::println("regular arguments"); |
1115 | |
40 | 1116 // regular arguments |
1 | 1117 for (int i=0; i<arguments->dim; i++,j++) |
1118 { | |
1119 Argument* fnarg = Argument::getNth(tf->parameters, i); | |
40 | 1120 llargs[j] = LLVM_DtoArgument(llfnty->getParamType(j), fnarg, (Expression*)arguments->data[i]); |
1 | 1121 } |
1122 | |
1123 // void returns cannot not be named | |
1124 const char* varname = ""; | |
1125 if (llfnty->getReturnType() != llvm::Type::VoidTy) | |
1126 varname = "tmp"; | |
1127 | |
1128 Logger::println("%d params passed", n); | |
1129 for (int i=0; i<n; ++i) | |
1130 { | |
1131 Logger::cout() << *llargs[i] << '\n'; | |
1132 } | |
1133 | |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1134 //Logger::cout() << "Calling: " << *funcval->getType() << '\n'; |
1 | 1135 |
1136 // call the function | |
1137 llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); | |
27
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
26
diff
changeset
|
1138 if (retinptr) |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
26
diff
changeset
|
1139 e->mem = llargs[0]; |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
26
diff
changeset
|
1140 else |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
26
diff
changeset
|
1141 e->val = call; |
1 | 1142 |
1143 // set calling convention | |
1144 if ((fn->funcdecl && (fn->funcdecl->llvmInternal != LLVMintrinsic)) || delegateCall) | |
1145 call->setCallingConv(LLVM_DtoCallingConv(dlink)); | |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
1146 else if (fn->callconv != (unsigned)-1) |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
1147 call->setCallingConv(fn->callconv); |
1 | 1148 |
1149 delete fn; | |
1150 return e; | |
1151 } | |
1152 | |
1153 ////////////////////////////////////////////////////////////////////////////////////////// | |
1154 | |
1155 elem* CastExp::toElem(IRState* p) | |
1156 { | |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1157 Logger::print("CastExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1 | 1158 LOG_SCOPE; |
1159 elem* e = new elem; | |
1160 elem* u = e1->toElem(p); | |
40 | 1161 const llvm::Type* tolltype = LLVM_DtoType(to); |
1162 Type* fromtype = LLVM_DtoDType(e1->type); | |
1163 Type* totype = LLVM_DtoDType(to); | |
1164 int lsz = fromtype->size(); | |
1165 int rsz = totype->size(); | |
1 | 1166 |
1167 // this makes sure the strange lvalue casts don't screw things up | |
1168 e->mem = u->mem; | |
1169 | |
40 | 1170 if (fromtype->isintegral()) { |
1171 if (totype->isintegral()) { | |
1 | 1172 if (lsz < rsz) { |
40 | 1173 Logger::cout() << *tolltype << '\n'; |
1174 if (fromtype->isunsigned() || fromtype->ty == Tbool) { | |
1175 e->val = new llvm::ZExtInst(u->getValue(), tolltype, "tmp", p->scopebb()); | |
1 | 1176 } else { |
40 | 1177 e->val = new llvm::SExtInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1 | 1178 } |
1179 } | |
1180 else if (lsz > rsz) { | |
40 | 1181 e->val = new llvm::TruncInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1 | 1182 } |
1183 else { | |
40 | 1184 e->val = new llvm::BitCastInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1 | 1185 } |
1186 } | |
40 | 1187 else if (totype->isfloating()) { |
1188 if (fromtype->isunsigned()) { | |
1189 e->val = new llvm::UIToFPInst(u->getValue(), tolltype, "tmp", p->scopebb()); | |
1 | 1190 } |
1191 else { | |
40 | 1192 e->val = new llvm::SIToFPInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1 | 1193 } |
1194 } | |
1195 else { | |
1196 assert(0); | |
1197 } | |
1198 //e->storeVal = u->storeVal ? u->storeVal : u->val; | |
1199 e->type = elem::VAL; | |
1200 } | |
40 | 1201 else if (fromtype->isfloating()) { |
1202 if (totype->isfloating()) { | |
1203 if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) { | |
1 | 1204 e->val = u->getValue(); |
1205 } | |
1206 else if (lsz < rsz) { | |
40 | 1207 e->val = new llvm::FPExtInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1 | 1208 } |
1209 else if (lsz > rsz) { | |
40 | 1210 e->val = new llvm::FPTruncInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1 | 1211 } |
1212 else { | |
1213 assert(0); | |
1214 } | |
1215 } | |
40 | 1216 else if (totype->isintegral()) { |
1217 if (totype->isunsigned()) { | |
1218 e->val = new llvm::FPToUIInst(u->getValue(), tolltype, "tmp", p->scopebb()); | |
1 | 1219 } |
1220 else { | |
40 | 1221 e->val = new llvm::FPToSIInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1 | 1222 } |
1223 } | |
1224 else { | |
1225 assert(0); | |
1226 } | |
1227 e->type = elem::VAL; | |
1228 } | |
40 | 1229 else if (fromtype->ty == Tclass) { |
1 | 1230 //assert(to->ty == Tclass); |
40 | 1231 e->val = new llvm::BitCastInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1 | 1232 e->type = elem::VAL; |
1233 } | |
40 | 1234 else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) { |
1 | 1235 Logger::cout() << "from array or sarray" << '\n'; |
40 | 1236 if (totype->ty == Tpointer) { |
1 | 1237 Logger::cout() << "to pointer" << '\n'; |
40 | 1238 assert(fromtype->next == totype->next); |
1 | 1239 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1240 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | |
6 | 1241 llvm::Value* ptr = LLVM_DtoGEP(u->getValue(),zero,one,"tmp",p->scopebb()); |
1 | 1242 e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb()); |
1243 e->type = elem::VAL; | |
1244 } | |
40 | 1245 else if (totype->ty == Tarray) { |
1 | 1246 Logger::cout() << "to array" << '\n'; |
40 | 1247 const llvm::Type* ptrty = LLVM_DtoType(totype->next); |
1 | 1248 if (ptrty == llvm::Type::VoidTy) |
1249 ptrty = llvm::Type::Int8Ty; | |
1250 ptrty = llvm::PointerType::get(ptrty); | |
1251 | |
52 | 1252 const llvm::Type* ety = LLVM_DtoType(fromtype->next); |
1253 if (ety == llvm::Type::VoidTy) | |
1254 ety = llvm::Type::Int8Ty; | |
1255 | |
1 | 1256 if (u->type == elem::SLICE) { |
1257 e->mem = new llvm::BitCastInst(u->mem, ptrty, "tmp", p->scopebb()); | |
52 | 1258 if (fromtype->next->size() == totype->next->size()) |
1259 e->arg = u->arg; | |
1260 else | |
1261 e->arg = LLVM_DtoArrayCastLength(u->arg, ety, ptrty->getContainedType(0)); | |
1 | 1262 } |
1263 else { | |
1264 llvm::Value* uval = u->getValue(); | |
40 | 1265 if (fromtype->ty == Tsarray) { |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1266 Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1267 assert(llvm::isa<llvm::PointerType>(uval->getType())); |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1268 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(uval->getType()->getContainedType(0)); |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1269 e->arg = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false); |
52 | 1270 e->arg = LLVM_DtoArrayCastLength(e->arg, ety, ptrty->getContainedType(0)); |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1271 e->mem = new llvm::BitCastInst(uval, ptrty, "tmp", p->scopebb()); |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1272 } |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1273 else { |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1274 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1275 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
6 | 1276 e->arg = LLVM_DtoGEP(uval,zero,zero,"tmp",p->scopebb()); |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1277 e->arg = new llvm::LoadInst(e->arg, "tmp", p->scopebb()); |
52 | 1278 e->arg = LLVM_DtoArrayCastLength(e->arg, ety, ptrty->getContainedType(0)); |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1279 |
6 | 1280 e->mem = LLVM_DtoGEP(uval,zero,one,"tmp",p->scopebb()); |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1281 e->mem = new llvm::LoadInst(e->mem, "tmp", p->scopebb()); |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1282 //Logger::cout() << *e->mem->getType() << '|' << *ptrty << '\n'; |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1283 e->mem = new llvm::BitCastInst(e->mem, ptrty, "tmp", p->scopebb()); |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
1284 } |
1 | 1285 } |
1286 e->type = elem::SLICE; | |
1287 } | |
40 | 1288 else if (totype->ty == Tsarray) { |
1 | 1289 Logger::cout() << "to sarray" << '\n'; |
1290 assert(0); | |
1291 } | |
1292 else { | |
1293 assert(0); | |
1294 } | |
1295 } | |
40 | 1296 else if (fromtype->ty == Tpointer) { |
1297 if (totype->ty == Tpointer || totype->ty == Tclass) { | |
1 | 1298 llvm::Value* src = u->getValue(); |
1299 //Logger::cout() << *src << '|' << *totype << '\n'; | |
40 | 1300 e->val = new llvm::BitCastInst(src, tolltype, "tmp", p->scopebb()); |
1 | 1301 } |
40 | 1302 else if (totype->isintegral()) { |
1303 e->val = new llvm::PtrToIntInst(u->getValue(), tolltype, "tmp", p->scopebb()); | |
1 | 1304 } |
1305 else | |
1306 assert(0); | |
1307 e->type = elem::VAL; | |
1308 } | |
1309 else { | |
1310 assert(0); | |
1311 } | |
1312 delete u; | |
1313 return e; | |
1314 } | |
1315 | |
1316 ////////////////////////////////////////////////////////////////////////////////////////// | |
1317 | |
1318 elem* SymOffExp::toElem(IRState* p) | |
1319 { | |
1320 Logger::print("SymOffExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
1321 LOG_SCOPE; | |
1322 elem* e = 0; | |
1323 if (VarDeclaration* vd = var->isVarDeclaration()) | |
1324 { | |
1325 Logger::println("VarDeclaration"); | |
52 | 1326 if (!vd->llvmTouched && vd->isDataseg()) |
1327 vd->toObjFile(); | |
1328 | |
1329 if (vd->isTypedefDeclaration()) { | |
1330 e->istypeinfo = true; | |
1331 } | |
1332 | |
23 | 1333 assert(vd->llvmValue); |
40 | 1334 Type* t = LLVM_DtoDType(type); |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1335 Type* vdtype = LLVM_DtoDType(vd->type); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1336 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1337 llvm::Value* llvalue = vd->nestedref ? LLVM_DtoNestedVariable(vd) : vd->llvmValue; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1338 |
40 | 1339 if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { |
1340 TypeStruct* vdt = (TypeStruct*)vdtype; | |
1 | 1341 e = new elem; |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
1342 std::vector<unsigned> dst(1,0); |
40 | 1343 vdt->sym->offsetToIndex(t->next, offset, dst); |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1344 llvm::Value* ptr = llvalue; |
1 | 1345 assert(ptr); |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
1346 e->mem = LLVM_DtoGEP(ptr,dst,"tmp",p->scopebb()); |
1 | 1347 e->type = elem::VAL; |
1348 e->field = true; | |
1349 } | |
40 | 1350 else if (vdtype->ty == Tsarray) { |
1 | 1351 /*e = new elem; |
1352 llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
1353 e->val = new llvm::GetElementPtrInst(vd->llvmValue,idx0,idx0,"tmp",p->scopebb());*/ | |
1354 e = new elem; | |
1355 llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
1356 //llvm::Value* idx1 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1357 e->mem = LLVM_DtoGEP(llvalue,idx0,idx0,"tmp",p->scopebb()); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1358 e->arg = llvalue; |
1 | 1359 e->type = elem::VAL; |
1360 } | |
1361 else if (offset == 0) { | |
1362 e = new elem; | |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1363 assert(llvalue); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1364 e->mem = llvalue; |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1365 const llvm::Type* llt = LLVM_DtoType(t); |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1366 if (llvalue->getType() != llt) { |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1367 Logger::cout() << "llt is:" << *llt << '\n'; |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1368 //const llvm::PointerType* vpty = llvm::PointerType::get(llvm::Type::Int8Ty); |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1369 e->mem = p->ir->CreateBitCast(e->mem, llt, "tmp"); |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1370 } |
1 | 1371 e->type = elem::VAL; |
1372 } | |
1373 else { | |
1374 assert(0); | |
1375 } | |
1376 } | |
1377 else if (FuncDeclaration* fd = var->isFuncDeclaration()) | |
1378 { | |
1379 Logger::println("FuncDeclaration"); | |
1380 e = new elem; | |
1381 if (fd->llvmValue == 0) | |
1382 fd->toObjFile(); | |
1383 e->val = fd->llvmValue; | |
1384 e->type = elem::FUNC; | |
1385 } | |
1386 assert(e != 0); | |
1387 assert(e->type != elem::NONE); | |
1388 return e; | |
1389 } | |
1390 | |
1391 ////////////////////////////////////////////////////////////////////////////////////////// | |
1392 | |
1393 elem* PtrExp::toElem(IRState* p) | |
1394 { | |
1395 Logger::print("PtrExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
1396 LOG_SCOPE; | |
1397 elem* e = new elem; | |
1398 elem* a = e1->toElem(p); | |
1399 | |
1400 if (a->mem) | |
1401 Logger::cout() << "mem: " << *a->mem << '\n'; | |
1402 if (a->val) | |
1403 Logger::cout() << "val: " << *a->val << '\n'; | |
1404 | |
1405 if (a->field) | |
1406 e->mem = a->mem; | |
1407 else | |
1408 e->mem = a->getValue(); | |
1409 e->type = elem::VAR; | |
1410 | |
1411 delete a; | |
1412 return e; | |
1413 } | |
1414 | |
1415 ////////////////////////////////////////////////////////////////////////////////////////// | |
1416 | |
1417 elem* DotVarExp::toElem(IRState* p) | |
1418 { | |
1419 Logger::print("DotVarExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
1420 LOG_SCOPE; | |
1421 elem* e = new elem; | |
1422 | |
1423 elem* l = e1->toElem(p); | |
1424 | |
40 | 1425 Type* t = LLVM_DtoDType(type); |
1426 Type* e1type = LLVM_DtoDType(e1->type); | |
1427 | |
1428 Logger::print("e1->type=%s\n", e1type->toChars()); | |
1 | 1429 |
1430 if (VarDeclaration* vd = var->isVarDeclaration()) { | |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
1431 std::vector<unsigned> vdoffsets(1,0); |
1 | 1432 llvm::Value* src = 0; |
40 | 1433 if (e1type->ty == Tpointer) { |
1434 assert(e1type->next->ty == Tstruct); | |
1435 TypeStruct* ts = (TypeStruct*)e1type->next; | |
24
25bb577878e8
[svn r28] * Fixed accessing aggregate fields. it was still not quite right. hopefully is now :)
lindquist
parents:
23
diff
changeset
|
1436 ts->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
1437 Logger::println("Struct member offset:%d", vd->offset); |
15
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
1438 src = l->val ? l->val : l->mem; |
1 | 1439 } |
1440 else if (e1->type->ty == Tclass) { | |
40 | 1441 TypeClass* tc = (TypeClass*)e1type; |
1 | 1442 Logger::println("Class member offset: %d", vd->offset); |
24
25bb577878e8
[svn r28] * Fixed accessing aggregate fields. it was still not quite right. hopefully is now :)
lindquist
parents:
23
diff
changeset
|
1443 tc->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); |
1 | 1444 src = l->getValue(); |
1445 } | |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
1446 assert(vdoffsets.size() != 1); |
1 | 1447 assert(src != 0); |
40 | 1448 Logger::cout() << "src: " << *src << '\n'; |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
1449 llvm::Value* arrptr = LLVM_DtoGEP(src,vdoffsets,"tmp",p->scopebb()); |
1 | 1450 e->mem = arrptr; |
1451 Logger::cout() << "mem: " << *e->mem << '\n'; | |
1452 e->type = elem::VAR; | |
1453 } | |
1454 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) | |
1455 { | |
1456 if (fdecl->llvmValue == 0) | |
1457 { | |
1458 fdecl->toObjFile(); | |
1459 } | |
1460 | |
1461 llvm::Value* funcval = fdecl->llvmValue; | |
1462 e->arg = l->getValue(); | |
1463 | |
1464 // virtual call | |
1465 if (fdecl->isVirtual()) { | |
1466 assert(fdecl->vtblIndex > 0); | |
40 | 1467 assert(e1type->ty == Tclass); |
1 | 1468 |
1469 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
1470 llvm::Value* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false); | |
6 | 1471 funcval = LLVM_DtoGEP(e->arg, zero, zero, "tmp", p->scopebb()); |
1 | 1472 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1473 funcval = LLVM_DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb()); |
1 | 1474 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); |
9 | 1475 assert(funcval->getType() == fdecl->llvmValue->getType()); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
1476 e->callconv = LLVM_DtoCallingConv(fdecl->linkage); |
1 | 1477 } |
1478 e->val = funcval; | |
1479 e->type = elem::VAL; | |
1480 } | |
1481 else { | |
1482 printf("unknown: %s\n", var->toChars()); | |
1483 assert(0); | |
1484 } | |
1485 | |
1486 delete l; | |
1487 | |
1488 return e; | |
1489 } | |
1490 | |
1491 ////////////////////////////////////////////////////////////////////////////////////////// | |
1492 | |
1493 elem* ThisExp::toElem(IRState* p) | |
1494 { | |
1495 Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
1496 LOG_SCOPE; | |
1497 elem* e = new elem; | |
1498 | |
1499 if (VarDeclaration* vd = var->isVarDeclaration()) { | |
40 | 1500 llvm::Value* v = p->func().decl->llvmThisVar; |
15
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
1501 if (llvm::isa<llvm::AllocaInst>(v)) |
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
1502 v = new llvm::LoadInst(v, "tmp", p->scopebb()); |
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
1503 e->mem = v; |
1 | 1504 e->type = elem::VAL; |
15
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
1505 e->isthis = true; |
1 | 1506 } |
1507 else { | |
1508 assert(0); | |
1509 } | |
1510 | |
1511 return e; | |
1512 } | |
1513 | |
1514 ////////////////////////////////////////////////////////////////////////////////////////// | |
1515 | |
1516 elem* AddrExp::toElem(IRState* p) | |
1517 { | |
1518 Logger::print("AddrExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
1519 LOG_SCOPE; | |
1520 elem* e = e1->toElem(p); | |
1521 e->field = true; | |
1522 return e; | |
1523 } | |
1524 | |
1525 ////////////////////////////////////////////////////////////////////////////////////////// | |
1526 | |
1527 elem* StructLiteralExp::toElem(IRState* p) | |
1528 { | |
1529 Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
1530 LOG_SCOPE; | |
1531 elem* e = new elem; | |
1532 | |
30
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1533 llvm::Value* sptr = 0; |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1534 |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1535 // if there is no lval, this is probably a temporary struct literal. correct? |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1536 if (!p->topexp() || p->topexp()->e2 != this) |
1 | 1537 { |
30
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1538 sptr = new llvm::AllocaInst(LLVM_DtoType(type),"tmpstructliteral",p->topallocapoint()); |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1539 e->mem = sptr; |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1540 e->type = elem::VAR; |
1 | 1541 } |
30
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1542 // already has memory |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1543 else if (p->topexp()->e2 == this) |
1 | 1544 { |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1545 sptr = p->topexp()->v; |
30
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1546 } |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1547 else |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1548 assert(0); |
1 | 1549 |
30
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1550 assert(sptr); |
1 | 1551 |
30
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1552 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1553 |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1554 unsigned n = elements->dim; |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1555 for (unsigned i=0; i<n; ++i) |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1556 { |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1557 llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false); |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1558 llvm::Value* arrptr = LLVM_DtoGEP(sptr,zero,offset,"tmp",p->scopebb()); |
1 | 1559 |
30
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1560 Expression* vx = (Expression*)elements->data[i]; |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1561 if (vx != 0) { |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1562 p->exps.push_back(IRExp(NULL,vx,arrptr)); |
30
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1563 elem* ve = vx->toElem(p); |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1564 p->exps.pop_back(); |
40 | 1565 |
1566 if (!ve->inplace) { | |
1567 llvm::Value* val = ve->getValue(); | |
1568 Logger::cout() << *val << " | " << *arrptr << '\n'; | |
1569 | |
1570 Type* vxtype = LLVM_DtoDType(vx->type); | |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1571 LLVM_DtoAssign(vxtype, arrptr, val); |
1 | 1572 } |
30
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1573 delete ve; |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1574 } |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1575 else { |
881158a93592
[svn r34] * Fixed passing a struct literal as function argument
lindquist
parents:
29
diff
changeset
|
1576 assert(0); |
1 | 1577 } |
1578 } | |
1579 | |
1580 e->inplace = true; | |
1581 | |
1582 return e; | |
1583 } | |
1584 | |
1585 ////////////////////////////////////////////////////////////////////////////////////////// | |
1586 | |
40 | 1587 llvm::Constant* StructLiteralExp::toConstElem(IRState* p) |
1588 { | |
1589 Logger::print("StructLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | |
1590 LOG_SCOPE; | |
1591 | |
1592 unsigned n = elements->dim; | |
1593 std::vector<llvm::Constant*> vals(n, NULL); | |
1594 | |
1595 for (unsigned i=0; i<n; ++i) | |
1596 { | |
1597 Expression* vx = (Expression*)elements->data[i]; | |
1598 vals[i] = vx->toConstElem(p); | |
1599 } | |
1600 | |
1601 assert(LLVM_DtoDType(type)->ty == Tstruct); | |
1602 const llvm::Type* t = LLVM_DtoType(type); | |
1603 const llvm::StructType* st = llvm::cast<llvm::StructType>(t); | |
1604 return llvm::ConstantStruct::get(st,vals); | |
1605 } | |
1606 | |
1607 ////////////////////////////////////////////////////////////////////////////////////////// | |
1608 | |
1 | 1609 elem* IndexExp::toElem(IRState* p) |
1610 { | |
1611 Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
1612 LOG_SCOPE; | |
1613 | |
1614 elem* e = new elem; | |
1615 | |
1616 elem* l = e1->toElem(p); | |
1617 | |
40 | 1618 Type* e1type = LLVM_DtoDType(e1->type); |
1619 | |
1 | 1620 p->arrays.push_back(l->mem); // if $ is used it must be an array so this is fine. |
1621 elem* r = e2->toElem(p); | |
1622 p->arrays.pop_back(); | |
1623 | |
1624 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
1625 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | |
1626 | |
1627 llvm::Value* arrptr = 0; | |
40 | 1628 if (e1type->ty == Tpointer) { |
1 | 1629 arrptr = new llvm::GetElementPtrInst(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
1630 } | |
40 | 1631 else if (e1type->ty == Tsarray) { |
1632 arrptr = LLVM_DtoGEP(l->getValue(), zero, r->getValue(),"tmp",p->scopebb()); | |
1 | 1633 } |
40 | 1634 else if (e1type->ty == Tarray) { |
6 | 1635 arrptr = LLVM_DtoGEP(l->mem,zero,one,"tmp",p->scopebb()); |
1 | 1636 arrptr = new llvm::LoadInst(arrptr,"tmp",p->scopebb()); |
1637 arrptr = new llvm::GetElementPtrInst(arrptr,r->getValue(),"tmp",p->scopebb()); | |
1638 } | |
1639 assert(arrptr); | |
1640 | |
1641 e->mem = arrptr; | |
1642 e->type = elem::VAR; | |
1643 | |
1644 delete l; | |
1645 delete r; | |
1646 | |
1647 return e; | |
1648 } | |
1649 | |
1650 ////////////////////////////////////////////////////////////////////////////////////////// | |
1651 | |
1652 elem* SliceExp::toElem(IRState* p) | |
1653 { | |
1654 Logger::print("SliceExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
1655 LOG_SCOPE; | |
1656 | |
52 | 1657 Type* t = LLVM_DtoDType(type); |
1658 assert(t->ty == Tarray); | |
1659 | |
1 | 1660 elem* v = e1->toElem(p); |
40 | 1661 Type* e1type = LLVM_DtoDType(e1->type); |
1 | 1662 |
1663 elem* e = new elem; | |
1664 assert(v->mem); | |
1665 e->type = elem::SLICE; | |
1666 | |
1667 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
1668 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | |
1669 | |
1670 // partial slice | |
1671 if (lwr) | |
1672 { | |
1673 assert(upr); | |
1674 p->arrays.push_back(v->mem); | |
1675 elem* lo = lwr->toElem(p); | |
1676 | |
1677 bool lwr_is_zero = false; | |
1678 if (lo->type == elem::CONST) | |
1679 { | |
1680 assert(lo->val); | |
1681 assert(llvm::isa<llvm::ConstantInt>(lo->val)); | |
1682 | |
40 | 1683 if (e1type->ty == Tpointer) { |
1 | 1684 e->mem = v->getValue(); |
1685 } | |
40 | 1686 else if (e1type->ty == Tarray) { |
6 | 1687 llvm::Value* tmp = LLVM_DtoGEP(v->mem,zero,one,"tmp",p->scopebb()); |
1 | 1688 e->mem = new llvm::LoadInst(tmp,"tmp",p->scopebb()); |
1689 } | |
40 | 1690 else if (e1type->ty == Tsarray) { |
1691 e->mem = LLVM_DtoGEP(v->mem,zero,zero,"tmp",p->scopebb()); | |
1692 } | |
1 | 1693 else |
1694 assert(e->mem); | |
1695 | |
1696 llvm::ConstantInt* c = llvm::cast<llvm::ConstantInt>(lo->val); | |
1697 if (!(lwr_is_zero = c->isZero())) { | |
1698 e->mem = new llvm::GetElementPtrInst(e->mem,lo->val,"tmp",p->scopebb()); | |
1699 } | |
1700 } | |
1701 else | |
1702 { | |
40 | 1703 if (e1type->ty == Tarray) { |
1704 llvm::Value* tmp = LLVM_DtoGEP(v->mem,zero,one,"tmp",p->scopebb()); | |
1705 tmp = new llvm::LoadInst(tmp,"tmp",p->scopebb()); | |
1706 e->mem = new llvm::GetElementPtrInst(tmp,lo->getValue(),"tmp",p->scopebb()); | |
1707 } | |
1708 else if (e1type->ty == Tsarray) { | |
1709 e->mem = LLVM_DtoGEP(v->mem,zero,lo->getValue(),"tmp",p->scopebb()); | |
1710 } | |
1711 else | |
1712 assert(0); | |
1 | 1713 } |
1714 | |
1715 elem* up = upr->toElem(p); | |
1716 p->arrays.pop_back(); | |
1717 | |
1718 if (up->type == elem::CONST) | |
1719 { | |
1720 assert(up->val); | |
1721 assert(llvm::isa<llvm::ConstantInt>(up->val)); | |
1722 if (lwr_is_zero) { | |
1723 e->arg = up->val; | |
1724 } | |
1725 else { | |
1726 if (lo->type == elem::CONST) { | |
1727 llvm::Constant* clo = llvm::cast<llvm::Constant>(lo->val); | |
1728 llvm::Constant* cup = llvm::cast<llvm::Constant>(up->val); | |
1729 e->arg = llvm::ConstantExpr::getSub(cup, clo); | |
1730 } | |
1731 else { | |
1732 e->arg = llvm::BinaryOperator::createSub(up->val, lo->getValue(), "tmp", p->scopebb()); | |
1733 } | |
1734 } | |
1735 } | |
1736 else | |
1737 { | |
1738 if (lwr_is_zero) { | |
1739 e->arg = up->getValue(); | |
1740 } | |
1741 else { | |
1742 e->arg = llvm::BinaryOperator::createSub(up->getValue(), lo->getValue(), "tmp", p->scopebb()); | |
1743 } | |
1744 } | |
1745 | |
1746 delete lo; | |
1747 delete up; | |
52 | 1748 |
1749 /* | |
1750 llvm::Value* tmpmem = new llvm::AllocaInst(LLVM_DtoType(t),"tmp",p->topallocapoint()); | |
1751 llvm::Value* ptr = LLVM_DtoGEPi(tmpmem,0,0,"tmp"); | |
1752 p->ir->CreateStore(e->arg, ptr); | |
1753 ptr = LLVM_DtoGEPi(tmpmem,0,1,"tmp"); | |
1754 p->ir->CreateStore(e->mem, ptr); | |
1755 e->arg = NULL; | |
1756 e->mem = tmpmem; | |
1757 */ | |
1 | 1758 } |
1759 // full slice | |
1760 else | |
1761 { | |
1762 e->mem = v->mem; | |
1763 } | |
1764 | |
1765 delete v; | |
1766 | |
1767 return e; | |
1768 } | |
1769 | |
1770 ////////////////////////////////////////////////////////////////////////////////////////// | |
1771 | |
1772 elem* CmpExp::toElem(IRState* p) | |
1773 { | |
1774 Logger::print("CmpExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
1775 LOG_SCOPE; | |
1776 | |
1777 elem* e = new elem; | |
1778 | |
1779 elem* l = e1->toElem(p); | |
1780 elem* r = e2->toElem(p); | |
1781 | |
40 | 1782 Type* t = LLVM_DtoDType(e1->type); |
1783 Type* e2t = LLVM_DtoDType(e2->type); | |
1784 assert(t == e2t); | |
1 | 1785 |
1786 if (t->isintegral()) | |
1787 { | |
1788 llvm::ICmpInst::Predicate cmpop; | |
40 | 1789 bool skip = false; |
1 | 1790 switch(op) |
1791 { | |
1792 case TOKlt: | |
40 | 1793 case TOKul: |
1 | 1794 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_ULT : llvm::ICmpInst::ICMP_SLT; |
1795 break; | |
1796 case TOKle: | |
40 | 1797 case TOKule: |
1 | 1798 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_ULE : llvm::ICmpInst::ICMP_SLE; |
1799 break; | |
1800 case TOKgt: | |
40 | 1801 case TOKug: |
1 | 1802 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_UGT : llvm::ICmpInst::ICMP_SGT; |
1803 break; | |
1804 case TOKge: | |
40 | 1805 case TOKuge: |
1 | 1806 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_UGE : llvm::ICmpInst::ICMP_SGE; |
1807 break; | |
40 | 1808 case TOKue: |
1809 cmpop = llvm::ICmpInst::ICMP_EQ; | |
1810 break; | |
1811 case TOKlg: | |
1812 cmpop = llvm::ICmpInst::ICMP_NE; | |
1813 break; | |
1814 case TOKleg: | |
1815 skip = true; | |
1816 e->val = llvm::ConstantInt::getTrue(); | |
1817 break; | |
1818 case TOKunord: | |
1819 skip = true; | |
1820 e->val = llvm::ConstantInt::getFalse(); | |
1821 break; | |
1822 | |
1 | 1823 default: |
1824 assert(0); | |
1825 } | |
40 | 1826 if (!skip) |
1827 { | |
1828 e->val = new llvm::ICmpInst(cmpop, l->getValue(), r->getValue(), "tmp", p->scopebb()); | |
1829 } | |
1 | 1830 } |
1831 else if (t->isfloating()) | |
1832 { | |
1833 llvm::FCmpInst::Predicate cmpop; | |
1834 switch(op) | |
1835 { | |
1836 case TOKlt: | |
1837 cmpop = llvm::FCmpInst::FCMP_OLT;break; | |
1838 case TOKle: | |
1839 cmpop = llvm::FCmpInst::FCMP_OLE;break; | |
1840 case TOKgt: | |
1841 cmpop = llvm::FCmpInst::FCMP_OGT;break; | |
1842 case TOKge: | |
1843 cmpop = llvm::FCmpInst::FCMP_OGE;break; | |
1844 case TOKunord: | |
1845 cmpop = llvm::FCmpInst::FCMP_UNO;break; | |
1846 case TOKule: | |
1847 cmpop = llvm::FCmpInst::FCMP_ULE;break; | |
1848 case TOKul: | |
1849 cmpop = llvm::FCmpInst::FCMP_ULT;break; | |
1850 case TOKuge: | |
1851 cmpop = llvm::FCmpInst::FCMP_UGE;break; | |
1852 case TOKug: | |
1853 cmpop = llvm::FCmpInst::FCMP_UGT;break; | |
1854 case TOKue: | |
1855 cmpop = llvm::FCmpInst::FCMP_UEQ;break; | |
1856 case TOKlg: | |
1857 cmpop = llvm::FCmpInst::FCMP_ONE;break; | |
1858 case TOKleg: | |
1859 cmpop = llvm::FCmpInst::FCMP_ORD;break; | |
1860 | |
1861 default: | |
1862 assert(0); | |
1863 } | |
1864 e->val = new llvm::FCmpInst(cmpop, l->getValue(), r->getValue(), "tmp", p->scopebb()); | |
1865 } | |
1866 else | |
1867 { | |
1868 assert(0 && "Unsupported CmpExp type"); | |
1869 } | |
1870 | |
1871 delete l; | |
1872 delete r; | |
1873 | |
1874 e->type = elem::VAL; | |
1875 | |
1876 return e; | |
1877 } | |
1878 | |
1879 ////////////////////////////////////////////////////////////////////////////////////////// | |
1880 | |
1881 elem* EqualExp::toElem(IRState* p) | |
1882 { | |
1883 Logger::print("EqualExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
1884 LOG_SCOPE; | |
1885 | |
1886 elem* e = new elem; | |
1887 | |
1888 elem* l = e1->toElem(p); | |
1889 elem* r = e2->toElem(p); | |
1890 | |
40 | 1891 Type* t = LLVM_DtoDType(e1->type); |
1892 Type* e2t = LLVM_DtoDType(e2->type); | |
1893 assert(t == e2t); | |
1 | 1894 |
1895 if (t->isintegral() || t->ty == Tpointer) | |
1896 { | |
1897 llvm::ICmpInst::Predicate cmpop; | |
1898 switch(op) | |
1899 { | |
1900 case TOKequal: | |
1901 cmpop = llvm::ICmpInst::ICMP_EQ; | |
1902 break; | |
1903 case TOKnotequal: | |
1904 cmpop = llvm::ICmpInst::ICMP_NE; | |
1905 break; | |
1906 default: | |
1907 assert(0); | |
1908 } | |
1909 e->val = new llvm::ICmpInst(cmpop, l->getValue(), r->getValue(), "tmp", p->scopebb()); | |
1910 } | |
1911 else if (t->isfloating()) | |
1912 { | |
1913 llvm::FCmpInst::Predicate cmpop; | |
1914 switch(op) | |
1915 { | |
1916 case TOKequal: | |
1917 cmpop = llvm::FCmpInst::FCMP_OEQ; | |
1918 break; | |
1919 case TOKnotequal: | |
1920 cmpop = llvm::FCmpInst::FCMP_UNE; | |
1921 break; | |
1922 default: | |
1923 assert(0); | |
1924 } | |
1925 e->val = new llvm::FCmpInst(cmpop, l->getValue(), r->getValue(), "tmp", p->scopebb()); | |
1926 } | |
40 | 1927 else if (t->ty == Tsarray) |
1928 { | |
1929 e->val = LLVM_DtoStaticArrayCompare(op,l->mem,r->mem); | |
1930 } | |
1 | 1931 else if (t->ty == Tarray) |
1932 { | |
52 | 1933 e->val = LLVM_DtoDynArrayCompare(op,l->mem,r->mem); |
1 | 1934 } |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1935 else if (t->ty == Tdelegate) |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1936 { |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1937 e->val = LLVM_DtoCompareDelegate(op,l->mem,r->mem); |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
1938 } |
1 | 1939 else |
1940 { | |
1941 assert(0 && "Unsupported EqualExp type"); | |
1942 } | |
1943 | |
1944 delete l; | |
1945 delete r; | |
1946 | |
1947 e->type = elem::VAL; | |
1948 | |
1949 return e; | |
1950 } | |
1951 | |
1952 ////////////////////////////////////////////////////////////////////////////////////////// | |
1953 | |
1954 elem* PostExp::toElem(IRState* p) | |
1955 { | |
1956 Logger::print("PostExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
1957 LOG_SCOPE; | |
1958 | |
1959 elem* l = e1->toElem(p); | |
1960 elem* r = e2->toElem(p); | |
1961 | |
1962 elem* e = new elem; | |
1963 e->mem = l->mem; | |
1964 e->val = l->getValue(); | |
1965 e->type = elem::VAL; | |
1966 | |
1967 llvm::Value* val = e->val; | |
1968 llvm::Value* post = 0; | |
1969 | |
40 | 1970 Type* e1type = LLVM_DtoDType(e1->type); |
1971 Type* e2type = LLVM_DtoDType(e2->type); | |
1972 | |
1973 if (e1type->isintegral()) | |
1 | 1974 { |
40 | 1975 assert(e2type->isintegral()); |
1976 llvm::Value* one = llvm::ConstantInt::get(val->getType(), 1, !e2type->isunsigned()); | |
1 | 1977 if (op == TOKplusplus) { |
1978 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); | |
1979 } | |
1980 else if (op == TOKminusminus) { | |
1981 post = llvm::BinaryOperator::createSub(val,one,"tmp",p->scopebb()); | |
1982 } | |
1983 } | |
40 | 1984 else if (e1type->ty == Tpointer) |
1 | 1985 { |
40 | 1986 assert(e2type->isintegral()); |
1 | 1987 llvm::Constant* minusone = llvm::ConstantInt::get(LLVM_DtoSize_t(),(uint64_t)-1,true); |
1988 llvm::Constant* plusone = llvm::ConstantInt::get(LLVM_DtoSize_t(),(uint64_t)1,false); | |
1989 llvm::Constant* whichone = (op == TOKplusplus) ? plusone : minusone; | |
1990 post = new llvm::GetElementPtrInst(val, whichone, "tmp", p->scopebb()); | |
1991 } | |
40 | 1992 else if (e1type->isfloating()) |
1 | 1993 { |
40 | 1994 assert(e2type->isfloating()); |
1 | 1995 llvm::Value* one = llvm::ConstantFP::get(val->getType(), 1.0f); |
1996 if (op == TOKplusplus) { | |
1997 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); | |
1998 } | |
1999 else if (op == TOKminusminus) { | |
2000 post = llvm::BinaryOperator::createSub(val,one,"tmp",p->scopebb()); | |
2001 } | |
2002 } | |
2003 else | |
2004 assert(post); | |
2005 | |
2006 //llvm::Value* tostore = l->storeVal ? l->storeVal : l->val; | |
2007 new llvm::StoreInst(post,l->mem,p->scopebb()); | |
2008 | |
2009 delete l; | |
2010 delete r; | |
2011 | |
2012 return e; | |
2013 } | |
2014 | |
2015 ////////////////////////////////////////////////////////////////////////////////////////// | |
2016 | |
2017 elem* NewExp::toElem(IRState* p) | |
2018 { | |
2019 Logger::print("NewExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2020 LOG_SCOPE; | |
2021 | |
2022 assert(!thisexp); | |
2023 assert(!newargs); | |
2024 assert(newtype); | |
2025 assert(!allocator); | |
2026 | |
2027 elem* e = new elem; | |
2028 | |
40 | 2029 Type* ntype = LLVM_DtoDType(newtype); |
2030 | |
2031 const llvm::Type* t = LLVM_DtoType(ntype); | |
1 | 2032 |
2033 if (onstack) { | |
40 | 2034 assert(ntype->ty == Tclass); |
1 | 2035 e->mem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint()); |
2036 } | |
2037 else { | |
40 | 2038 if (ntype->ty == Tclass) { |
1 | 2039 e->mem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb()); |
2040 } | |
40 | 2041 else if (ntype->ty == Tarray) { |
1 | 2042 assert(arguments); |
2043 if (arguments->dim == 1) { | |
2044 elem* sz = ((Expression*)arguments->data[0])->toElem(p); | |
2045 llvm::Value* dimval = sz->getValue(); | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2046 assert(p->topexp() && p->topexp()->e2 == this && p->topexp()->v); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2047 LLVM_DtoNewDynArray(p->topexp()->v, dimval, ntype->next); |
1 | 2048 delete sz; |
2049 } | |
2050 else { | |
2051 assert(0); | |
2052 } | |
2053 } | |
2054 else { | |
2055 e->mem = new llvm::MallocInst(t,"tmp",p->scopebb()); | |
2056 } | |
2057 } | |
2058 | |
40 | 2059 if (ntype->ty == Tclass) { |
1 | 2060 // first apply the static initializer |
2061 assert(e->mem); | |
40 | 2062 LLVM_DtoInitClass((TypeClass*)ntype, e->mem); |
1 | 2063 |
2064 // then call constructor | |
2065 if (arguments) { | |
40 | 2066 assert(member); |
2067 assert(member->llvmValue); | |
2068 llvm::Function* fn = llvm::cast<llvm::Function>(member->llvmValue); | |
2069 TypeFunction* tf = (TypeFunction*)LLVM_DtoDType(member->type); | |
2070 | |
1 | 2071 std::vector<llvm::Value*> ctorargs; |
2072 ctorargs.push_back(e->mem); | |
2073 for (size_t i=0; i<arguments->dim; ++i) | |
2074 { | |
2075 Expression* ex = (Expression*)arguments->data[i]; | |
40 | 2076 Argument* fnarg = Argument::getNth(tf->parameters, i); |
2077 llvm::Value* a = LLVM_DtoArgument(fn->getFunctionType()->getParamType(i+1), fnarg, ex); | |
2078 ctorargs.push_back(a); | |
1 | 2079 } |
40 | 2080 e->mem = new llvm::CallInst(fn, ctorargs.begin(), ctorargs.end(), "tmp", p->scopebb()); |
1 | 2081 } |
2082 } | |
40 | 2083 else if (ntype->ty == Tstruct) { |
2084 TypeStruct* ts = (TypeStruct*)ntype; | |
1 | 2085 if (ts->isZeroInit()) { |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
2086 LLVM_DtoStructZeroInit(e->mem); |
1 | 2087 } |
2088 else { | |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
2089 LLVM_DtoStructCopy(e->mem,ts->llvmInit); |
1 | 2090 } |
2091 } | |
2092 | |
2093 e->inplace = true; | |
2094 e->type = elem::VAR; | |
15
37a4fdab33fc
[svn r19] * Added support for reassigning 'this' inside class constructors.
lindquist
parents:
14
diff
changeset
|
2095 |
1 | 2096 return e; |
2097 } | |
2098 | |
2099 ////////////////////////////////////////////////////////////////////////////////////////// | |
2100 | |
2101 elem* DeleteExp::toElem(IRState* p) | |
2102 { | |
2103 Logger::print("DeleteExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2104 LOG_SCOPE; | |
2105 | |
2106 //assert(e1->type->ty != Tclass); | |
2107 | |
2108 elem* v = e1->toElem(p); | |
2109 llvm::Value* val = v->getValue(); | |
2110 llvm::Value* ldval = 0; | |
2111 | |
2112 const llvm::Type* t = val->getType(); | |
2113 llvm::Constant* z = llvm::Constant::getNullValue(t); | |
2114 | |
40 | 2115 Type* e1type = LLVM_DtoDType(e1->type); |
2116 | |
2117 if (e1type->ty == Tpointer) { | |
1 | 2118 ldval = v->getValue(); |
2119 new llvm::FreeInst(ldval, p->scopebb()); | |
2120 | |
2121 Logger::cout() << *z << '\n'; | |
2122 Logger::cout() << *val << '\n'; | |
2123 new llvm::StoreInst(z, v->mem, p->scopebb()); | |
2124 } | |
40 | 2125 else if (e1type->ty == Tclass) { |
2126 TypeClass* tc = (TypeClass*)e1type; | |
1 | 2127 LLVM_DtoCallClassDtors(tc, val); |
2128 | |
2129 if (v->vardecl && !v->vardecl->onstack) { | |
2130 new llvm::FreeInst(val, p->scopebb()); | |
2131 } | |
2132 new llvm::StoreInst(z, v->mem, p->scopebb()); | |
2133 } | |
40 | 2134 else if (e1type->ty == Tarray) { |
1 | 2135 // must be on the heap (correct?) |
2136 ldval = v->getValue(); | |
2137 | |
2138 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
2139 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | |
2140 | |
6 | 2141 llvm::Value* ptr = LLVM_DtoGEP(ldval,zero,one,"tmp",p->scopebb()); |
1 | 2142 ptr = new llvm::LoadInst(ptr,"tmp",p->scopebb()); |
2143 new llvm::FreeInst(ptr, p->scopebb()); | |
2144 LLVM_DtoNullArray(val); | |
2145 } | |
2146 else { | |
2147 assert(0); | |
2148 } | |
2149 | |
2150 delete v; | |
2151 | |
2152 // this expression produces no useful data | |
2153 return 0; | |
2154 } | |
2155 | |
2156 ////////////////////////////////////////////////////////////////////////////////////////// | |
2157 | |
2158 elem* ArrayLengthExp::toElem(IRState* p) | |
2159 { | |
2160 Logger::print("ArrayLengthExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2161 LOG_SCOPE; | |
2162 | |
2163 elem* e = new elem; | |
2164 elem* u = e1->toElem(p); | |
2165 | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2166 if (p->topexp() && p->topexp()->e1 == this) |
34 | 2167 { |
2168 e->mem = u->mem; | |
2169 e->type = elem::ARRAYLEN; | |
2170 } | |
2171 else | |
2172 { | |
2173 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
2174 llvm::Value* ptr = LLVM_DtoGEP(u->mem,zero,zero,"tmp",p->scopebb()); | |
2175 e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb()); | |
2176 e->type = elem::VAL; | |
2177 } | |
1 | 2178 delete u; |
2179 | |
2180 return e; | |
2181 } | |
2182 | |
2183 ////////////////////////////////////////////////////////////////////////////////////////// | |
2184 | |
2185 elem* AssertExp::toElem(IRState* p) | |
2186 { | |
2187 Logger::print("AssertExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2188 LOG_SCOPE; | |
2189 | |
2190 elem* u = e1->toElem(p); | |
34 | 2191 elem* m = msg ? msg->toElem(p) : NULL; |
1 | 2192 |
34 | 2193 llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); |
2194 LLVM_DtoAssert(u->getValue(), loca, m ? m->val : NULL); | |
2195 | |
1 | 2196 delete m; |
2197 delete u; | |
2198 | |
34 | 2199 return new elem; |
1 | 2200 } |
2201 | |
2202 ////////////////////////////////////////////////////////////////////////////////////////// | |
2203 | |
2204 elem* NotExp::toElem(IRState* p) | |
2205 { | |
2206 Logger::print("NotExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2207 LOG_SCOPE; | |
2208 | |
2209 elem* e = new elem; | |
2210 elem* u = e1->toElem(p); | |
2211 | |
2212 llvm::Value* b = LLVM_DtoBoolean(u->getValue()); | |
2213 | |
2214 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int1Ty, 0, true); | |
40 | 2215 e->val = p->ir->CreateICmpEQ(b,zero); |
2216 //e->val = new llvm::ICmpInst(llvm::ICmpInst::ICMP_EQ,b,zero,"tmp",p->scopebb()); | |
1 | 2217 e->type = elem::VAL; |
2218 | |
2219 delete u; | |
2220 | |
2221 return e; | |
2222 } | |
2223 | |
2224 ////////////////////////////////////////////////////////////////////////////////////////// | |
2225 | |
2226 elem* AndAndExp::toElem(IRState* p) | |
2227 { | |
2228 Logger::print("AndAndExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2229 LOG_SCOPE; | |
2230 | |
2231 // allocate a temporary for the final result. failed to come up with a better way :/ | |
2232 llvm::Value* resval = 0; | |
2233 llvm::BasicBlock* entryblock = &p->topfunc()->front(); | |
2234 resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"andandtmp",p->topallocapoint()); | |
2235 | |
2236 elem* e = new elem; | |
2237 elem* u = e1->toElem(p); | |
2238 | |
2239 llvm::BasicBlock* oldend = p->scopeend(); | |
2240 llvm::BasicBlock* andand = new llvm::BasicBlock("andand", gIR->topfunc(), oldend); | |
2241 llvm::BasicBlock* andandend = new llvm::BasicBlock("andandend", gIR->topfunc(), oldend); | |
2242 | |
2243 llvm::Value* ubool = LLVM_DtoBoolean(u->getValue()); | |
2244 new llvm::StoreInst(ubool,resval,p->scopebb()); | |
2245 new llvm::BranchInst(andand,andandend,ubool,p->scopebb()); | |
2246 | |
2247 p->scope() = IRScope(andand, andandend); | |
2248 elem* v = e2->toElem(p); | |
2249 | |
2250 llvm::Value* vbool = LLVM_DtoBoolean(v->getValue()); | |
2251 llvm::Value* uandvbool = llvm::BinaryOperator::create(llvm::BinaryOperator::And, ubool, vbool,"tmp",p->scopebb()); | |
2252 new llvm::StoreInst(uandvbool,resval,p->scopebb()); | |
2253 new llvm::BranchInst(andandend,p->scopebb()); | |
2254 | |
2255 delete u; | |
2256 delete v; | |
2257 | |
2258 p->scope() = IRScope(andandend, oldend); | |
2259 | |
2260 e->val = new llvm::LoadInst(resval,"tmp",p->scopebb()); | |
2261 e->type = elem::VAL; | |
2262 | |
2263 return e; | |
2264 } | |
2265 | |
2266 ////////////////////////////////////////////////////////////////////////////////////////// | |
2267 | |
2268 elem* OrOrExp::toElem(IRState* p) | |
2269 { | |
2270 Logger::print("OrOrExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2271 LOG_SCOPE; | |
2272 | |
2273 // allocate a temporary for the final result. failed to come up with a better way :/ | |
2274 llvm::Value* resval = 0; | |
2275 llvm::BasicBlock* entryblock = &p->topfunc()->front(); | |
2276 resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"orortmp",p->topallocapoint()); | |
2277 | |
2278 elem* e = new elem; | |
2279 elem* u = e1->toElem(p); | |
2280 | |
2281 llvm::BasicBlock* oldend = p->scopeend(); | |
2282 llvm::BasicBlock* oror = new llvm::BasicBlock("oror", gIR->topfunc(), oldend); | |
2283 llvm::BasicBlock* ororend = new llvm::BasicBlock("ororend", gIR->topfunc(), oldend); | |
2284 | |
2285 llvm::Value* ubool = LLVM_DtoBoolean(u->getValue()); | |
2286 new llvm::StoreInst(ubool,resval,p->scopebb()); | |
2287 new llvm::BranchInst(ororend,oror,ubool,p->scopebb()); | |
2288 | |
2289 p->scope() = IRScope(oror, ororend); | |
2290 elem* v = e2->toElem(p); | |
2291 | |
2292 llvm::Value* vbool = LLVM_DtoBoolean(v->getValue()); | |
2293 new llvm::StoreInst(vbool,resval,p->scopebb()); | |
2294 new llvm::BranchInst(ororend,p->scopebb()); | |
2295 | |
2296 delete u; | |
2297 delete v; | |
2298 | |
2299 p->scope() = IRScope(ororend, oldend); | |
2300 | |
2301 e->val = new llvm::LoadInst(resval,"tmp",p->scopebb()); | |
2302 e->type = elem::VAL; | |
2303 | |
2304 return e; | |
2305 } | |
2306 | |
2307 ////////////////////////////////////////////////////////////////////////////////////////// | |
2308 | |
2309 #define BinBitExp(X,Y) \ | |
2310 elem* X##Exp::toElem(IRState* p) \ | |
2311 { \ | |
2312 Logger::print("%sExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \ | |
2313 LOG_SCOPE; \ | |
2314 elem* e = new elem; \ | |
2315 elem* u = e1->toElem(p); \ | |
2316 elem* v = e2->toElem(p); \ | |
2317 e->val = llvm::BinaryOperator::create(llvm::Instruction::Y, u->getValue(), v->getValue(), "tmp", p->scopebb()); \ | |
2318 e->type = elem::VAL; \ | |
2319 delete u; \ | |
2320 delete v; \ | |
2321 return e; \ | |
2322 } \ | |
2323 \ | |
2324 elem* X##AssignExp::toElem(IRState* p) \ | |
2325 { \ | |
2326 Logger::print("%sAssignExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \ | |
2327 LOG_SCOPE; \ | |
2328 elem* u = e1->toElem(p); \ | |
2329 elem* v = e2->toElem(p); \ | |
42 | 2330 llvm::Value* uval = u->getValue(); \ |
2331 assert(uval); \ | |
2332 llvm::Value* vval = v->getValue(); \ | |
2333 assert(vval); \ | |
2334 llvm::Value* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \ | |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
2335 if (u->mem == 0) \ |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
28
diff
changeset
|
2336 LLVM_DtoGiveArgumentStorage(u); \ |
42 | 2337 Logger::cout() << *tmp << '|' << *u->mem << '\n'; \ |
1 | 2338 new llvm::StoreInst(LLVM_DtoPointedType(u->mem, tmp), u->mem, p->scopebb()); \ |
2339 delete u; \ | |
2340 delete v; \ | |
2341 elem* e = new elem; \ | |
2342 e->mem = u->mem; \ | |
2343 e->type = elem::VAR; \ | |
2344 return e; \ | |
2345 } | |
2346 | |
2347 BinBitExp(And,And); | |
2348 BinBitExp(Or,Or); | |
2349 BinBitExp(Xor,Xor); | |
2350 BinBitExp(Shl,Shl); | |
2351 BinBitExp(Shr,AShr); | |
2352 BinBitExp(Ushr,LShr); | |
2353 | |
2354 ////////////////////////////////////////////////////////////////////////////////////////// | |
2355 | |
2356 elem* HaltExp::toElem(IRState* p) | |
2357 { | |
2358 Logger::print("HaltExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2359 LOG_SCOPE; | |
2360 | |
36
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2361 llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2362 LLVM_DtoAssert(llvm::ConstantInt::getFalse(), loca, NULL); |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2363 |
40 | 2364 new llvm::UnreachableInst(p->scopebb()); |
1 | 2365 return 0; |
2366 } | |
2367 | |
2368 ////////////////////////////////////////////////////////////////////////////////////////// | |
2369 | |
2370 elem* DelegateExp::toElem(IRState* p) | |
2371 { | |
2372 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2373 LOG_SCOPE; | |
2374 | |
2375 elem* e = new elem; | |
2376 elem* u = e1->toElem(p); | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2377 |
1 | 2378 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
2379 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2380 |
1 | 2381 const llvm::Type* int8ptrty = llvm::PointerType::get(llvm::Type::Int8Ty); |
2382 | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2383 assert(p->topexp() && p->topexp()->e2 == this && p->topexp()->v); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2384 llvm::Value* lval = p->topexp()->v; |
1 | 2385 |
6 | 2386 llvm::Value* context = LLVM_DtoGEP(lval,zero,zero,"tmp",p->scopebb()); |
1 | 2387 llvm::Value* castcontext = new llvm::BitCastInst(u->getValue(),int8ptrty,"tmp",p->scopebb()); |
2388 new llvm::StoreInst(castcontext, context, p->scopebb()); | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2389 |
6 | 2390 llvm::Value* fptr = LLVM_DtoGEP(lval,zero,one,"tmp",p->scopebb()); |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2391 |
1 | 2392 assert(func->llvmValue); |
2393 llvm::Value* castfptr = new llvm::BitCastInst(func->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb()); | |
2394 new llvm::StoreInst(castfptr, fptr, p->scopebb()); | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2395 |
1 | 2396 e->inplace = true; |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2397 |
1 | 2398 delete u; |
2399 return e; | |
2400 } | |
2401 | |
2402 ////////////////////////////////////////////////////////////////////////////////////////// | |
2403 | |
2404 elem* IdentityExp::toElem(IRState* p) | |
2405 { | |
2406 Logger::print("IdentityExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2407 LOG_SCOPE; | |
2408 | |
2409 elem* u = e1->toElem(p); | |
2410 elem* v = e2->toElem(p); | |
2411 | |
2412 elem* e = new elem; | |
2413 | |
2414 llvm::Value* l = u->getValue(); | |
2415 llvm::Value* r = 0; | |
2416 if (v->type == elem::NUL) | |
2417 r = llvm::ConstantPointerNull::get(llvm::cast<llvm::PointerType>(l->getType())); | |
2418 else | |
2419 r = v->getValue(); | |
2420 | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2421 Type* t1 = LLVM_DtoDType(e1->type); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2422 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2423 if (t1->ty == Tarray) { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2424 assert(l->getType() == r->getType()); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2425 e->val = LLVM_DtoDynArrayIs(op,l,r); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2426 } |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2427 else { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2428 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2429 e->val = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb()); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2430 } |
1 | 2431 e->type = elem::VAL; |
2432 | |
2433 delete u; | |
2434 delete v; | |
2435 | |
2436 return e; | |
2437 } | |
2438 | |
2439 ////////////////////////////////////////////////////////////////////////////////////////// | |
2440 | |
2441 elem* CommaExp::toElem(IRState* p) | |
2442 { | |
2443 Logger::print("CommaExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2444 LOG_SCOPE; | |
2445 | |
2446 elem* u = e1->toElem(p); | |
2447 elem* v = e2->toElem(p); | |
2448 delete u; | |
2449 return v; | |
2450 } | |
2451 | |
2452 ////////////////////////////////////////////////////////////////////////////////////////// | |
2453 | |
2454 elem* CondExp::toElem(IRState* p) | |
2455 { | |
2456 Logger::print("CondExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2457 LOG_SCOPE; | |
2458 | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2459 Type* dtype = LLVM_DtoDType(type); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2460 const llvm::Type* resty = LLVM_DtoType(dtype); |
1 | 2461 |
2462 // allocate a temporary for the final result. failed to come up with a better way :/ | |
2463 llvm::BasicBlock* entryblock = &p->topfunc()->front(); | |
2464 llvm::Value* resval = new llvm::AllocaInst(resty,"condtmp",p->topallocapoint()); | |
2465 | |
2466 llvm::BasicBlock* oldend = p->scopeend(); | |
2467 llvm::BasicBlock* condtrue = new llvm::BasicBlock("condtrue", gIR->topfunc(), oldend); | |
2468 llvm::BasicBlock* condfalse = new llvm::BasicBlock("condfalse", gIR->topfunc(), oldend); | |
2469 llvm::BasicBlock* condend = new llvm::BasicBlock("condend", gIR->topfunc(), oldend); | |
2470 | |
2471 elem* c = econd->toElem(p); | |
2472 llvm::Value* cond_val = LLVM_DtoBoolean(c->getValue()); | |
2473 delete c; | |
2474 new llvm::BranchInst(condtrue,condfalse,cond_val,p->scopebb()); | |
2475 | |
2476 p->scope() = IRScope(condtrue, condfalse); | |
2477 elem* u = e1->toElem(p); | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2478 LLVM_DtoAssign(dtype, resval, u->getValue()); |
1 | 2479 new llvm::BranchInst(condend,p->scopebb()); |
2480 delete u; | |
2481 | |
2482 p->scope() = IRScope(condfalse, condend); | |
2483 elem* v = e2->toElem(p); | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2484 LLVM_DtoAssign(dtype, resval, v->getValue()); |
1 | 2485 new llvm::BranchInst(condend,p->scopebb()); |
2486 delete v; | |
2487 | |
2488 p->scope() = IRScope(condend, oldend); | |
2489 | |
2490 elem* e = new elem; | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2491 e->mem = resval; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2492 e->type = elem::VAR; |
1 | 2493 return e; |
2494 } | |
2495 | |
2496 ////////////////////////////////////////////////////////////////////////////////////////// | |
2497 | |
2498 elem* ComExp::toElem(IRState* p) | |
2499 { | |
2500 Logger::print("ComExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2501 LOG_SCOPE; | |
2502 | |
2503 elem* e = new elem; | |
2504 elem* u = e1->toElem(p); | |
2505 | |
2506 llvm::Value* value = u->getValue(); | |
2507 llvm::Value* minusone = llvm::ConstantInt::get(value->getType(), -1, true); | |
2508 e->val = llvm::BinaryOperator::create(llvm::Instruction::Xor, value, minusone, "tmp", p->scopebb()); | |
2509 | |
2510 delete u; | |
2511 | |
2512 e->type = elem::VAL; | |
2513 | |
2514 return e; | |
2515 } | |
2516 | |
2517 ////////////////////////////////////////////////////////////////////////////////////////// | |
2518 | |
23 | 2519 elem* NegExp::toElem(IRState* p) |
2520 { | |
2521 Logger::print("NegExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2522 LOG_SCOPE; | |
2523 elem* e = new elem; | |
2524 elem* l = e1->toElem(p); | |
2525 llvm::Value* val = l->getValue(); | |
2526 delete l; | |
2527 | |
40 | 2528 Type* t = LLVM_DtoDType(type); |
2529 | |
23 | 2530 llvm::Value* zero = 0; |
40 | 2531 if (t->isintegral()) |
23 | 2532 zero = llvm::ConstantInt::get(val->getType(), 0, true); |
40 | 2533 else if (t->isfloating()) { |
2534 if (t->ty == Tfloat32) | |
23 | 2535 zero = llvm::ConstantFP::get(val->getType(), float(0)); |
40 | 2536 else if (t->ty == Tfloat64 || t->ty == Tfloat80) |
23 | 2537 zero = llvm::ConstantFP::get(val->getType(), double(0)); |
2538 else | |
2539 assert(0); | |
2540 } | |
2541 else | |
2542 assert(0); | |
2543 | |
2544 e->val = llvm::BinaryOperator::createSub(zero,val,"tmp",p->scopebb()); | |
2545 e->type = elem::VAL; | |
2546 | |
2547 return e; | |
2548 } | |
2549 | |
2550 ////////////////////////////////////////////////////////////////////////////////////////// | |
2551 | |
36
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2552 elem* CatExp::toElem(IRState* p) |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2553 { |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2554 Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars()); |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2555 LOG_SCOPE; |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2556 |
40 | 2557 assert(0 && "array cat is not yet implemented"); |
36
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2558 |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2559 elem* lhs = e1->toElem(p); |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2560 elem* rhs = e2->toElem(p); |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2561 |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2562 // determine new size |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2563 |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2564 delete lhs; |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2565 delete rhs; |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2566 |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2567 return 0; |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2568 } |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2569 |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2570 ////////////////////////////////////////////////////////////////////////////////////////// |
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2571 |
40 | 2572 elem* CatAssignExp::toElem(IRState* p) |
2573 { | |
2574 Logger::print("CatAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2575 LOG_SCOPE; | |
2576 | |
2577 elem* l = e1->toElem(p); | |
2578 assert(l->mem); | |
2579 | |
2580 Type* e1type = LLVM_DtoDType(e1->type); | |
2581 Type* elemtype = LLVM_DtoDType(e1type->next); | |
2582 Type* e2type = LLVM_DtoDType(e2->type); | |
2583 | |
2584 if (e2type == elemtype) { | |
2585 LLVM_DtoCatArrayElement(l->mem,e2); | |
2586 } | |
2587 else | |
2588 assert(0 && "only one element at a time right now"); | |
2589 | |
2590 return 0; | |
2591 } | |
2592 | |
2593 ////////////////////////////////////////////////////////////////////////////////////////// | |
2594 | |
2595 elem* ArrayLiteralExp::toElem(IRState* p) | |
2596 { | |
2597 Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2598 LOG_SCOPE; | |
2599 | |
2600 const llvm::Type* t = LLVM_DtoType(type); | |
2601 Logger::cout() << "array literal has llvm type: " << *t << '\n'; | |
2602 | |
2603 llvm::Value* mem = 0; | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2604 if (!p->topexp() || p->topexp()->e2 != this) { |
40 | 2605 assert(LLVM_DtoDType(type)->ty == Tsarray); |
2606 mem = new llvm::AllocaInst(t,"tmparrayliteral",p->topallocapoint()); | |
2607 } | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2608 else if (p->topexp()->e2 == this) { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2609 mem = p->topexp()->v; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2610 assert(mem); |
40 | 2611 if (!llvm::isa<llvm::PointerType>(mem->getType()) || |
2612 !llvm::isa<llvm::ArrayType>(mem->getType()->getContainedType(0))) | |
2613 { | |
2614 error("TODO array literals can currently only be used to initialise static arrays"); | |
2615 fatal(); | |
2616 } | |
2617 } | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2618 else |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2619 assert(0); |
40 | 2620 |
2621 for (unsigned i=0; i<elements->dim; ++i) | |
2622 { | |
2623 Expression* expr = (Expression*)elements->data[i]; | |
2624 llvm::Value* elemAddr = LLVM_DtoGEPi(mem,0,i,"tmp",p->scopebb()); | |
2625 elem* e = expr->toElem(p); | |
2626 new llvm::StoreInst(e->getValue(), elemAddr, p->scopebb()); | |
2627 } | |
2628 | |
2629 elem* e = new elem; | |
2630 e->mem = mem; | |
2631 e->type = elem::VAL; | |
2632 e->inplace = true; | |
2633 | |
2634 return e; | |
2635 } | |
2636 | |
2637 ////////////////////////////////////////////////////////////////////////////////////////// | |
2638 | |
2639 llvm::Constant* ArrayLiteralExp::toConstElem(IRState* p) | |
2640 { | |
2641 Logger::print("ArrayLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | |
2642 LOG_SCOPE; | |
2643 | |
2644 const llvm::Type* t = LLVM_DtoType(type); | |
2645 Logger::cout() << "array literal has llvm type: " << *t << '\n'; | |
2646 assert(llvm::isa<llvm::ArrayType>(t)); | |
2647 const llvm::ArrayType* arrtype = llvm::cast<llvm::ArrayType>(t); | |
2648 | |
2649 assert(arrtype->getNumElements() == elements->dim); | |
2650 std::vector<llvm::Constant*> vals(elements->dim, NULL); | |
2651 for (unsigned i=0; i<elements->dim; ++i) | |
2652 { | |
2653 Expression* expr = (Expression*)elements->data[i]; | |
2654 vals[i] = expr->toConstElem(p); | |
2655 } | |
2656 | |
2657 return llvm::ConstantArray::get(arrtype, vals); | |
2658 } | |
2659 | |
2660 ////////////////////////////////////////////////////////////////////////////////////////// | |
2661 | |
49
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2662 elem* FuncExp::toElem(IRState* p) |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2663 { |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2664 Logger::print("FuncExp::toElem: %s | %s\n", toChars(), type->toChars()); |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2665 LOG_SCOPE; |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2666 |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2667 assert(fd); |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2668 |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2669 if (fd->isNested()) Logger::println("nested"); |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2670 Logger::println("kind = %s\n", fd->kind()); |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2671 |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2672 fd->toObjFile(); |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2673 |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2674 llvm::Value* lval = NULL; |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2675 if (!p->topexp() || p->topexp()->e2 != this) { |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2676 const llvm::Type* dgty = LLVM_DtoType(type); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2677 Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2678 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2679 } |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2680 else if (p->topexp()->e2 == this) { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2681 lval = p->topexp()->v; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2682 assert(lval); |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2683 } |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2684 else |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
2685 assert(0); |
49
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2686 |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2687 elem* e = new elem; |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2688 |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2689 llvm::Value* context = LLVM_DtoGEPi(lval,0,0,"tmp",p->scopebb()); |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2690 const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(context->getType()->getContainedType(0)); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2691 llvm::Value* llvmNested = p->func().decl->llvmNested; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2692 if (llvmNested == NULL) { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2693 llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2694 p->ir->CreateStore(nullcontext, context); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2695 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2696 else { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2697 llvm::Value* nestedcontext = p->ir->CreateBitCast(llvmNested, pty, "tmp"); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2698 p->ir->CreateStore(nestedcontext, context); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2699 } |
49
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2700 |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2701 llvm::Value* fptr = LLVM_DtoGEPi(lval,0,1,"tmp",p->scopebb()); |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2702 |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2703 assert(fd->llvmValue); |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2704 llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb()); |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2705 new llvm::StoreInst(castfptr, fptr, p->scopebb()); |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2706 |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2707 e->inplace = true; |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2708 e->mem = lval; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
2709 e->type = elem::VAR; |
49
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2710 |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2711 return e; |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2712 } |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2713 |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2714 ////////////////////////////////////////////////////////////////////////////////////////// |
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2715 |
1 | 2716 #define STUB(x) elem *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; } |
2717 //STUB(IdentityExp); | |
2718 //STUB(CondExp); | |
2719 //STUB(EqualExp); | |
2720 STUB(InExp); | |
2721 //STUB(CmpExp); | |
2722 //STUB(AndAndExp); | |
2723 //STUB(OrOrExp); | |
2724 //STUB(AndExp); | |
2725 //STUB(AndAssignExp); | |
2726 //STUB(OrExp); | |
2727 //STUB(OrAssignExp); | |
2728 //STUB(XorExp); | |
2729 //STUB(XorAssignExp); | |
2730 //STUB(ShrExp); | |
2731 //STUB(ShrAssignExp); | |
2732 //STUB(ShlExp); | |
2733 //STUB(ShlAssignExp); | |
2734 //STUB(UshrExp); | |
2735 //STUB(UshrAssignExp); | |
2736 //STUB(DivExp); | |
2737 //STUB(DivAssignExp); | |
2738 //STUB(MulExp); | |
2739 //STUB(MulAssignExp); | |
2740 //STUB(ModExp); | |
2741 //STUB(ModAssignExp); | |
36
c0967c4b2a74
[svn r40] Cleaned up some of the array routines to use gep/load/store instead of memcpy/memset.
lindquist
parents:
34
diff
changeset
|
2742 //STUB(CatExp); |
40 | 2743 //STUB(CatAssignExp); |
1 | 2744 //STUB(AddExp); |
2745 //STUB(AddAssignExp); | |
2746 STUB(Expression); | |
2747 //STUB(MinExp); | |
2748 //STUB(MinAssignExp); | |
2749 //STUB(PostExp); | |
2750 //STUB(NullExp); | |
2751 //STUB(ThisExp); | |
2752 //STUB(CallExp); | |
2753 STUB(DotTypeExp); | |
2754 STUB(TypeDotIdExp); | |
2755 //STUB(DotVarExp); | |
2756 //STUB(AssertExp); | |
49
e5c4bece7fa1
[svn r53] added basic support for delegate literals. if you access outer variables you get a broken module
lindquist
parents:
48
diff
changeset
|
2757 //STUB(FuncExp); |
1 | 2758 //STUB(DelegateExp); |
2759 //STUB(VarExp); | |
2760 //STUB(DeclarationExp); | |
2761 //STUB(NewExp); | |
2762 //STUB(SymOffExp); | |
2763 STUB(ScopeExp); | |
2764 //STUB(AssignExp); | |
2765 | |
2766 STUB(TypeExp); | |
2767 //STUB(RealExp); | |
2768 STUB(ComplexExp); | |
2769 //STUB(StringExp); | |
2770 //STUB(IntegerExp); | |
2771 STUB(BoolExp); | |
2772 | |
2773 //STUB(NotExp); | |
2774 //STUB(ComExp); | |
23 | 2775 //STUB(NegExp); |
1 | 2776 //STUB(PtrExp); |
2777 //STUB(AddrExp); | |
2778 //STUB(SliceExp); | |
2779 //STUB(CastExp); | |
2780 //STUB(DeleteExp); | |
2781 //STUB(IndexExp); | |
2782 //STUB(CommaExp); | |
2783 //STUB(ArrayLengthExp); | |
2784 //STUB(HaltExp); | |
2785 STUB(RemoveExp); | |
40 | 2786 //STUB(ArrayLiteralExp); |
1 | 2787 STUB(AssocArrayLiteralExp); |
2788 //STUB(StructLiteralExp); | |
2789 | |
40 | 2790 #define CONSTSTUB(x) llvm::Constant* x::toConstElem(IRState * p) {error("const Exp type "#x" not implemented: '%s' type: '%s'", toChars(), type->toChars()); assert(0); fatal(); return NULL; } |
2791 CONSTSTUB(Expression); | |
2792 //CONSTSTUB(IntegerExp); | |
2793 //CONSTSTUB(RealExp); | |
2794 //CONSTSTUB(NullExp); | |
2795 //CONSTSTUB(StringExp); | |
2796 //CONSTSTUB(VarExp); | |
2797 //CONSTSTUB(ArrayLiteralExp); | |
2798 CONSTSTUB(AssocArrayLiteralExp); | |
2799 //CONSTSTUB(StructLiteralExp); | |
2800 | |
1 | 2801 unsigned Type::totym() { return 0; } |
2802 | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2803 type * Type::toCtype() |
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2804 { |
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2805 assert(0); |
1 | 2806 return 0; |
2807 } | |
2808 | |
2809 type * Type::toCParamtype() | |
2810 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2811 assert(0); |
1 | 2812 return 0; |
2813 } | |
2814 Symbol * Type::toSymbol() | |
2815 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2816 assert(0); |
1 | 2817 return 0; |
2818 } | |
2819 | |
2820 type * | |
2821 TypeTypedef::toCtype() | |
2822 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2823 assert(0); |
1 | 2824 return 0; |
2825 } | |
2826 | |
2827 type * | |
2828 TypeTypedef::toCParamtype() | |
2829 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2830 assert(0); |
1 | 2831 return 0; |
2832 } | |
2833 | |
2834 void | |
2835 TypedefDeclaration::toDebug() | |
2836 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2837 assert(0); |
1 | 2838 } |
2839 | |
2840 | |
2841 type * | |
2842 TypeEnum::toCtype() | |
2843 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2844 assert(0); |
1 | 2845 return 0; |
2846 } | |
2847 | |
2848 type * | |
2849 TypeStruct::toCtype() | |
2850 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2851 assert(0); |
1 | 2852 return 0; |
2853 } | |
2854 | |
2855 void | |
2856 StructDeclaration::toDebug() | |
2857 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2858 assert(0); |
1 | 2859 } |
2860 | |
2861 Symbol * TypeClass::toSymbol() | |
2862 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2863 assert(0); |
1 | 2864 return 0; |
2865 } | |
2866 | |
2867 unsigned TypeFunction::totym() | |
2868 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2869 assert(0); |
1 | 2870 return 0; |
2871 } | |
2872 | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2873 type * TypeFunction::toCtype() |
1 | 2874 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2875 assert(0); |
1 | 2876 return 0; |
2877 } | |
2878 | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2879 type * TypeSArray::toCtype() |
1 | 2880 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2881 assert(0); |
1 | 2882 return 0; |
2883 } | |
2884 | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2885 type *TypeSArray::toCParamtype() |
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2886 { |
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2887 assert(0); |
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2888 return 0; |
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2889 } |
1 | 2890 |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2891 type * TypeDArray::toCtype() |
1 | 2892 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2893 assert(0); |
1 | 2894 return 0; |
2895 } | |
2896 | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2897 type * TypeAArray::toCtype() |
1 | 2898 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2899 assert(0); |
1 | 2900 return 0; |
2901 } | |
2902 | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2903 type * TypePointer::toCtype() |
1 | 2904 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2905 assert(0); |
1 | 2906 return 0; |
2907 } | |
2908 | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2909 type * TypeDelegate::toCtype() |
1 | 2910 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2911 assert(0); |
1 | 2912 return 0; |
2913 } | |
2914 | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2915 type * TypeClass::toCtype() |
1 | 2916 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2917 assert(0); |
1 | 2918 return 0; |
2919 } | |
2920 | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2921 void ClassDeclaration::toDebug() |
1 | 2922 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2923 assert(0); |
1 | 2924 } |
2925 | |
14
0e86428ee567
[svn r18] * Initial support for switch statements - No string switches yet.
lindquist
parents:
11
diff
changeset
|
2926 ////////////////////////////////////////////////////////////////////////////// |
1 | 2927 |
2928 void | |
2929 EnumDeclaration::toDebug() | |
2930 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2931 assert(0); |
1 | 2932 } |
2933 | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2934 int Dsymbol::cvMember(unsigned char*) |
1 | 2935 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2936 assert(0); |
1 | 2937 return 0; |
2938 } | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2939 int EnumDeclaration::cvMember(unsigned char*) |
1 | 2940 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2941 assert(0); |
1 | 2942 return 0; |
2943 } | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2944 int FuncDeclaration::cvMember(unsigned char*) |
1 | 2945 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2946 assert(0); |
1 | 2947 return 0; |
2948 } | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2949 int VarDeclaration::cvMember(unsigned char*) |
1 | 2950 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2951 assert(0); |
1 | 2952 return 0; |
2953 } | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2954 int TypedefDeclaration::cvMember(unsigned char*) |
1 | 2955 { |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2956 assert(0); |
1 | 2957 return 0; |
2958 } | |
2959 | |
2960 void obj_includelib(char*){} | |
2961 | |
2962 AsmStatement::AsmStatement(Loc loc, Token *tokens) : | |
2963 Statement(loc) | |
2964 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2965 assert(0); |
1 | 2966 } |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2967 Statement *AsmStatement::syntaxCopy() |
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2968 { |
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2969 assert(0); |
1 | 2970 return 0; |
2971 } | |
2972 | |
2973 Statement *AsmStatement::semantic(Scope *sc) | |
2974 { | |
2975 return Statement::semantic(sc); | |
2976 } | |
2977 | |
2978 | |
2979 void AsmStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
2980 { | |
2981 Statement::toCBuffer(buf, hgs); | |
2982 } | |
2983 | |
2984 int AsmStatement::comeFrom() | |
2985 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2986 assert(0); |
1 | 2987 return FALSE; |
2988 } | |
2989 | |
2990 void | |
2991 backend_init() | |
2992 { | |
37
77cdca8c210f
[svn r41] new'd dynamic arrays are now initialized with the element type's default initializer.
lindquist
parents:
36
diff
changeset
|
2993 // now lazily loaded |
1 | 2994 //LLVM_D_InitRuntime(); |
2995 } | |
2996 | |
2997 void | |
2998 backend_term() | |
2999 { | |
3000 LLVM_D_FreeRuntime(); | |
3001 } |