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