Mercurial > projects > ldc
annotate gen/tollvm.c @ 83:339422268de1 trunk
[svn r87] Fixed some memory bloat when passing string literals as char[] params (double temporary before)
author | lindquist |
---|---|
date | Fri, 02 Nov 2007 02:03:13 +0100 |
parents | d8dd47ef3973 |
children | f869c636a113 |
rev | line source |
---|---|
1 | 1 #include <iostream> |
2 | |
40 | 3 #include "gen/llvm.h" |
1 | 4 |
5 #include "mtype.h" | |
6 #include "dsymbol.h" | |
7 #include "aggregate.h" | |
8 #include "declaration.h" | |
9 #include "init.h" | |
10 | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
11 #include "gen/tollvm.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
12 #include "gen/irstate.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
13 #include "gen/logger.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
14 #include "gen/runtime.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
15 #include "gen/elem.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
16 #include "gen/arrays.h" |
1 | 17 |
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
|
18 bool DtoIsPassedByRef(Type* type) |
40 | 19 { |
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
|
20 TY t = DtoDType(type)->ty; |
73 | 21 return (t == Tstruct || t == Tarray || t == Tdelegate); |
40 | 22 } |
23 | |
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
|
24 Type* DtoDType(Type* t) |
40 | 25 { |
26 if (t->ty == Ttypedef) { | |
27 Type* bt = t->toBasetype(); | |
28 assert(bt); | |
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
|
29 return DtoDType(bt); |
40 | 30 } |
31 return t; | |
32 } | |
33 | |
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
|
34 const llvm::Type* DtoType(Type* t) |
1 | 35 { |
36 assert(t); | |
37 switch (t->ty) | |
38 { | |
39 // integers | |
40 case Tint8: | |
41 case Tuns8: | |
42 case Tchar: | |
43 return (const llvm::Type*)llvm::Type::Int8Ty; | |
44 case Tint16: | |
45 case Tuns16: | |
46 case Twchar: | |
47 return (const llvm::Type*)llvm::Type::Int16Ty; | |
48 case Tint32: | |
49 case Tuns32: | |
50 case Tdchar: | |
51 return (const llvm::Type*)llvm::Type::Int32Ty; | |
52 case Tint64: | |
53 case Tuns64: | |
54 return (const llvm::Type*)llvm::Type::Int64Ty; | |
55 | |
56 case Tbool: | |
57 return (const llvm::Type*)llvm::ConstantInt::getTrue()->getType(); | |
58 | |
59 // floats | |
60 case Tfloat32: | |
62
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
61 case Timaginary32: |
1 | 62 return llvm::Type::FloatTy; |
63 case Tfloat64: | |
62
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
64 case Timaginary64: |
1 | 65 case Tfloat80: |
62
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
66 case Timaginary80: |
1 | 67 return llvm::Type::DoubleTy; |
68 | |
62
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
69 // complex |
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
70 case Tcomplex32: |
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
71 case Tcomplex64: |
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
72 case Tcomplex80: |
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
73 assert(0 && "complex number types not yet implemented"); |
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
74 |
1 | 75 // pointers |
76 case Tpointer: { | |
77 assert(t->next); | |
78 if (t->next->ty == Tvoid) | |
79 return (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty); | |
80 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
|
81 return (const llvm::Type*)llvm::PointerType::get(DtoType(t->next)); |
1 | 82 } |
83 | |
84 // arrays | |
85 case 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
|
86 return DtoArrayType(t); |
1 | 87 case 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
|
88 return DtoStaticArrayType(t); |
1 | 89 |
90 // void | |
91 case Tvoid: | |
92 return llvm::Type::VoidTy; | |
93 | |
94 // aggregates | |
95 case Tstruct: { | |
96 if (t->llvmType == 0) | |
97 { | |
98 // recursive or cyclic declaration | |
99 if (!gIR->structs.empty()) | |
100 { | |
101 IRStruct* found = 0; | |
102 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i) | |
103 { | |
104 if (t == i->type) | |
105 { | |
106 return i->recty.get(); | |
107 } | |
108 } | |
109 } | |
110 | |
111 // forward declaration | |
112 TypeStruct* ts = (TypeStruct*)t; | |
113 assert(ts->sym); | |
114 ts->sym->toObjFile(); | |
115 } | |
116 return t->llvmType; | |
117 } | |
118 | |
119 case Tclass: { | |
120 if (t->llvmType == 0) | |
121 { | |
6 | 122 // recursive or cyclic declaration |
123 if (!gIR->structs.empty()) | |
124 { | |
125 IRStruct* found = 0; | |
126 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i) | |
127 { | |
128 if (t == i->type) | |
129 { | |
130 return llvm::PointerType::get(i->recty.get()); | |
131 } | |
132 } | |
133 } | |
134 | |
135 // forward declaration | |
1 | 136 TypeClass* tc = (TypeClass*)t; |
137 assert(tc->sym); | |
6 | 138 tc->sym->toObjFile(); |
1 | 139 } |
140 return llvm::PointerType::get(t->llvmType); | |
141 } | |
142 | |
143 // functions | |
144 case Tfunction: | |
145 { | |
146 if (t->llvmType == 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
|
147 return DtoFunctionType(t,NULL); |
1 | 148 } |
149 else { | |
150 return t->llvmType; | |
151 } | |
152 } | |
6 | 153 |
1 | 154 // delegates |
155 case Tdelegate: | |
156 { | |
157 if (t->llvmType == 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
|
158 return DtoDelegateType(t); |
1 | 159 } |
160 else { | |
161 return t->llvmType; | |
162 } | |
163 } | |
164 | |
165 // typedefs | |
52 | 166 // enum |
1 | 167 case Ttypedef: |
52 | 168 case Tenum: |
1 | 169 { |
170 Type* bt = t->toBasetype(); | |
171 assert(bt); | |
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
|
172 return DtoType(bt); |
1 | 173 } |
174 | |
175 default: | |
176 printf("trying to convert unknown type with value %d\n", t->ty); | |
177 assert(0); | |
178 } | |
179 return 0; | |
180 } | |
181 | |
182 ////////////////////////////////////////////////////////////////////////////////////////// | |
183 | |
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
|
184 const llvm::FunctionType* DtoFunctionType(Type* type, const llvm::Type* thistype, bool ismain) |
1 | 185 { |
72 | 186 TypeFunction* f = (TypeFunction*)type; |
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
|
187 assert(f != 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
|
188 |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
189 bool typesafeVararg = false; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
190 if (f->linkage == LINKd && f->varargs == 1) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
191 typesafeVararg = true; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
192 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
193 |
1 | 194 // return value type |
195 const llvm::Type* rettype; | |
196 const llvm::Type* actualRettype; | |
197 Type* rt = f->next; | |
198 bool retinptr = false; | |
199 bool usesthis = false; | |
200 | |
72 | 201 if (ismain) { |
1 | 202 rettype = llvm::Type::Int32Ty; |
203 actualRettype = rettype; | |
204 } | |
72 | 205 else { |
206 assert(rt); | |
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 if (DtoIsPassedByRef(rt)) { |
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
|
208 rettype = llvm::PointerType::get(DtoType(rt)); |
1 | 209 actualRettype = llvm::Type::VoidTy; |
210 f->llvmRetInPtr = retinptr = true; | |
211 } | |
212 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
|
213 rettype = DtoType(rt); |
1 | 214 actualRettype = rettype; |
215 } | |
216 } | |
217 | |
218 // parameter types | |
219 std::vector<const llvm::Type*> paramvec; | |
220 | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
221 if (retinptr) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
222 Logger::cout() << "returning through pointer parameter: " << *rettype << '\n'; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
223 paramvec.push_back(rettype); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
224 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
225 |
72 | 226 if (thistype) { |
227 paramvec.push_back(thistype); | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
228 usesthis = true; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
229 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
230 |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
231 if (typesafeVararg) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
232 ClassDeclaration* ti = Type::typeinfo; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
233 if (!ti->llvmInitZ) |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
234 ti->toObjFile(); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
235 assert(ti->llvmInitZ); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
236 std::vector<const llvm::Type*> types; |
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
|
237 types.push_back(DtoSize_t()); |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
238 types.push_back(llvm::PointerType::get(llvm::PointerType::get(ti->llvmInitZ->getType()))); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
239 const llvm::Type* t1 = llvm::StructType::get(types); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
240 paramvec.push_back(llvm::PointerType::get(t1)); |
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
|
241 paramvec.push_back(llvm::PointerType::get(llvm::Type::Int8Ty)); |
1 | 242 } |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
243 |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
244 size_t n = Argument::dim(f->parameters); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
245 |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
246 for (int i=0; i < n; ++i) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
247 Argument* arg = Argument::getNth(f->parameters, i); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
248 // ensure scalar |
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
|
249 Type* argT = DtoDType(arg->type); |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
250 assert(argT); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
251 |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
252 if ((arg->storageClass & STCref) || (arg->storageClass & STCout)) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
253 //assert(arg->vardecl); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
254 //arg->vardecl->refparam = true; |
9 | 255 } |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
256 else |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
257 arg->llvmCopy = true; |
1 | 258 |
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
|
259 const llvm::Type* at = DtoType(argT); |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
260 if (llvm::isa<llvm::StructType>(at)) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
261 Logger::println("struct param"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
262 paramvec.push_back(llvm::PointerType::get(at)); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
263 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
264 else if (llvm::isa<llvm::ArrayType>(at)) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
265 Logger::println("sarray param"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
266 assert(argT->ty == Tsarray); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
267 //paramvec.push_back(llvm::PointerType::get(at->getContainedType(0))); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
268 paramvec.push_back(llvm::PointerType::get(at)); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
269 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
270 else if (llvm::isa<llvm::OpaqueType>(at)) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
271 Logger::println("opaque param"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
272 if (argT->ty == Tstruct || argT->ty == Tclass) |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
273 paramvec.push_back(llvm::PointerType::get(at)); |
40 | 274 else |
275 assert(0); | |
276 } | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
277 /*if (llvm::isa<llvm::StructType>(at) || argT->ty == Tstruct || argT->ty == Tsarray) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
278 paramvec.push_back(llvm::PointerType::get(at)); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
279 }*/ |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
280 else { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
281 if (!arg->llvmCopy) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
282 Logger::println("ref param"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
283 at = llvm::PointerType::get(at); |
1 | 284 } |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
285 else { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
286 Logger::println("in param"); |
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
|
287 } |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
288 paramvec.push_back(at); |
1 | 289 } |
290 } | |
291 | |
292 // construct function type | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
293 bool isvararg = !typesafeVararg && f->varargs; |
1 | 294 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); |
295 | |
9 | 296 f->llvmRetInPtr = retinptr; |
297 f->llvmUsesThis = usesthis; | |
1 | 298 return functype; |
299 } | |
300 | |
301 ////////////////////////////////////////////////////////////////////////////////////////// | |
302 | |
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
|
303 static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl) |
72 | 304 { |
305 TypeFunction* f = (TypeFunction*)fdecl->type; | |
306 assert(f != 0); | |
307 | |
308 const llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
309 std::vector<const llvm::Type*> args; | |
310 | |
311 if (fdecl->llvmInternal == LLVMva_start) { | |
312 args.push_back(i8pty); | |
313 } | |
314 else if (fdecl->llvmInternal == LLVMva_intrinsic) { | |
315 size_t n = Argument::dim(f->parameters); | |
316 for (size_t i=0; i<n; ++i) { | |
317 args.push_back(i8pty); | |
318 } | |
319 } | |
320 else | |
321 assert(0); | |
322 | |
323 const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::VoidTy, args, false); | |
324 f->llvmType = fty; | |
325 return fty; | |
326 } | |
327 | |
328 ////////////////////////////////////////////////////////////////////////////////////////// | |
329 | |
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
|
330 const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl) |
72 | 331 { |
332 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == 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
|
333 return DtoVaFunctionType(fdecl); |
72 | 334 } |
335 | |
336 // type has already been resolved | |
337 if (fdecl->type->llvmType != 0) { | |
338 return llvm::cast<llvm::FunctionType>(fdecl->type->llvmType); | |
339 } | |
340 | |
341 const llvm::Type* thisty = NULL; | |
342 if (fdecl->needThis()) { | |
343 if (AggregateDeclaration* ad = fdecl->isMember()) { | |
344 Logger::print("isMember = this is: %s\n", ad->type->toChars()); | |
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
|
345 thisty = DtoType(ad->type); |
72 | 346 Logger::cout() << "this llvm type: " << *thisty << '\n'; |
347 if (llvm::isa<llvm::StructType>(thisty) || thisty == gIR->topstruct().recty.get()) | |
348 thisty = llvm::PointerType::get(thisty); | |
349 } | |
350 else | |
351 assert(0); | |
352 } | |
353 else if (fdecl->isNested()) { | |
354 thisty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
355 } | |
356 | |
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
|
357 const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, fdecl->isMain()); |
72 | 358 fdecl->type->llvmType = functype; |
359 return functype; | |
360 } | |
361 | |
362 ////////////////////////////////////////////////////////////////////////////////////////// | |
363 | |
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
|
364 const llvm::StructType* DtoDelegateType(Type* t) |
1 | 365 { |
366 const llvm::Type* i8ptr = llvm::PointerType::get(llvm::Type::Int8Ty); | |
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
|
367 const llvm::Type* func = DtoFunctionType(t->next, i8ptr); |
1 | 368 const llvm::Type* funcptr = llvm::PointerType::get(func); |
369 | |
370 std::vector<const llvm::Type*> types; | |
371 types.push_back(i8ptr); | |
372 types.push_back(funcptr); | |
373 return llvm::StructType::get(types); | |
374 } | |
375 | |
376 ////////////////////////////////////////////////////////////////////////////////////////// | |
377 | |
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
|
378 const llvm::Type* DtoStructType(Type* t) |
1 | 379 { |
380 assert(0); | |
381 std::vector<const llvm::Type*> types; | |
382 return llvm::StructType::get(types); | |
383 } | |
384 | |
385 | |
386 ////////////////////////////////////////////////////////////////////////////////////////// | |
387 | |
388 static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false) | |
389 { | |
390 assert(bits == 32 || bits == 64); | |
391 const llvm::Type* int8ty = (const llvm::Type*)llvm::Type::Int8Ty; | |
392 const llvm::Type* int32ty = (const llvm::Type*)llvm::Type::Int32Ty; | |
393 const llvm::Type* int64ty = (const llvm::Type*)llvm::Type::Int64Ty; | |
394 const llvm::Type* int8ptrty = (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty); | |
395 const llvm::Type* voidty = (const llvm::Type*)llvm::Type::VoidTy; | |
396 | |
397 assert(gIR); | |
398 assert(gIR->module); | |
399 | |
400 // parameter types | |
401 std::vector<const llvm::Type*> pvec; | |
402 pvec.push_back(int8ptrty); | |
403 pvec.push_back(set?int8ty:int8ptrty); | |
404 pvec.push_back(bits==32?int32ty:int64ty); | |
405 pvec.push_back(int32ty); | |
406 llvm::FunctionType* functype = llvm::FunctionType::get(voidty, pvec, false); | |
407 return new llvm::Function(functype, llvm::GlobalValue::ExternalLinkage, name, gIR->module); | |
408 } | |
409 | |
410 ////////////////////////////////////////////////////////////////////////////////////////// | |
411 | |
412 // llvm.memset.i32 | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
413 llvm::Function* LLVM_DeclareMemSet32() |
1 | 414 { |
415 static llvm::Function* _func = 0; | |
416 if (_func == 0) { | |
417 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i32", 32, true); | |
418 } | |
419 return _func; | |
420 } | |
421 | |
422 ////////////////////////////////////////////////////////////////////////////////////////// | |
423 | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
424 llvm::Function* LLVM_DeclareMemSet64() |
1 | 425 { |
426 static llvm::Function* _func = 0; | |
427 if (_func == 0) { | |
428 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i64", 64, true); | |
429 } | |
430 return _func; | |
431 } | |
432 | |
433 ////////////////////////////////////////////////////////////////////////////////////////// | |
434 | |
435 // llvm.memcpy.i32 | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
436 llvm::Function* LLVM_DeclareMemCpy32() |
1 | 437 { |
438 static llvm::Function* _func = 0; | |
439 if (_func == 0) { | |
440 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i32", 32); | |
441 } | |
442 return _func; | |
443 } | |
444 | |
445 ////////////////////////////////////////////////////////////////////////////////////////// | |
446 | |
447 // llvm.memcpy.i64 | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
448 llvm::Function* LLVM_DeclareMemCpy64() |
1 | 449 { |
450 static llvm::Function* _func = 0; | |
451 if (_func == 0) { | |
452 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i64", 64); | |
453 } | |
454 return _func; | |
455 } | |
456 | |
457 ////////////////////////////////////////////////////////////////////////////////////////// | |
458 | |
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
|
459 llvm::Value* DtoStructZeroInit(llvm::Value* v) |
1 | 460 { |
461 assert(gIR); | |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
462 uint64_t n = gTargetData->getTypeSize(v->getType()->getContainedType(0)); |
1 | 463 //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n)); |
464 llvm::Type* sarrty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
465 | |
466 llvm::Value* sarr = new llvm::BitCastInst(v,sarrty,"tmp",gIR->scopebb()); | |
467 | |
468 llvm::Function* fn = LLVM_DeclareMemSet32(); | |
469 std::vector<llvm::Value*> llargs; | |
470 llargs.resize(4); | |
471 llargs[0] = sarr; | |
472 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); | |
473 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
474 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
475 | |
476 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
477 | |
478 return ret; | |
479 } | |
480 | |
481 ////////////////////////////////////////////////////////////////////////////////////////// | |
482 | |
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
|
483 llvm::Value* DtoStructCopy(llvm::Value* dst, llvm::Value* src) |
1 | 484 { |
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
|
485 Logger::cout() << "dst = " << *dst << " src = " << *src << '\n'; |
1 | 486 assert(dst->getType() == src->getType()); |
487 assert(gIR); | |
488 | |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
489 uint64_t n = gTargetData->getTypeSize(dst->getType()->getContainedType(0)); |
1 | 490 //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n)); |
491 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
492 | |
493 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | |
494 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb()); | |
495 | |
496 llvm::Function* fn = LLVM_DeclareMemCpy32(); | |
497 std::vector<llvm::Value*> llargs; | |
498 llargs.resize(4); | |
499 llargs[0] = dstarr; | |
500 llargs[1] = srcarr; | |
501 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
502 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
503 | |
504 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
505 } | |
506 | |
507 ////////////////////////////////////////////////////////////////////////////////////////// | |
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 llvm::Constant* DtoConstStructInitializer(StructInitializer* si) |
1 | 509 { |
510 llvm::StructType* structtype = llvm::cast<llvm::StructType>(si->ad->llvmType); | |
511 size_t n = structtype->getNumElements(); | |
512 | |
513 assert(si->value.dim == si->vars.dim); | |
514 | |
515 std::vector<llvm::Constant*> inits; | |
516 inits.resize(n, NULL); | |
517 for (int i = 0; i < si->value.dim; ++i) | |
518 { | |
519 Initializer* ini = (Initializer*)si->value.data[i]; | |
520 assert(ini); | |
521 | |
522 VarDeclaration* vd = (VarDeclaration*)si->vars.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
|
523 Type* vdtype = DtoDType(vd->type); |
1 | 524 assert(vd); |
525 Logger::println("vars[%d] = %s", i, vd->toChars()); | |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
526 |
73 | 527 llvm::Constant* v = 0; |
1 | 528 |
73 | 529 assert(vd->llvmFieldIndex >= 0); |
530 unsigned idx = vd->llvmFieldIndex; | |
1 | 531 |
532 if (ExpInitializer* ex = ini->isExpInitializer()) | |
533 { | |
40 | 534 v = ex->exp->toConstElem(gIR); |
1 | 535 } |
536 else if (StructInitializer* si = ini->isStructInitializer()) | |
537 { | |
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
|
538 v = DtoConstStructInitializer(si); |
1 | 539 } |
540 else if (ArrayInitializer* ai = ini->isArrayInitializer()) | |
541 { | |
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
|
542 v = DtoConstArrayInitializer(ai); |
1 | 543 } |
544 else if (ini->isVoidInitializer()) | |
545 { | |
546 v = llvm::UndefValue::get(structtype->getElementType(idx)); | |
547 } | |
548 else | |
549 assert(v); | |
550 | |
551 inits[idx] = v; | |
73 | 552 Logger::cout() << "init[" << idx << "] = " << *v << '\n'; |
1 | 553 } |
554 | |
555 // fill out nulls | |
556 assert(si->ad->llvmInitZ); | |
557 if (si->ad->llvmInitZ->isNullValue()) | |
558 { | |
559 for (int i = 0; i < n; ++i) | |
560 { | |
561 if (inits[i] == 0) | |
562 { | |
563 inits[i] = llvm::Constant::getNullValue(structtype->getElementType(i)); | |
564 } | |
565 } | |
566 } | |
567 else | |
568 { | |
569 for (int i = 0; i < n; ++i) | |
570 { | |
571 if (inits[i] == 0) | |
572 { | |
573 inits[i] = si->ad->llvmInitZ->getOperand(i); | |
574 } | |
575 } | |
576 } | |
577 | |
578 return llvm::ConstantStruct::get(structtype, inits); | |
579 } | |
580 | |
581 | |
582 | |
583 ////////////////////////////////////////////////////////////////////////////////////////// | |
584 | |
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
|
585 llvm::Value* DtoNullDelegate(llvm::Value* v) |
1 | 586 { |
587 assert(gIR); | |
588 d_uns64 n = (global.params.is64bit) ? 16 : 8; | |
589 | |
590 llvm::Type* i8p_ty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
591 | |
592 llvm::Value* arr = new llvm::BitCastInst(v,i8p_ty,"tmp",gIR->scopebb()); | |
593 | |
594 llvm::Function* fn = LLVM_DeclareMemSet32(); | |
595 std::vector<llvm::Value*> llargs; | |
596 llargs.resize(4); | |
597 llargs[0] = arr; | |
598 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); | |
599 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
600 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
601 | |
602 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
603 | |
604 return ret; | |
605 } | |
606 | |
607 ////////////////////////////////////////////////////////////////////////////////////////// | |
608 | |
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
|
609 llvm::Value* DtoDelegateCopy(llvm::Value* dst, llvm::Value* src) |
1 | 610 { |
611 assert(dst->getType() == src->getType()); | |
612 assert(gIR); | |
613 | |
614 d_uns64 n = (global.params.is64bit) ? 16 : 8; | |
615 | |
616 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
617 | |
618 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | |
619 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb()); | |
620 | |
621 llvm::Function* fn = LLVM_DeclareMemCpy32(); | |
622 std::vector<llvm::Value*> llargs; | |
623 llargs.resize(4); | |
624 llargs[0] = dstarr; | |
625 llargs[1] = srcarr; | |
626 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
627 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
628 | |
629 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
630 } | |
631 | |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
632 ////////////////////////////////////////////////////////////////////////////////////////// |
1 | 633 |
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
|
634 llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs) |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
635 { |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
636 llvm::ICmpInst::Predicate pred = (op == TOKequal) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; |
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
|
637 llvm::Value* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp"); |
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
|
638 llvm::Value* r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,0,"tmp"),"tmp"); |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
639 llvm::Value* b1 = gIR->ir->CreateICmp(pred,l,r,"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
|
640 l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp"); |
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
|
641 r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,1,"tmp"),"tmp"); |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
642 llvm::Value* b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
643 llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp"); |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
644 if (op == TOKnotequal) |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
645 return gIR->ir->CreateNot(b,"tmp"); |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
646 return b; |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
647 } |
1 | 648 |
649 ////////////////////////////////////////////////////////////////////////////////////////// | |
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 llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc) |
1 | 652 { |
653 switch(prot) | |
654 { | |
655 case PROTprivate: | |
656 return llvm::GlobalValue::InternalLinkage; | |
657 | |
658 case PROTpublic: | |
659 case PROTpackage: | |
660 case PROTprotected: | |
661 case PROTexport: | |
662 return llvm::GlobalValue::ExternalLinkage; | |
663 | |
664 case PROTundefined: | |
665 case PROTnone: | |
666 assert(0 && "Unsupported linkage type"); | |
667 } | |
668 return llvm::GlobalValue::ExternalLinkage; | |
669 | |
670 /* ExternalLinkage = 0, LinkOnceLinkage, WeakLinkage, AppendingLinkage, | |
671 InternalLinkage, DLLImportLinkage, DLLExportLinkage, ExternalWeakLinkage, | |
672 GhostLinkage */ | |
673 } | |
674 | |
675 ////////////////////////////////////////////////////////////////////////////////////////// | |
676 | |
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
|
677 unsigned DtoCallingConv(LINK l) |
1 | 678 { |
679 if (l == LINKc) | |
680 return llvm::CallingConv::C; | |
681 else if (l == LINKd || l == LINKdefault) | |
682 return llvm::CallingConv::Fast; | |
683 else if (l == LINKwindows) | |
684 return llvm::CallingConv::X86_StdCall; | |
685 else | |
686 assert(0 && "Unsupported calling convention"); | |
687 } | |
688 | |
689 ////////////////////////////////////////////////////////////////////////////////////////// | |
690 | |
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
|
691 llvm::Value* DtoPointedType(llvm::Value* ptr, llvm::Value* val) |
1 | 692 { |
693 const llvm::Type* ptrTy = ptr->getType()->getContainedType(0); | |
694 const llvm::Type* valTy = val->getType(); | |
695 // ptr points to val's type | |
696 if (ptrTy == valTy) | |
697 { | |
698 return val; | |
699 } | |
700 // ptr is integer pointer | |
701 else if (ptrTy->isInteger()) | |
702 { | |
703 // val is integer | |
704 assert(valTy->isInteger()); | |
705 const llvm::IntegerType* pt = llvm::cast<const llvm::IntegerType>(ptrTy); | |
706 const llvm::IntegerType* vt = llvm::cast<const llvm::IntegerType>(valTy); | |
707 if (pt->getBitWidth() < vt->getBitWidth()) { | |
708 return new llvm::TruncInst(val, pt, "tmp", gIR->scopebb()); | |
709 } | |
710 else | |
711 assert(0); | |
712 } | |
713 // something else unsupported | |
714 else | |
715 { | |
716 Logger::cout() << *ptrTy << '|' << *valTy << '\n'; | |
717 assert(0); | |
718 } | |
719 return 0; | |
720 } | |
721 | |
722 ////////////////////////////////////////////////////////////////////////////////////////// | |
723 | |
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
|
724 llvm::Value* DtoBoolean(llvm::Value* val) |
1 | 725 { |
726 const llvm::Type* t = val->getType(); | |
727 if (t->isInteger()) | |
728 { | |
729 if (t == llvm::Type::Int1Ty) | |
730 return val; | |
731 else { | |
732 llvm::Value* zero = llvm::ConstantInt::get(t, 0, false); | |
733 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, val, zero, "tmp", gIR->scopebb()); | |
734 } | |
735 } | |
736 else 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
|
737 const llvm::Type* st = DtoSize_t(); |
1 | 738 llvm::Value* ptrasint = new llvm::PtrToIntInst(val,st,"tmp",gIR->scopebb()); |
739 llvm::Value* zero = llvm::ConstantInt::get(st, 0, false); | |
740 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, ptrasint, zero, "tmp", gIR->scopebb()); | |
741 } | |
742 else | |
743 { | |
744 Logger::cout() << *t << '\n'; | |
745 } | |
746 assert(0); | |
747 return 0; | |
748 } | |
749 | |
750 ////////////////////////////////////////////////////////////////////////////////////////// | |
751 | |
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
|
752 const llvm::Type* DtoSize_t() |
1 | 753 { |
754 if (global.params.is64bit) | |
755 return llvm::Type::Int64Ty; | |
756 else | |
757 return llvm::Type::Int32Ty; | |
758 } | |
759 | |
760 ////////////////////////////////////////////////////////////////////////////////////////// | |
761 | |
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
|
762 void DtoMain() |
1 | 763 { |
764 // emit main function llvm style | |
765 // int main(int argc, char**argv, char**env); | |
766 | |
767 assert(gIR != 0); | |
768 IRState& ir = *gIR; | |
769 | |
770 assert(ir.emitMain && ir.mainFunc); | |
771 | |
772 // parameter types | |
773 std::vector<const llvm::Type*> pvec; | |
774 pvec.push_back((const llvm::Type*)llvm::Type::Int32Ty); | |
775 const llvm::Type* chPtrType = (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty); | |
776 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType)); | |
777 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType)); | |
778 const llvm::Type* rettype = (const llvm::Type*)llvm::Type::Int32Ty; | |
779 | |
780 llvm::FunctionType* functype = llvm::FunctionType::get(rettype, pvec, false); | |
781 llvm::Function* func = new llvm::Function(functype,llvm::GlobalValue::ExternalLinkage,"main",ir.module); | |
782 | |
783 llvm::BasicBlock* bb = new llvm::BasicBlock("entry",func); | |
784 | |
785 // call static ctors | |
786 llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_ctors"); | |
787 new llvm::CallInst(fn,"",bb); | |
788 | |
789 // call user main function | |
790 llvm::CallInst* call = new llvm::CallInst(ir.mainFunc,"ret",bb); | |
791 call->setCallingConv(ir.mainFunc->getCallingConv()); | |
792 | |
793 // call static dtors | |
794 fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_dtors"); | |
795 new llvm::CallInst(fn,"",bb); | |
796 | |
797 // return | |
798 new llvm::ReturnInst(call,bb); | |
799 } | |
800 | |
801 ////////////////////////////////////////////////////////////////////////////////////////// | |
802 | |
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
|
803 void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance) |
1 | 804 { |
805 Array* arr = &tc->sym->dtors; | |
806 for (size_t i=0; i<arr->dim; i++) | |
807 { | |
808 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i]; | |
809 assert(fd->llvmValue); | |
810 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb()); | |
811 } | |
812 } | |
813 | |
814 ////////////////////////////////////////////////////////////////////////////////////////// | |
815 | |
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
|
816 void DtoInitClass(TypeClass* tc, llvm::Value* dst) |
1 | 817 { |
818 assert(gIR); | |
819 | |
820 assert(tc->llvmType); | |
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
|
821 uint64_t size_t_size = gTargetData->getTypeSize(DtoSize_t()); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
822 uint64_t n = gTargetData->getTypeSize(tc->llvmType) - size_t_size; |
1 | 823 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
824 // set vtable field |
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
|
825 llvm::Value* vtblvar = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
826 assert(tc->sym->llvmVtbl); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
827 new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb()); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
828 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
829 // copy the static initializer |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
830 if (n > 0) { |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
831 assert(tc->llvmInit); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
832 assert(dst->getType() == tc->llvmInit->getType()); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
833 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
834 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); |
1 | 835 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
836 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->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
|
837 dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb()); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
838 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
839 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->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
|
840 srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb()); |
1 | 841 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
842 llvm::Function* fn = LLVM_DeclareMemCpy32(); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
843 std::vector<llvm::Value*> llargs; |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
844 llargs.resize(4); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
845 llargs[0] = dstarr; |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
846 llargs[1] = srcarr; |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
847 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
848 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
849 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
850 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
851 } |
1 | 852 } |
853 | |
854 ////////////////////////////////////////////////////////////////////////////////////////// | |
855 | |
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
|
856 llvm::Constant* DtoConstInitializer(Type* type, Initializer* init) |
1 | 857 { |
21
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
858 llvm::Constant* _init = 0; // may return zero |
1 | 859 if (!init) |
860 { | |
40 | 861 Logger::println("const default initializer for %s", type->toChars()); |
862 _init = type->defaultInit()->toConstElem(gIR); | |
1 | 863 } |
864 else if (ExpInitializer* ex = init->isExpInitializer()) | |
865 { | |
40 | 866 Logger::println("const expression initializer"); |
867 _init = ex->exp->toConstElem(gIR); | |
1 | 868 } |
869 else if (StructInitializer* si = init->isStructInitializer()) | |
870 { | |
40 | 871 Logger::println("const struct initializer"); |
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
|
872 _init = DtoConstStructInitializer(si); |
1 | 873 } |
874 else if (ArrayInitializer* ai = init->isArrayInitializer()) | |
875 { | |
40 | 876 Logger::println("const array initializer"); |
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
|
877 _init = DtoConstArrayInitializer(ai); |
1 | 878 } |
879 else if (init->isVoidInitializer()) | |
880 { | |
40 | 881 Logger::println("const void initializer"); |
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
|
882 const llvm::Type* ty = DtoType(type); |
1 | 883 _init = llvm::Constant::getNullValue(ty); |
884 } | |
885 else { | |
40 | 886 Logger::println("unsupported const initializer: %s", init->toChars()); |
887 } | |
888 return _init; | |
889 } | |
890 | |
891 ////////////////////////////////////////////////////////////////////////////////////////// | |
892 | |
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
|
893 void DtoInitializer(Initializer* init) |
40 | 894 { |
895 if (ExpInitializer* ex = init->isExpInitializer()) | |
896 { | |
897 Logger::println("expression initializer"); | |
898 elem* e = ex->exp->toElem(gIR); | |
899 delete e; | |
900 } | |
901 else { | |
1 | 902 Logger::println("unsupported initializer: %s", init->toChars()); |
903 } | |
904 } | |
6 | 905 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
906 ////////////////////////////////////////////////////////////////////////////////////////// |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
907 |
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
|
908 llvm::Value* DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb) |
6 | 909 { |
910 std::vector<llvm::Value*> v(2); | |
911 v[0] = i0; | |
912 v[1] = i1; | |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
913 Logger::cout() << "DtoGEP: " << *ptr << '\n'; |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
914 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); |
6 | 915 } |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
916 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
917 ////////////////////////////////////////////////////////////////////////////////////////// |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
918 |
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
|
919 llvm::Value* DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
920 { |
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
921 size_t n = src.size(); |
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
922 std::vector<llvm::Value*> dst(n); |
40 | 923 std::ostream& ostr = Logger::cout(); |
924 ostr << "indices for '" << *ptr << "':"; | |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
925 for (size_t i=0; i<n; ++i) |
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
926 { |
40 | 927 ostr << ' ' << i; |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
928 dst[i] = llvm::ConstantInt::get(llvm::Type::Int32Ty, src[i], false); |
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
929 } |
40 | 930 ostr << '\n'; |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
931 return new llvm::GetElementPtrInst(ptr, dst.begin(), dst.end(), var, bb?bb:gIR->scopebb()); |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
932 } |
9 | 933 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
934 ////////////////////////////////////////////////////////////////////////////////////////// |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
935 |
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
|
936 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i, const std::string& var, llvm::BasicBlock* bb) |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
937 { |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
938 return new llvm::GetElementPtrInst(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb?bb:gIR->scopebb()); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
939 } |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
940 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
941 ////////////////////////////////////////////////////////////////////////////////////////// |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
942 |
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
|
943 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb) |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
944 { |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
945 std::vector<llvm::Value*> v(2); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
946 v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
947 v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false); |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
948 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
949 } |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
950 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
951 ////////////////////////////////////////////////////////////////////////////////////////// |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
952 |
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
|
953 static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl) |
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
|
954 { |
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
|
955 TypeFunction* f = (TypeFunction*)DtoDType(fdecl->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
|
956 const llvm::FunctionType* fty = DtoVaFunctionType(fdecl); |
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
|
957 llvm::Constant* fn = 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
|
958 |
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
|
959 if (fdecl->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
|
960 fn = gIR->module->getOrInsertFunction("llvm.va_start", fty); |
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
|
961 assert(fn); |
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
|
962 } |
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
|
963 else if (fdecl->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
|
964 fn = gIR->module->getOrInsertFunction(fdecl->llvmInternal1, fty); |
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
|
965 assert(fn); |
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
|
966 } |
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
|
967 else |
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
|
968 assert(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
|
969 |
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
|
970 llvm::Function* func = llvm::cast_or_null<llvm::Function>(fn); |
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
|
971 assert(func); |
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
|
972 assert(func->isIntrinsic()); |
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
|
973 fdecl->llvmValue = func; |
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
|
974 return func; |
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
|
975 } |
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
|
976 |
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
|
977 ////////////////////////////////////////////////////////////////////////////////////////// |
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
|
978 |
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
|
979 llvm::Function* DtoDeclareFunction(FuncDeclaration* fdecl) |
9 | 980 { |
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
|
981 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == 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
|
982 return DtoDeclareVaFunction(fdecl); |
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
|
983 } |
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 |
27
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
985 // mangled name |
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
|
986 char* mangled_name; |
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 if (fdecl->llvmInternal == LLVMintrinsic) |
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 mangled_name = fdecl->llvmInternal1; |
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 else |
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 mangled_name = fdecl->mangle(); |
27
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
991 |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
992 // unit test special handling |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
993 if (fdecl->isUnitTestDeclaration()) |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
994 { |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
995 assert(0 && "no unittests yet"); |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
996 /*const llvm::FunctionType* fnty = llvm::FunctionType::get(llvm::Type::VoidTy, std::vector<const llvm::Type*>(), false); |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
997 // make the function |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
998 llvm::Function* func = gIR->module->getFunction(mangled_name); |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
999 if (func == 0) |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1000 func = new llvm::Function(fnty,llvm::GlobalValue::InternalLinkage,mangled_name,gIR->module); |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1001 func->setCallingConv(llvm::CallingConv::Fast); |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1002 fdecl->llvmValue = func; |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1003 return func; |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1004 */ |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1005 } |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1006 |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1007 // regular function |
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
|
1008 TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
1009 assert(f != 0); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
1010 |
9 | 1011 if (fdecl->llvmValue != 0) { |
18 | 1012 if (!llvm::isa<llvm::Function>(fdecl->llvmValue)) |
1013 { | |
1014 Logger::cout() << *fdecl->llvmValue << '\n'; | |
1015 assert(0); | |
1016 } | |
9 | 1017 return llvm::cast<llvm::Function>(fdecl->llvmValue); |
1018 } | |
1019 | |
18 | 1020 Logger::print("FuncDeclaration::toObjFile(%s): %s\n", fdecl->needThis()?"this":"static",fdecl->toChars()); |
9 | 1021 LOG_SCOPE; |
1022 | |
1023 if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) { | |
1024 error("intrinsics cannot have function bodies"); | |
1025 fatal(); | |
1026 } | |
1027 | |
1028 // construct function | |
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
|
1029 const llvm::FunctionType* functype = (f->llvmType == 0) ? DtoFunctionType(fdecl) : llvm::cast<llvm::FunctionType>(f->llvmType); |
9 | 1030 |
1031 // make the function | |
1032 llvm::Function* func = gIR->module->getFunction(mangled_name); | |
1033 if (func == 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
|
1034 func = new llvm::Function(functype,DtoLinkage(fdecl->protection, fdecl->storage_class),mangled_name,gIR->module); |
9 | 1035 } |
1036 | |
1037 if (fdecl->llvmInternal != LLVMintrinsic) | |
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
|
1038 func->setCallingConv(DtoCallingConv(f->linkage)); |
9 | 1039 |
1040 fdecl->llvmValue = func; | |
1041 f->llvmType = functype; | |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
1042 assert(llvm::isa<llvm::FunctionType>(f->llvmType)); |
9 | 1043 |
1044 if (fdecl->isMain()) { | |
1045 gIR->mainFunc = func; | |
1046 } | |
1047 | |
1048 // name parameters | |
1049 llvm::Function::arg_iterator iarg = func->arg_begin(); | |
1050 int k = 0; | |
1051 if (f->llvmRetInPtr) { | |
1052 iarg->setName("retval"); | |
1053 f->llvmRetArg = iarg; | |
1054 ++iarg; | |
1055 } | |
1056 if (f->llvmUsesThis) { | |
1057 iarg->setName("this"); | |
1058 ++iarg; | |
1059 } | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1060 int varargs = -1; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1061 if (f->linkage == LINKd && f->varargs == 1) |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1062 varargs = 0; |
9 | 1063 for (; iarg != func->arg_end(); ++iarg) |
1064 { | |
1065 Argument* arg = Argument::getNth(f->parameters, k++); | |
1066 //arg->llvmValue = iarg; | |
1067 //printf("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident); | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1068 if (arg && arg->ident != 0) { |
9 | 1069 if (arg->vardecl) { |
1070 arg->vardecl->llvmValue = iarg; | |
1071 } | |
1072 iarg->setName(arg->ident->toChars()); | |
1073 } | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1074 else if (!arg && varargs >= 0) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1075 if (varargs == 0) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1076 iarg->setName("_arguments"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1077 fdecl->llvmArguments = iarg; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1078 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1079 else if (varargs == 1) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1080 iarg->setName("_argptr"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1081 fdecl->llvmArgPtr = iarg; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1082 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1083 else |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1084 assert(0); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1085 varargs++; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1086 } |
9 | 1087 else { |
1088 iarg->setName("unnamed"); | |
1089 } | |
1090 } | |
1091 | |
1092 return func; | |
1093 } | |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1094 |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1095 ////////////////////////////////////////////////////////////////////////////////////////// |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1096 |
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
|
1097 llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty) |
34 | 1098 { |
1099 /*size_t sz = gTargetData->getTypeSize(ty); | |
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
|
1100 llvm::ConstantInt* n = llvm::ConstantInt::get(DtoSize_t(), sz, false); |
34 | 1101 if (ptr == 0) { |
1102 llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
1103 ptr = llvm::ConstantPointerNull::get(i8pty); | |
1104 } | |
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
|
1105 return DtoRealloc(ptr, n);*/ |
34 | 1106 return NULL; |
1107 } | |
1108 | |
1109 ////////////////////////////////////////////////////////////////////////////////////////// | |
1110 | |
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
|
1111 llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* n) |
34 | 1112 { |
1113 assert(ptr); | |
1114 assert(n); | |
1115 | |
1116 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_realloc"); | |
1117 assert(fn); | |
1118 | |
1119 llvm::Value* newptr = ptr; | |
1120 | |
1121 llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
1122 if (ptr->getType() != i8pty) { | |
1123 newptr = new llvm::BitCastInst(ptr,i8pty,"tmp",gIR->scopebb()); | |
1124 } | |
1125 | |
1126 std::vector<llvm::Value*> args; | |
1127 args.push_back(newptr); | |
1128 args.push_back(n); | |
1129 llvm::Value* ret = new llvm::CallInst(fn, args.begin(), args.end(), "tmprealloc", gIR->scopebb()); | |
1130 | |
1131 return ret->getType() == ptr->getType() ? ret : new llvm::BitCastInst(ret,ptr->getType(),"tmp",gIR->scopebb()); | |
1132 } | |
1133 | |
1134 ////////////////////////////////////////////////////////////////////////////////////////// | |
1135 | |
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
|
1136 void DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg) |
34 | 1137 { |
1138 assert(loc); | |
1139 std::vector<llvm::Value*> llargs; | |
1140 llargs.resize(3); | |
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
|
1141 llargs[0] = cond ? DtoBoolean(cond) : llvm::ConstantInt::getFalse(); |
34 | 1142 llargs[1] = loc; |
1143 llargs[2] = msg ? msg : llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); | |
1144 | |
1145 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assert"); | |
1146 assert(fn); | |
1147 llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
1148 call->setCallingConv(llvm::CallingConv::C); | |
1149 } | |
1150 | |
40 | 1151 ////////////////////////////////////////////////////////////////////////////////////////// |
34 | 1152 |
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
|
1153 llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expression* argexp) |
40 | 1154 { |
1155 llvm::Value* retval = 0; | |
1156 | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1157 bool haslvals = !gIR->exps.empty(); |
40 | 1158 if (haslvals) |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1159 gIR->exps.push_back(IRExp(NULL,NULL,NULL)); |
40 | 1160 |
1161 elem* arg = argexp->toElem(gIR); | |
1162 | |
1163 if (haslvals) | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1164 gIR->exps.pop_back(); |
40 | 1165 |
1166 if (arg->inplace) { | |
1167 assert(arg->mem != 0); | |
1168 retval = arg->mem; | |
1169 delete arg; | |
1170 return retval; | |
1171 } | |
1172 | |
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 Type* realtype = DtoDType(argexp->type); |
40 | 1174 TY argty = realtype->ty; |
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
|
1175 if (DtoIsPassedByRef(realtype)) { |
40 | 1176 if (!fnarg || !fnarg->llvmCopy) { |
1177 retval = arg->getValue(); | |
1178 assert(retval != 0); | |
1179 } | |
1180 else { | |
1181 llvm::Value* allocaInst = 0; | |
1182 llvm::BasicBlock* entryblock = &gIR->topfunc()->front(); | |
1183 //const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(arg->mem->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
|
1184 const llvm::Type* realtypell = DtoType(realtype); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1185 const llvm::PointerType* pty = llvm::PointerType::get(realtypell); |
40 | 1186 if (argty == Tstruct) { |
1187 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->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
|
1188 DtoStructCopy(allocaInst,arg->mem); |
40 | 1189 } |
1190 else if (argty == Tdelegate) { | |
1191 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->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
|
1192 DtoDelegateCopy(allocaInst,arg->mem); |
40 | 1193 } |
1194 else if (argty == Tarray) { | |
1195 if (arg->type == elem::SLICE) { | |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1196 allocaInst = new llvm::AllocaInst(realtypell, "tmpparam", gIR->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
|
1197 DtoSetArray(allocaInst, arg->arg, arg->mem); |
40 | 1198 } |
83
339422268de1
[svn r87] Fixed some memory bloat when passing string literals as char[] params (double temporary before)
lindquist
parents:
82
diff
changeset
|
1199 else if (arg->temp) { |
339422268de1
[svn r87] Fixed some memory bloat when passing string literals as char[] params (double temporary before)
lindquist
parents:
82
diff
changeset
|
1200 allocaInst = arg->mem; |
339422268de1
[svn r87] Fixed some memory bloat when passing string literals as char[] params (double temporary before)
lindquist
parents:
82
diff
changeset
|
1201 } |
40 | 1202 else { |
1203 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->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
|
1204 DtoArrayAssign(allocaInst,arg->mem); |
40 | 1205 } |
1206 } | |
1207 else | |
1208 assert(0); | |
1209 | |
1210 retval = allocaInst; | |
1211 } | |
1212 } | |
1213 else if (!fnarg || fnarg->llvmCopy) { | |
1214 Logger::println("regular arg"); | |
1215 assert(arg->type != elem::SLICE); | |
1216 if (arg->mem) Logger::cout() << "mem = " << *arg->mem << '\n'; | |
1217 if (arg->val) Logger::cout() << "val = " << *arg->val << '\n'; | |
1218 if (arg->arg) Logger::cout() << "arg = " << *arg->arg << '\n'; | |
1219 retval = arg->arg ? arg->arg : arg->field ? arg->mem : arg->getValue(); | |
1220 } | |
1221 else { | |
1222 Logger::println("as ptr arg"); | |
1223 retval = arg->mem ? arg->mem : arg->val; | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1224 if (paramtype && retval->getType() != paramtype) |
40 | 1225 { |
1226 assert(retval->getType() == paramtype->getContainedType(0)); | |
1227 new llvm::StoreInst(retval, arg->mem, gIR->scopebb()); | |
1228 retval = arg->mem; | |
1229 } | |
1230 } | |
1231 | |
78
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1232 if (fnarg && paramtype && retval->getType() != paramtype) { |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1233 // this is unfortunately needed with the way SymOffExp is overused |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1234 // and static arrays can end up being a pointer to their element type |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1235 if (arg->field) { |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1236 retval = gIR->ir->CreateBitCast(retval, paramtype, "tmp"); |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1237 } |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1238 else { |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1239 Logger::cout() << "got '" << *retval->getType() << "' expected '" << *paramtype << "'\n"; |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1240 assert(0 && "parameter type that was actually passed is invalid"); |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1241 } |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1242 } |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1243 |
40 | 1244 delete arg; |
1245 | |
1246 return retval; | |
1247 } | |
34 | 1248 |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1249 ////////////////////////////////////////////////////////////////////////////////////////// |
34 | 1250 |
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
|
1251 llvm::Value* DtoNestedVariable(VarDeclaration* vd) |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1252 { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1253 FuncDeclaration* fd = vd->toParent()->isFuncDeclaration(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1254 assert(fd != NULL); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1255 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1256 IRFunction* fcur = &gIR->func(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1257 FuncDeclaration* f = fcur->decl; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1258 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1259 // on this stack |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1260 if (fd == f) { |
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
|
1261 llvm::Value* v = DtoGEPi(vd->llvmValue,0,unsigned(vd->llvmNestedIndex),"tmp"); |
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
|
1262 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) { |
73 | 1263 Logger::cout() << "1267 loading: " << *v << '\n'; |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1264 v = gIR->ir->CreateLoad(v,"tmp"); |
73 | 1265 } |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1266 return v; |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1267 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1268 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1269 // on a caller stack |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1270 llvm::Value* ptr = f->llvmThisVar; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1271 assert(ptr); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1272 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1273 f = f->toParent()->isFuncDeclaration(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1274 assert(f); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1275 assert(f->llvmNested); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1276 const llvm::Type* nesttype = f->llvmNested->getType(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1277 assert(nesttype); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1278 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1279 ptr = gIR->ir->CreateBitCast(ptr, nesttype, "tmp"); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1280 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1281 Logger::cout() << "nested var reference:" << '\n' << *ptr << *nesttype << '\n'; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1282 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1283 while (f) { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1284 if (fd == f) { |
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
|
1285 llvm::Value* v = DtoGEPi(ptr,0,vd->llvmNestedIndex,"tmp"); |
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
|
1286 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) { |
73 | 1287 Logger::cout() << "1291 loading: " << *v << '\n'; |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1288 v = gIR->ir->CreateLoad(v,"tmp"); |
73 | 1289 } |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1290 return v; |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1291 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1292 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
|
1293 ptr = DtoGEPi(ptr,0,0,"tmp"); |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1294 ptr = gIR->ir->CreateLoad(ptr,"tmp"); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1295 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1296 f = f->toParent()->isFuncDeclaration(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1297 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1298 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1299 assert(0 && "nested var not found"); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1300 return NULL; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1301 } |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1302 |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1303 ////////////////////////////////////////////////////////////////////////////////////////// |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1304 |
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
|
1305 void DtoAssign(Type* t, llvm::Value* lhs, llvm::Value* rhs) |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1306 { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1307 Logger::cout() << "assignment:" << '\n' << *lhs << *rhs << '\n'; |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1308 |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1309 if (t->ty == Tstruct) { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1310 assert(lhs->getType() == rhs->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
|
1311 DtoStructCopy(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1312 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1313 else if (t->ty == Tarray) { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1314 assert(lhs->getType() == rhs->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
|
1315 DtoArrayAssign(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1316 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1317 else if (t->ty == Tsarray) { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1318 assert(lhs->getType() == rhs->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
|
1319 DtoStaticArrayCopy(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1320 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1321 else if (t->ty == Tdelegate) { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1322 assert(lhs->getType() == rhs->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
|
1323 DtoDelegateCopy(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1324 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1325 else { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1326 assert(lhs->getType()->getContainedType(0) == rhs->getType()); |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1327 gIR->ir->CreateStore(rhs, lhs); |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1328 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1329 } |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1330 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1331 ////////////////////////////////////////////////////////////////////////////////////////// |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1332 |
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
|
1333 llvm::ConstantInt* DtoConstSize_t(size_t i) |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1334 { |
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
|
1335 return llvm::ConstantInt::get(DtoSize_t(), i, false); |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1336 } |
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
|
1337 llvm::ConstantInt* DtoConstUint(unsigned i) |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1338 { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1339 return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1340 } |
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
|
1341 llvm::ConstantInt* DtoConstInt(int i) |
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
|
1342 { |
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
|
1343 return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, 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
|
1344 } |
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
|
1345 llvm::Constant* DtoConstBool(bool b) |
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
|
1346 { |
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 return llvm::ConstantInt::get(llvm::Type::Int1Ty, b, 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 } |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1349 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1350 ////////////////////////////////////////////////////////////////////////////////////////// |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1351 |
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
|
1352 llvm::Constant* DtoConstString(const char* str) |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1353 { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1354 std::string s(str); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1355 llvm::Constant* init = llvm::ConstantArray::get(s, true); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1356 llvm::GlobalVariable* gvar = new llvm::GlobalVariable( |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1357 init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module); |
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
|
1358 llvm::Constant* idxs[2] = { DtoConstUint(0), DtoConstUint(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
|
1359 return DtoConstSlice( |
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
|
1360 DtoConstSize_t(s.length()), |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1361 llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2) |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1362 ); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1363 } |
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
|
1364 llvm::Constant* DtoConstStringPtr(const char* str, const char* section) |
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
|
1365 { |
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
|
1366 std::string s(str); |
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
|
1367 llvm::Constant* init = llvm::ConstantArray::get(s, true); |
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
|
1368 llvm::GlobalVariable* gvar = new llvm::GlobalVariable( |
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
|
1369 init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module); |
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
|
1370 if (section) gvar->setSection(section); |
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
|
1371 llvm::Constant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; |
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
|
1372 return llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); |
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
|
1373 } |
58
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1374 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1375 ////////////////////////////////////////////////////////////////////////////////////////// |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1376 |
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
|
1377 void DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes) |
58
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1378 { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1379 assert(dst->getType() == src->getType()); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1380 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1381 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1382 llvm::Value *dstarr, *srcarr; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1383 if (dst->getType() == arrty) |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1384 { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1385 dstarr = dst; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1386 srcarr = src; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1387 } |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1388 else |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1389 { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1390 dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1391 srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb()); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1392 } |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1393 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1394 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1395 std::vector<llvm::Value*> llargs; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1396 llargs.resize(4); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1397 llargs[0] = dstarr; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1398 llargs[1] = srcarr; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1399 llargs[2] = nbytes; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1400 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1401 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1402 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1403 } |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1404 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1405 ////////////////////////////////////////////////////////////////////////////////////////// |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1406 |
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
|
1407 llvm::Value* DtoIndexStruct(llvm::Value* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs) |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1408 { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1409 Logger::println("checking for offset %u type %s:", os, t->toChars()); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1410 LOG_SCOPE; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1411 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1412 if (idxs.empty()) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1413 idxs.push_back(0); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1414 |
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
|
1415 const llvm::Type* llt = llvm::PointerType::get(DtoType(t)); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1416 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1417 for (unsigned i=0; i<sd->fields.dim; ++i) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1418 VarDeclaration* vd = (VarDeclaration*)sd->fields.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
|
1419 Type* vdtype = DtoDType(vd->type); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1420 Logger::println("found %u type %s", vd->offset, vdtype->toChars()); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1421 assert(vd->llvmFieldIndex >= 0); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1422 if (os == vd->offset && vdtype == t) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1423 idxs.push_back(vd->llvmFieldIndex); |
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
|
1424 ptr = DtoGEP(ptr, idxs, "tmp"); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1425 if (ptr->getType() != llt) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1426 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1427 if (vd->llvmFieldIndexOffset) |
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
|
1428 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1429 return ptr; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1430 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1431 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1432 TypeStruct* ts = (TypeStruct*)vdtype; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1433 StructDeclaration* ssd = ts->sym; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1434 idxs.push_back(vd->llvmFieldIndex); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1435 if (vd->llvmFieldIndexOffset) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1436 Logger::println("has union field offset"); |
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
|
1437 ptr = DtoGEP(ptr, idxs, "tmp"); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1438 if (ptr->getType() != llt) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1439 ptr = gIR->ir->CreateBitCast(ptr, llt, "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
|
1440 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1441 std::vector<unsigned> 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
|
1442 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1443 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1444 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
|
1445 const llvm::Type* sty = llvm::PointerType::get(DtoType(vd->type)); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1446 if (ptr->getType() != sty) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1447 ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp"); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1448 std::vector<unsigned> 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
|
1449 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1450 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1451 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
|
1452 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, idxs); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1453 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1454 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1455 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1456 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1457 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1458 size_t llt_sz = gTargetData->getTypeSize(llt->getContainedType(0)); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1459 assert(os % llt_sz == 0); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1460 ptr = gIR->ir->CreateBitCast(ptr, llt, "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
|
1461 return new llvm::GetElementPtrInst(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb()); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1462 } |