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