Mercurial > projects > ldc
annotate gen/tollvm.c @ 82:d8dd47ef3973 trunk
[svn r86] Changed the way arguments are given storage. It is now detected if they will need it during semantic passes.
Initial support for debug information. Very limited, but MUCH better than nothing :)
author | lindquist |
---|---|
date | Fri, 02 Nov 2007 01:17:26 +0100 |
parents | 3587401b6eeb |
children | 339422268de1 |
rev | line source |
---|---|
1 | 1 #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 } |
1199 else { | |
1200 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
|
1201 DtoArrayAssign(allocaInst,arg->mem); |
40 | 1202 } |
1203 } | |
1204 else | |
1205 assert(0); | |
1206 | |
1207 assert(allocaInst != 0); | |
1208 retval = allocaInst; | |
1209 } | |
1210 } | |
1211 else if (!fnarg || fnarg->llvmCopy) { | |
1212 Logger::println("regular arg"); | |
1213 assert(arg->type != elem::SLICE); | |
1214 if (arg->mem) Logger::cout() << "mem = " << *arg->mem << '\n'; | |
1215 if (arg->val) Logger::cout() << "val = " << *arg->val << '\n'; | |
1216 if (arg->arg) Logger::cout() << "arg = " << *arg->arg << '\n'; | |
1217 retval = arg->arg ? arg->arg : arg->field ? arg->mem : arg->getValue(); | |
1218 } | |
1219 else { | |
1220 Logger::println("as ptr arg"); | |
1221 retval = arg->mem ? arg->mem : arg->val; | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1222 if (paramtype && retval->getType() != paramtype) |
40 | 1223 { |
1224 assert(retval->getType() == paramtype->getContainedType(0)); | |
1225 new llvm::StoreInst(retval, arg->mem, gIR->scopebb()); | |
1226 retval = arg->mem; | |
1227 } | |
1228 } | |
1229 | |
78
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1230 if (fnarg && paramtype && retval->getType() != paramtype) { |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1231 // 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
|
1232 // 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
|
1233 if (arg->field) { |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1234 retval = gIR->ir->CreateBitCast(retval, paramtype, "tmp"); |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1235 } |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1236 else { |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1237 Logger::cout() << "got '" << *retval->getType() << "' expected '" << *paramtype << "'\n"; |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1238 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
|
1239 } |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1240 } |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1241 |
40 | 1242 delete arg; |
1243 | |
1244 return retval; | |
1245 } | |
34 | 1246 |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1247 ////////////////////////////////////////////////////////////////////////////////////////// |
34 | 1248 |
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
|
1249 llvm::Value* DtoNestedVariable(VarDeclaration* vd) |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1250 { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1251 FuncDeclaration* fd = vd->toParent()->isFuncDeclaration(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1252 assert(fd != NULL); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1253 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1254 IRFunction* fcur = &gIR->func(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1255 FuncDeclaration* f = fcur->decl; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1256 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1257 // on this stack |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1258 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
|
1259 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
|
1260 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) { |
73 | 1261 Logger::cout() << "1267 loading: " << *v << '\n'; |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1262 v = gIR->ir->CreateLoad(v,"tmp"); |
73 | 1263 } |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1264 return v; |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1265 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1266 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1267 // on a caller stack |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1268 llvm::Value* ptr = f->llvmThisVar; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1269 assert(ptr); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1270 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1271 f = f->toParent()->isFuncDeclaration(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1272 assert(f); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1273 assert(f->llvmNested); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1274 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
|
1275 assert(nesttype); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1276 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1277 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
|
1278 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1279 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
|
1280 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1281 while (f) { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1282 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
|
1283 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
|
1284 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) { |
73 | 1285 Logger::cout() << "1291 loading: " << *v << '\n'; |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1286 v = gIR->ir->CreateLoad(v,"tmp"); |
73 | 1287 } |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1288 return v; |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1289 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1290 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
|
1291 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
|
1292 ptr = gIR->ir->CreateLoad(ptr,"tmp"); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1293 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1294 f = f->toParent()->isFuncDeclaration(); |
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 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1297 assert(0 && "nested var not found"); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1298 return NULL; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1299 } |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1300 |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1301 ////////////////////////////////////////////////////////////////////////////////////////// |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1302 |
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
|
1303 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
|
1304 { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1305 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
|
1306 |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1307 if (t->ty == Tstruct) { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1308 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
|
1309 DtoStructCopy(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1310 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1311 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
|
1312 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
|
1313 DtoArrayAssign(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1314 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1315 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
|
1316 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
|
1317 DtoStaticArrayCopy(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1318 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1319 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
|
1320 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
|
1321 DtoDelegateCopy(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1322 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1323 else { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1324 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
|
1325 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
|
1326 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1327 } |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1328 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1329 ////////////////////////////////////////////////////////////////////////////////////////// |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1330 |
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
|
1331 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
|
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 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
|
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 llvm::ConstantInt* DtoConstUint(unsigned i) |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1336 { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1337 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
|
1338 } |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1339 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
|
1340 { |
3587401b6eeb
[svn r85] Fixed: if a return statement 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 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
|
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 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
|
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 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
|
1346 } |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1347 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1348 ////////////////////////////////////////////////////////////////////////////////////////// |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1349 |
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
|
1350 llvm::Constant* DtoConstString(const char* str) |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1351 { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1352 std::string s(str); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1353 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
|
1354 llvm::GlobalVariable* gvar = new llvm::GlobalVariable( |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1355 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
|
1356 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
|
1357 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
|
1358 DtoConstSize_t(s.length()), |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1359 llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2) |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1360 ); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1361 } |
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
|
1362 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
|
1363 { |
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 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
|
1365 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
|
1366 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
|
1367 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
|
1368 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
|
1369 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
|
1370 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
|
1371 } |
58
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1372 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1373 ////////////////////////////////////////////////////////////////////////////////////////// |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1374 |
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
|
1375 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
|
1376 { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1377 assert(dst->getType() == src->getType()); |
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 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
|
1380 llvm::Value *dstarr, *srcarr; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1381 if (dst->getType() == arrty) |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1382 { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1383 dstarr = dst; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1384 srcarr = src; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1385 } |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1386 else |
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 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
|
1389 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
|
1390 } |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1391 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1392 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
|
1393 std::vector<llvm::Value*> llargs; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1394 llargs.resize(4); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1395 llargs[0] = dstarr; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1396 llargs[1] = srcarr; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1397 llargs[2] = nbytes; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1398 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
|
1399 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1400 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
|
1401 } |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1402 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1403 ////////////////////////////////////////////////////////////////////////////////////////// |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1404 |
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
|
1405 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
|
1406 { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1407 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
|
1408 LOG_SCOPE; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1409 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1410 if (idxs.empty()) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1411 idxs.push_back(0); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1412 |
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
|
1413 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
|
1414 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1415 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
|
1416 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
|
1417 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
|
1418 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
|
1419 assert(vd->llvmFieldIndex >= 0); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1420 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
|
1421 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
|
1422 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
|
1423 if (ptr->getType() != llt) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1424 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
|
1425 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
|
1426 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
|
1427 return ptr; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1428 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1429 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
|
1430 TypeStruct* ts = (TypeStruct*)vdtype; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1431 StructDeclaration* ssd = ts->sym; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1432 idxs.push_back(vd->llvmFieldIndex); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1433 if (vd->llvmFieldIndexOffset) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1434 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
|
1435 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
|
1436 if (ptr->getType() != llt) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1437 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
|
1438 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
|
1439 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
|
1440 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
|
1441 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1442 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
|
1443 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
|
1444 if (ptr->getType() != sty) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1445 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
|
1446 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
|
1447 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
|
1448 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1449 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
|
1450 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
|
1451 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1452 } |
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 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
|
1457 assert(os % llt_sz == 0); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1458 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
|
1459 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
|
1460 } |