Mercurial > projects > ldc
annotate gen/functions.cpp @ 240:0db62b770a49 trunk
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
Fixed: most runtime calls did not get correct param attrs.
author | lindquist |
---|---|
date | Mon, 09 Jun 2008 00:01:10 +0200 |
parents | 9760f54af0b7 |
children | 53568c37cfa7 |
rev | line source |
---|---|
100 | 1 #include "gen/llvm.h" |
2 | |
3 #include "mtype.h" | |
4 #include "aggregate.h" | |
5 #include "init.h" | |
6 #include "declaration.h" | |
7 #include "template.h" | |
8 #include "module.h" | |
9 #include "statement.h" | |
10 | |
11 #include "gen/irstate.h" | |
12 #include "gen/tollvm.h" | |
13 #include "gen/runtime.h" | |
14 #include "gen/arrays.h" | |
15 #include "gen/logger.h" | |
16 #include "gen/functions.h" | |
17 #include "gen/todebug.h" | |
18 #include "gen/classes.h" | |
131 | 19 #include "gen/dvalue.h" |
100 | 20 |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
21 const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bool ismain) |
100 | 22 { |
23 TypeFunction* f = (TypeFunction*)type; | |
24 assert(f != 0); | |
25 | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
26 if (type->ir.type != NULL) { |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
27 return llvm::cast<llvm::FunctionType>(type->ir.type->get()); |
100 | 28 } |
29 | |
30 bool typesafeVararg = false; | |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
31 bool arrayVararg = false; |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
32 if (f->linkage == LINKd) |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
33 { |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
34 if (f->varargs == 1) |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
35 typesafeVararg = true; |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
36 else if (f->varargs == 2) |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
37 arrayVararg = true; |
100 | 38 } |
39 | |
40 // return value type | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
41 const LLType* rettype; |
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
42 const LLType* actualRettype; |
100 | 43 Type* rt = f->next; |
44 bool retinptr = false; | |
45 bool usesthis = false; | |
46 | |
234
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
47 // parameter types |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
48 std::vector<const LLType*> paramvec; |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
49 |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
50 if (ismain) |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
51 { |
100 | 52 rettype = llvm::Type::Int32Ty; |
53 actualRettype = rettype; | |
234
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
54 if (Argument::dim(f->parameters) == 0) |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
55 { |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
56 const LLType* arrTy = DtoArrayType(LLType::Int8Ty); |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
57 const LLType* arrArrTy = DtoArrayType(arrTy); |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
58 paramvec.push_back(getPtrToType(arrArrTy)); |
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
59 } |
100 | 60 } |
234
9760f54af0b7
[svn r250] Fixed the warning about dropping arguments to _Dmain when optimizing.
lindquist
parents:
225
diff
changeset
|
61 else{ |
100 | 62 assert(rt); |
109
5ab8e92611f9
[svn r113] Added initial support for associative arrays (AAs).
lindquist
parents:
108
diff
changeset
|
63 Type* rtfin = DtoDType(rt); |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
64 if (DtoIsReturnedInArg(rt)) { |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
65 rettype = getPtrToType(DtoType(rt)); |
100 | 66 actualRettype = llvm::Type::VoidTy; |
67 f->llvmRetInPtr = retinptr = true; | |
68 } | |
69 else { | |
70 rettype = DtoType(rt); | |
71 actualRettype = rettype; | |
72 } | |
73 } | |
74 | |
75 if (retinptr) { | |
123
7f9a0a58394b
[svn r127] Updated the lphobos build scripts a little. Created a new rebuild profile.
lindquist
parents:
121
diff
changeset
|
76 //Logger::cout() << "returning through pointer parameter: " << *rettype << '\n'; |
100 | 77 paramvec.push_back(rettype); |
78 } | |
79 | |
80 if (thistype) { | |
81 paramvec.push_back(thistype); | |
82 usesthis = true; | |
83 } | |
84 | |
85 if (typesafeVararg) { | |
86 ClassDeclaration* ti = Type::typeinfo; | |
87 ti->toObjFile(); | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
88 DtoForceConstInitDsymbol(ti); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
89 assert(ti->ir.irStruct->constInit); |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
90 std::vector<const LLType*> types; |
100 | 91 types.push_back(DtoSize_t()); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
92 types.push_back(getPtrToType(getPtrToType(ti->ir.irStruct->constInit->getType()))); |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
93 const LLType* t1 = llvm::StructType::get(types); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
94 paramvec.push_back(getPtrToType(t1)); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
95 paramvec.push_back(getPtrToType(llvm::Type::Int8Ty)); |
100 | 96 } |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
97 else if (arrayVararg) |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
98 { |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
99 // do nothing? |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
100 } |
100 | 101 |
102 size_t n = Argument::dim(f->parameters); | |
103 | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
104 int nbyval = 0; |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
105 |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
106 llvm::PAListPtr palist; |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
107 |
100 | 108 for (int i=0; i < n; ++i) { |
109 Argument* arg = Argument::getNth(f->parameters, i); | |
110 // ensure scalar | |
111 Type* argT = DtoDType(arg->type); | |
112 assert(argT); | |
113 | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
114 bool refOrOut = ((arg->storageClass & STCref) || (arg->storageClass & STCout)); |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
115 |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
116 const LLType* at = DtoType(argT); |
100 | 117 if (isaStruct(at)) { |
118 Logger::println("struct param"); | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
119 paramvec.push_back(getPtrToType(at)); |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
120 arg->llvmByVal = !refOrOut; |
100 | 121 } |
122 else if (isaArray(at)) { | |
123 Logger::println("sarray param"); | |
124 assert(argT->ty == Tsarray); | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
125 //paramvec.push_back(getPtrToType(at->getContainedType(0))); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
126 paramvec.push_back(getPtrToType(at)); |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
127 arg->llvmByVal = !refOrOut; |
100 | 128 } |
129 else if (llvm::isa<llvm::OpaqueType>(at)) { | |
130 Logger::println("opaque param"); | |
131 assert(argT->ty == Tstruct || argT->ty == Tclass); | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
132 paramvec.push_back(getPtrToType(at)); |
100 | 133 } |
134 else { | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
135 if (refOrOut) { |
131 | 136 Logger::println("by ref param"); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
137 at = getPtrToType(at); |
100 | 138 } |
139 else { | |
140 Logger::println("in param"); | |
141 } | |
142 paramvec.push_back(at); | |
143 } | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
144 |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
145 if (arg->llvmByVal) |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
146 nbyval++; |
100 | 147 } |
148 | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
149 //warning("set %d byval args for type: %s", nbyval, f->toChars()); |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
150 |
100 | 151 // construct function type |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
152 bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; |
100 | 153 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); |
154 | |
155 f->llvmRetInPtr = retinptr; | |
156 f->llvmUsesThis = usesthis; | |
157 | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
158 f->ir.type = new llvm::PATypeHolder(functype); |
100 | 159 |
160 return functype; | |
161 } | |
162 | |
163 ////////////////////////////////////////////////////////////////////////////////////////// | |
164 | |
165 static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl) | |
166 { | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
167 // type has already been resolved |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
168 if (fdecl->type->ir.type != 0) { |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
169 return llvm::cast<llvm::FunctionType>(fdecl->type->ir.type->get()); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
170 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
171 |
100 | 172 TypeFunction* f = (TypeFunction*)fdecl->type; |
173 assert(f != 0); | |
174 | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
175 const llvm::PointerType* i8pty = getPtrToType(llvm::Type::Int8Ty); |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
176 std::vector<const LLType*> args; |
100 | 177 |
178 if (fdecl->llvmInternal == LLVMva_start) { | |
179 args.push_back(i8pty); | |
180 } | |
181 else if (fdecl->llvmInternal == LLVMva_intrinsic) { | |
182 size_t n = Argument::dim(f->parameters); | |
183 for (size_t i=0; i<n; ++i) { | |
184 args.push_back(i8pty); | |
185 } | |
186 } | |
187 else | |
188 assert(0); | |
189 | |
190 const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::VoidTy, args, false); | |
191 | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
192 f->ir.type = new llvm::PATypeHolder(fty); |
100 | 193 |
194 return fty; | |
195 } | |
196 | |
197 ////////////////////////////////////////////////////////////////////////////////////////// | |
198 | |
199 const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl) | |
200 { | |
201 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) { | |
202 return DtoVaFunctionType(fdecl); | |
203 } | |
204 | |
121
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
205 // unittest has null type, just build it manually |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
206 /*if (fdecl->isUnitTestDeclaration()) { |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
207 std::vector<const LLType*> args; |
121
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
208 return llvm::FunctionType::get(llvm::Type::VoidTy, args, false); |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
209 }*/ |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
210 |
100 | 211 // type has already been resolved |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
212 if (fdecl->type->ir.type != 0) { |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
213 return llvm::cast<llvm::FunctionType>(fdecl->type->ir.type->get()); |
100 | 214 } |
215 | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
216 const LLType* thisty = NULL; |
100 | 217 if (fdecl->needThis()) { |
132 | 218 if (AggregateDeclaration* ad = fdecl->isMember2()) { |
219 Logger::println("isMember = this is: %s", ad->type->toChars()); | |
100 | 220 thisty = DtoType(ad->type); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
109
diff
changeset
|
221 //Logger::cout() << "this llvm type: " << *thisty << '\n'; |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
222 if (isaStruct(thisty) || (!gIR->structs.empty() && thisty == gIR->topstruct()->recty.get())) |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
223 thisty = getPtrToType(thisty); |
100 | 224 } |
132 | 225 else { |
226 Logger::println("chars: %s type: %s kind: %s", fdecl->toChars(), fdecl->type->toChars(), fdecl->kind()); | |
227 assert(0); | |
228 } | |
100 | 229 } |
230 else if (fdecl->isNested()) { | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
231 thisty = getPtrToType(llvm::Type::Int8Ty); |
100 | 232 } |
233 | |
234 const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, fdecl->isMain()); | |
235 | |
236 return functype; | |
237 } | |
238 | |
239 ////////////////////////////////////////////////////////////////////////////////////////// | |
240 | |
241 static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl) | |
242 { | |
243 TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type); | |
244 const llvm::FunctionType* fty = DtoVaFunctionType(fdecl); | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
245 LLConstant* fn = 0; |
100 | 246 |
247 if (fdecl->llvmInternal == LLVMva_start) { | |
248 fn = gIR->module->getOrInsertFunction("llvm.va_start", fty); | |
249 assert(fn); | |
250 } | |
251 else if (fdecl->llvmInternal == LLVMva_intrinsic) { | |
252 fn = gIR->module->getOrInsertFunction(fdecl->llvmInternal1, fty); | |
253 assert(fn); | |
254 } | |
255 else | |
256 assert(0); | |
257 | |
258 llvm::Function* func = llvm::dyn_cast<llvm::Function>(fn); | |
259 assert(func); | |
260 assert(func->isIntrinsic()); | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
261 fdecl->ir.irFunc->func = func; |
100 | 262 return func; |
263 } | |
264 | |
265 ////////////////////////////////////////////////////////////////////////////////////////// | |
266 | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
267 void DtoResolveFunction(FuncDeclaration* fdecl) |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
268 { |
121
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
269 if (!global.params.useUnitTests && fdecl->isUnitTestDeclaration()) { |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
270 return; // ignore declaration completely |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
271 } |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
272 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
273 // is imported and we don't have access? |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
274 if (fdecl->getModule() != gIR->dmodule) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
275 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
276 if (fdecl->prot() == PROTprivate) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
277 return; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
278 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
279 |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
280 if (fdecl->ir.resolved) return; |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
281 fdecl->ir.resolved = true; |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
282 |
132 | 283 Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars()); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
284 LOG_SCOPE; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
285 |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
286 if (fdecl->runTimeHack) { |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
287 gIR->declareList.push_back(fdecl); |
127 | 288 TypeFunction* tf = (TypeFunction*)fdecl->type; |
289 tf->llvmRetInPtr = DtoIsPassedByRef(tf->next); | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
290 return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
291 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
292 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
293 if (fdecl->parent) |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
294 if (TemplateInstance* tinst = fdecl->parent->isTemplateInstance()) |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
295 { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
296 TemplateDeclaration* tempdecl = tinst->tempdecl; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
297 if (tempdecl->llvmInternal == LLVMva_arg) |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
298 { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
299 Logger::println("magic va_arg found"); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
300 fdecl->llvmInternal = LLVMva_arg; |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
301 fdecl->ir.declared = true; |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
302 fdecl->ir.initialized = true; |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
303 fdecl->ir.defined = true; |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
304 return; // this gets mapped to an instruction so a declaration makes no sence |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
305 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
306 else if (tempdecl->llvmInternal == LLVMva_start) |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
307 { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
308 Logger::println("magic va_start found"); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
309 fdecl->llvmInternal = LLVMva_start; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
310 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
311 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
312 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
313 DtoFunctionType(fdecl); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
314 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
315 // queue declaration |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
109
diff
changeset
|
316 if (!fdecl->isAbstract()) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
109
diff
changeset
|
317 gIR->declareList.push_back(fdecl); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
318 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
319 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
320 ////////////////////////////////////////////////////////////////////////////////////////// |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
321 |
240
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
322 static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl) |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
323 { |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
324 assert(f->parameters); |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
325 |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
326 int llidx = 1; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
327 if (f->llvmRetInPtr) ++llidx; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
328 if (f->llvmUsesThis) ++llidx; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
329 if (f->linkage == LINKd && f->varargs == 1) |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
330 llidx += 2; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
331 |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
332 int funcNumArgs = func->getArgumentList().size(); |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
333 std::vector<llvm::ParamAttrsWithIndex> attrs; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
334 int k = 0; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
335 |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
336 int nbyval = 0; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
337 |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
338 if (fdecl->isMain() && Argument::dim(f->parameters) == 0) |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
339 { |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
340 llvm::ParamAttrsWithIndex PAWI; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
341 PAWI.Index = llidx; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
342 PAWI.Attrs = llvm::ParamAttr::ByVal; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
343 attrs.push_back(PAWI); |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
344 llidx++; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
345 nbyval++; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
346 } |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
347 |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
348 for (; llidx <= funcNumArgs && f->parameters->dim > k; ++llidx,++k) |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
349 { |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
350 Argument* fnarg = (Argument*)f->parameters->data[k]; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
351 assert(fnarg); |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
352 if (fnarg->llvmByVal) |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
353 { |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
354 llvm::ParamAttrsWithIndex PAWI; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
355 PAWI.Index = llidx; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
356 PAWI.Attrs = llvm::ParamAttr::ByVal; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
357 attrs.push_back(PAWI); |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
358 nbyval++; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
359 } |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
360 } |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
361 |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
362 if (nbyval) { |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
363 llvm::PAListPtr palist = llvm::PAListPtr::get(attrs.begin(), attrs.end()); |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
364 func->setParamAttrs(palist); |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
365 } |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
366 } |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
367 |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
368 ////////////////////////////////////////////////////////////////////////////////////////// |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
369 |
100 | 370 void DtoDeclareFunction(FuncDeclaration* fdecl) |
371 { | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
372 if (fdecl->ir.declared) return; |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
373 fdecl->ir.declared = true; |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
374 |
132 | 375 Logger::println("DtoDeclareFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars()); |
100 | 376 LOG_SCOPE; |
377 | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
109
diff
changeset
|
378 assert(!fdecl->isAbstract()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
109
diff
changeset
|
379 |
121
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
380 // intrinsic sanity check |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
381 if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) { |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
382 error(fdecl->loc, "intrinsics cannot have function bodies"); |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
383 fatal(); |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
384 } |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
385 |
240
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
386 // get TypeFunction* |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
387 Type* t = DtoDType(fdecl->type); |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
388 TypeFunction* f = (TypeFunction*)t; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
389 |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
390 // runtime function special handling |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
391 if (fdecl->runTimeHack) { |
100 | 392 Logger::println("runtime hack func chars: %s", fdecl->toChars()); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
393 if (!fdecl->ir.irFunc) { |
240
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
394 IrFunction* irfunc = new IrFunction(fdecl); |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
395 llvm::Function* llfunc = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars()); |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
396 fdecl->ir.irFunc = irfunc; |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
397 fdecl->ir.irFunc->func = llfunc; |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
398 } |
100 | 399 return; |
400 } | |
401 | |
402 bool declareOnly = false; | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
403 bool templInst = fdecl->parent && DtoIsTemplateInstance(fdecl->parent); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
404 if (!templInst && fdecl->getModule() != gIR->dmodule) |
144
a27941d00351
[svn r149] fixed: a bunch of D-style variadics problems.
lindquist
parents:
139
diff
changeset
|
405 { |
a27941d00351
[svn r149] fixed: a bunch of D-style variadics problems.
lindquist
parents:
139
diff
changeset
|
406 Logger::println("not template instance, and not in this module. declare only!"); |
a27941d00351
[svn r149] fixed: a bunch of D-style variadics problems.
lindquist
parents:
139
diff
changeset
|
407 Logger::println("current module: %s", gIR->dmodule->ident->toChars()); |
a27941d00351
[svn r149] fixed: a bunch of D-style variadics problems.
lindquist
parents:
139
diff
changeset
|
408 Logger::println("func module: %s", fdecl->getModule()->ident->toChars()); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
409 declareOnly = true; |
144
a27941d00351
[svn r149] fixed: a bunch of D-style variadics problems.
lindquist
parents:
139
diff
changeset
|
410 } |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
411 else if (fdecl->llvmInternal == LLVMva_start) |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
412 declareOnly = true; |
100 | 413 |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
414 if (!fdecl->ir.irFunc) { |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
415 fdecl->ir.irFunc = new IrFunction(fdecl); |
100 | 416 } |
417 | |
418 // mangled name | |
419 char* mangled_name; | |
420 if (fdecl->llvmInternal == LLVMintrinsic) | |
421 mangled_name = fdecl->llvmInternal1; | |
422 else | |
423 mangled_name = fdecl->mangle(); | |
424 | |
425 llvm::Function* vafunc = 0; | |
426 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) { | |
427 vafunc = DtoDeclareVaFunction(fdecl); | |
428 } | |
429 | |
430 // construct function | |
431 const llvm::FunctionType* functype = DtoFunctionType(fdecl); | |
432 llvm::Function* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name); | |
433 if (!func) | |
205
9d44ec83acd1
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
lindquist
parents:
173
diff
changeset
|
434 func = llvm::Function::Create(functype, DtoLinkage(fdecl), mangled_name, gIR->module); |
100 | 435 else |
436 assert(func->getFunctionType() == functype); | |
437 | |
438 // add func to IRFunc | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
439 fdecl->ir.irFunc->func = func; |
100 | 440 |
441 // calling convention | |
442 if (!vafunc && fdecl->llvmInternal != LLVMintrinsic) | |
443 func->setCallingConv(DtoCallingConv(f->linkage)); | |
149
4c577c2b7229
[svn r155] Fixed a bunch of linkage problems (especially with templates)
lindquist
parents:
144
diff
changeset
|
444 else // fall back to C, it should be the right thing to do |
132 | 445 func->setCallingConv(llvm::CallingConv::C); |
446 | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
447 fdecl->ir.irFunc->func = func; |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
448 assert(llvm::isa<llvm::FunctionType>(f->ir.type->get())); |
100 | 449 |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
450 // parameter attributes |
240
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
451 if (f->parameters) { |
0db62b770a49
[svn r257] Fixed: array .sort and .reverse runtime code was incorrect.
lindquist
parents:
234
diff
changeset
|
452 set_param_attrs(f, func, fdecl); |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
453 } |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
454 |
116
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
455 // main |
100 | 456 if (fdecl->isMain()) { |
457 gIR->mainFunc = func; | |
458 } | |
459 | |
116
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
460 // static ctor |
163
a8cd9bc1021a
[svn r179] lots and lots of fixes, much more of tango now compiles/works.
lindquist
parents:
162
diff
changeset
|
461 if (fdecl->isStaticCtorDeclaration() && fdecl->getModule() == gIR->dmodule) { |
116
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
462 gIR->ctors.push_back(fdecl); |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
463 } |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
464 // static dtor |
163
a8cd9bc1021a
[svn r179] lots and lots of fixes, much more of tango now compiles/works.
lindquist
parents:
162
diff
changeset
|
465 else if (fdecl->isStaticDtorDeclaration() && fdecl->getModule() == gIR->dmodule) { |
116
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
466 gIR->dtors.push_back(fdecl); |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
467 } |
fd7ad91fd713
[svn r120] ModuleInfo implementation is now almost complete.
lindquist
parents:
113
diff
changeset
|
468 |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
469 // we never reference parameters of function prototypes |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
470 if (!declareOnly) |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
471 { |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
472 // name parameters |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
473 llvm::Function::arg_iterator iarg = func->arg_begin(); |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
474 int k = 0; |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
475 if (f->llvmRetInPtr) { |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
476 iarg->setName("retval"); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
477 fdecl->ir.irFunc->retArg = iarg; |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
478 ++iarg; |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
479 } |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
480 if (f->llvmUsesThis) { |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
481 iarg->setName("this"); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
482 fdecl->ir.irFunc->thisVar = iarg; |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
483 assert(fdecl->ir.irFunc->thisVar); |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
484 ++iarg; |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
485 } |
119
79c9ac745fbc
[svn r123] Fixed some typeinfo module name mismatches.
lindquist
parents:
117
diff
changeset
|
486 |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
487 if (f->linkage == LINKd && f->varargs == 1) { |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
488 iarg->setName("_arguments"); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
489 fdecl->ir.irFunc->_arguments = iarg; |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
490 ++iarg; |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
491 iarg->setName("_argptr"); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
492 fdecl->ir.irFunc->_argptr = iarg; |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
493 ++iarg; |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
494 } |
119
79c9ac745fbc
[svn r123] Fixed some typeinfo module name mismatches.
lindquist
parents:
117
diff
changeset
|
495 |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
496 for (; iarg != func->arg_end(); ++iarg) |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
497 { |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
498 if (fdecl->parameters && fdecl->parameters->dim > k) |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
499 { |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
500 Dsymbol* argsym = (Dsymbol*)fdecl->parameters->data[k++]; |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
501 VarDeclaration* argvd = argsym->isVarDeclaration(); |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
502 assert(argvd); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
503 assert(!argvd->ir.irLocal); |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
504 argvd->ir.irLocal = new IrLocal(argvd); |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
505 argvd->ir.irLocal->value = iarg; |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
506 iarg->setName(argvd->ident->toChars()); |
100 | 507 } |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
508 else |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
509 { |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
510 iarg->setName("unnamed"); |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
511 } |
100 | 512 } |
513 } | |
514 | |
121
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
515 if (fdecl->isUnitTestDeclaration()) |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
516 gIR->unitTests.push_back(fdecl); |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
517 |
100 | 518 if (!declareOnly) |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
519 gIR->defineList.push_back(fdecl); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
520 else |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
521 assert(func->getLinkage() != llvm::GlobalValue::InternalLinkage); |
100 | 522 |
523 Logger::cout() << "func decl: " << *func << '\n'; | |
524 } | |
525 | |
526 ////////////////////////////////////////////////////////////////////////////////////////// | |
527 | |
528 void DtoDefineFunc(FuncDeclaration* fd) | |
529 { | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
530 if (fd->ir.defined) return; |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
531 fd->ir.defined = true; |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
532 |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
533 assert(fd->ir.declared); |
108
288fe1029e1f
[svn r112] Fixed 'case 1,2,3:' style case statements.
lindquist
parents:
102
diff
changeset
|
534 |
132 | 535 Logger::println("DtoDefineFunc(%s): %s", fd->toPrettyChars(), fd->loc.toChars()); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
536 LOG_SCOPE; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
537 |
100 | 538 // debug info |
539 if (global.params.symdebug) { | |
540 Module* mo = fd->getModule(); | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
541 fd->ir.irFunc->dwarfSubProg = DtoDwarfSubProgram(fd, DtoDwarfCompileUnit(mo)); |
100 | 542 } |
543 | |
544 Type* t = DtoDType(fd->type); | |
545 TypeFunction* f = (TypeFunction*)t; | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
546 assert(f->ir.type); |
100 | 547 |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
548 llvm::Function* func = fd->ir.irFunc->func; |
100 | 549 const llvm::FunctionType* functype = func->getFunctionType(); |
550 | |
551 // only members of the current module or template instances maybe be defined | |
552 if (fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent)) | |
553 { | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
554 fd->ir.DModule = gIR->dmodule; |
100 | 555 |
556 // function definition | |
557 if (fd->fbody != 0) | |
558 { | |
559 Logger::println("Doing function body for: %s", fd->toChars()); | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
560 assert(fd->ir.irFunc); |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
561 gIR->functions.push_back(fd->ir.irFunc); |
100 | 562 |
563 if (fd->isMain()) | |
564 gIR->emitMain = true; | |
565 | |
205
9d44ec83acd1
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
lindquist
parents:
173
diff
changeset
|
566 std::string entryname("entry_"); |
9d44ec83acd1
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
lindquist
parents:
173
diff
changeset
|
567 entryname.append(fd->toPrettyChars()); |
9d44ec83acd1
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
lindquist
parents:
173
diff
changeset
|
568 |
9d44ec83acd1
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
lindquist
parents:
173
diff
changeset
|
569 llvm::BasicBlock* beginbb = llvm::BasicBlock::Create(entryname,func); |
9d44ec83acd1
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
lindquist
parents:
173
diff
changeset
|
570 llvm::BasicBlock* endbb = llvm::BasicBlock::Create("endentry",func); |
100 | 571 |
572 //assert(gIR->scopes.empty()); | |
573 gIR->scopes.push_back(IRScope(beginbb, endbb)); | |
574 | |
575 // create alloca point | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
576 llvm::Instruction* allocaPoint = new llvm::AllocaInst(llvm::Type::Int32Ty, "alloca point", beginbb); |
121
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
577 gIR->func()->allocapoint = allocaPoint; |
100 | 578 |
108
288fe1029e1f
[svn r112] Fixed 'case 1,2,3:' style case statements.
lindquist
parents:
102
diff
changeset
|
579 // need result variable? (not nested) |
288fe1029e1f
[svn r112] Fixed 'case 1,2,3:' style case statements.
lindquist
parents:
102
diff
changeset
|
580 if (fd->vresult && !fd->vresult->nestedref) { |
288fe1029e1f
[svn r112] Fixed 'case 1,2,3:' style case statements.
lindquist
parents:
102
diff
changeset
|
581 Logger::println("non-nested vresult value"); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
582 fd->vresult->ir.irLocal = new IrLocal(fd->vresult); |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
583 fd->vresult->ir.irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint); |
108
288fe1029e1f
[svn r112] Fixed 'case 1,2,3:' style case statements.
lindquist
parents:
102
diff
changeset
|
584 } |
288fe1029e1f
[svn r112] Fixed 'case 1,2,3:' style case statements.
lindquist
parents:
102
diff
changeset
|
585 |
100 | 586 // give arguments storage |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
587 if (fd->parameters) |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
588 { |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
589 size_t n = fd->parameters->dim; |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
590 for (int i=0; i < n; ++i) |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
591 { |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
592 Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i]; |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
593 VarDeclaration* vd = argsym->isVarDeclaration(); |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
594 assert(vd); |
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
595 |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
596 if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)) |
100 | 597 continue; |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
598 |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
599 LLValue* a = vd->ir.irLocal->value; |
100 | 600 assert(a); |
601 std::string s(a->getName()); | |
602 Logger::println("giving argument '%s' storage", s.c_str()); | |
603 s.append("_storage"); | |
162
1856c62af24b
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
lindquist
parents:
157
diff
changeset
|
604 |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
605 LLValue* v = new llvm::AllocaInst(a->getType(),s,allocaPoint); |
100 | 606 gIR->ir->CreateStore(a,v); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
607 vd->ir.irLocal->value = v; |
100 | 608 } |
609 } | |
610 | |
611 // debug info | |
612 if (global.params.symdebug) DtoDwarfFuncStart(fd); | |
613 | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
614 LLValue* parentNested = NULL; |
131 | 615 if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) { |
616 if (!fd->isStatic()) // huh? | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
617 parentNested = fd2->ir.irFunc->nestedVar; |
108
288fe1029e1f
[svn r112] Fixed 'case 1,2,3:' style case statements.
lindquist
parents:
102
diff
changeset
|
618 } |
288fe1029e1f
[svn r112] Fixed 'case 1,2,3:' style case statements.
lindquist
parents:
102
diff
changeset
|
619 |
288fe1029e1f
[svn r112] Fixed 'case 1,2,3:' style case statements.
lindquist
parents:
102
diff
changeset
|
620 // need result variable? (nested) |
288fe1029e1f
[svn r112] Fixed 'case 1,2,3:' style case statements.
lindquist
parents:
102
diff
changeset
|
621 if (fd->vresult && fd->vresult->nestedref) { |
288fe1029e1f
[svn r112] Fixed 'case 1,2,3:' style case statements.
lindquist
parents:
102
diff
changeset
|
622 Logger::println("nested vresult value: %s", fd->vresult->toChars()); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
623 fd->nestedVars.insert(fd->vresult); |
100 | 624 } |
625 | |
626 // construct nested variables struct | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
627 if (!fd->nestedVars.empty() || parentNested) { |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
628 std::vector<const LLType*> nestTypes; |
100 | 629 int j = 0; |
630 if (parentNested) { | |
631 nestTypes.push_back(parentNested->getType()); | |
632 j++; | |
633 } | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
634 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) { |
100 | 635 VarDeclaration* vd = *i; |
144
a27941d00351
[svn r149] fixed: a bunch of D-style variadics problems.
lindquist
parents:
139
diff
changeset
|
636 Logger::println("referenced nested variable %s", vd->toChars()); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
637 if (!vd->ir.irLocal) |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
638 vd->ir.irLocal = new IrLocal(vd); |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
639 vd->ir.irLocal->nestedIndex = j++; |
100 | 640 if (vd->isParameter()) { |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
641 if (!vd->ir.irLocal->value) { |
144
a27941d00351
[svn r149] fixed: a bunch of D-style variadics problems.
lindquist
parents:
139
diff
changeset
|
642 assert(vd == fd->vthis); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
643 vd->ir.irLocal->value = fd->ir.irFunc->thisVar; |
144
a27941d00351
[svn r149] fixed: a bunch of D-style variadics problems.
lindquist
parents:
139
diff
changeset
|
644 } |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
645 assert(vd->ir.irLocal->value); |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
646 nestTypes.push_back(vd->ir.irLocal->value->getType()); |
100 | 647 } |
648 else { | |
649 nestTypes.push_back(DtoType(vd->type)); | |
650 } | |
651 } | |
652 const llvm::StructType* nestSType = llvm::StructType::get(nestTypes); | |
129
8096ba7082db
[svn r133] Fixed some problems with inlining not happening :P
lindquist
parents:
127
diff
changeset
|
653 Logger::cout() << "nested var struct has type:" << *nestSType << '\n'; |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
654 fd->ir.irFunc->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint); |
100 | 655 if (parentNested) { |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
656 assert(fd->ir.irFunc->thisVar); |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
657 LLValue* ptr = gIR->ir->CreateBitCast(fd->ir.irFunc->thisVar, parentNested->getType(), "tmp"); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
658 gIR->ir->CreateStore(ptr, DtoGEPi(fd->ir.irFunc->nestedVar, 0,0, "tmp")); |
100 | 659 } |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
660 for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) { |
100 | 661 VarDeclaration* vd = *i; |
662 if (vd->isParameter()) { | |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
663 assert(vd->ir.irLocal); |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
664 gIR->ir->CreateStore(vd->ir.irLocal->value, DtoGEPi(fd->ir.irFunc->nestedVar, 0, vd->ir.irLocal->nestedIndex, "tmp")); |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
665 vd->ir.irLocal->value = fd->ir.irFunc->nestedVar; |
100 | 666 } |
667 } | |
668 } | |
669 | |
670 // copy _argptr to a memory location | |
671 if (f->linkage == LINKd && f->varargs == 1) | |
672 { | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
673 LLValue* argptrmem = new llvm::AllocaInst(fd->ir.irFunc->_argptr->getType(), "_argptrmem", gIR->topallocapoint()); |
173
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
674 new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb()); |
db9890b3fb64
[svn r189] moving IR data back into DMD frontend nodes
ChristianK
parents:
163
diff
changeset
|
675 fd->ir.irFunc->_argptr = argptrmem; |
100 | 676 } |
677 | |
678 // output function body | |
679 fd->fbody->toIR(gIR); | |
680 | |
681 // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement | |
682 // in automatically, so we do it here. | |
683 if (!fd->isMain()) { | |
684 if (!gIR->scopereturned()) { | |
685 // pass the previous block into this block | |
686 if (global.params.symdebug) DtoDwarfFuncEnd(fd); | |
687 if (func->getReturnType() == llvm::Type::VoidTy) { | |
205
9d44ec83acd1
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
lindquist
parents:
173
diff
changeset
|
688 llvm::ReturnInst::Create(gIR->scopebb()); |
100 | 689 } |
690 else { | |
205
9d44ec83acd1
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
lindquist
parents:
173
diff
changeset
|
691 llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb()); |
100 | 692 } |
693 } | |
694 } | |
695 | |
696 // erase alloca point | |
121
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
697 allocaPoint->eraseFromParent(); |
9c79b61fb638
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
lindquist
parents:
119
diff
changeset
|
698 allocaPoint = 0; |
100 | 699 gIR->func()->allocapoint = 0; |
700 | |
701 gIR->scopes.pop_back(); | |
702 | |
703 // get rid of the endentry block, it's never used | |
704 assert(!func->getBasicBlockList().empty()); | |
705 func->getBasicBlockList().pop_back(); | |
706 | |
707 // if the last block is empty now, it must be unreachable or it's a bug somewhere else | |
708 // would be nice to figure out how to assert that this is correct | |
709 llvm::BasicBlock* lastbb = &func->getBasicBlockList().back(); | |
710 if (lastbb->empty()) { | |
711 if (lastbb->getNumUses() == 0) | |
712 lastbb->eraseFromParent(); | |
713 else { | |
714 new llvm::UnreachableInst(lastbb); | |
715 /*if (func->getReturnType() == llvm::Type::VoidTy) { | |
205
9d44ec83acd1
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
lindquist
parents:
173
diff
changeset
|
716 llvm::ReturnInst::Create(lastbb); |
100 | 717 } |
718 else { | |
205
9d44ec83acd1
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
lindquist
parents:
173
diff
changeset
|
719 llvm::ReturnInst::Create(llvm::UndefValue::get(func->getReturnType()), lastbb); |
100 | 720 }*/ |
721 } | |
722 } | |
723 | |
225
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
724 // if the last block is not terminated we return a null value or void |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
725 // for some unknown reason this is needed when a void main() has a inline asm block ... |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
726 // this should be harmless for well formed code! |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
727 lastbb = &func->getBasicBlockList().back(); |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
728 if (!lastbb->getTerminator()) |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
729 { |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
730 Logger::println("adding missing return statement"); |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
731 if (func->getReturnType() == llvm::Type::VoidTy) |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
732 llvm::ReturnInst::Create(lastbb); |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
733 else |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
734 llvm::ReturnInst::Create(llvm::Constant::getNullValue(func->getReturnType()), lastbb); |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
735 } |
74701ba40398
[svn r241] Fixed missing terminator for void main() with inline asm block.
lindquist
parents:
217
diff
changeset
|
736 |
100 | 737 gIR->functions.pop_back(); |
738 } | |
739 } | |
740 } | |
741 | |
742 ////////////////////////////////////////////////////////////////////////////////////////// | |
743 | |
117 | 744 const llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl) |
745 { | |
746 Dsymbol* parent = fdecl->toParent(); | |
747 ClassDeclaration* cd = parent->isClassDeclaration(); | |
748 assert(cd); | |
749 | |
750 FuncDeclaration* f = fdecl; | |
751 | |
752 while (cd) | |
753 { | |
754 ClassDeclaration* base = cd->baseClass; | |
755 if (!base) | |
756 break; | |
757 FuncDeclaration* f2 = base->findFunc(fdecl->ident, (TypeFunction*)fdecl->type); | |
758 if (f2) { | |
759 f = f2; | |
760 cd = base; | |
761 } | |
762 else | |
763 break; | |
764 } | |
765 | |
766 DtoResolveDsymbol(f); | |
767 return llvm::cast<llvm::FunctionType>(DtoType(f->type)); | |
768 } | |
769 | |
770 ////////////////////////////////////////////////////////////////////////////////////////// | |
131 | 771 |
772 DValue* DtoArgument(Argument* fnarg, Expression* argexp) | |
773 { | |
774 Logger::println("DtoArgument"); | |
775 LOG_SCOPE; | |
776 | |
777 DValue* arg = argexp->toElem(gIR); | |
778 | |
779 // ref/out arg | |
780 if (fnarg && ((fnarg->storageClass & STCref) || (fnarg->storageClass & STCout))) | |
781 { | |
782 if (arg->isVar() || arg->isLRValue()) | |
783 arg = new DImValue(argexp->type, arg->getLVal(), false); | |
784 else | |
785 arg = new DImValue(argexp->type, arg->getRVal(), false); | |
786 } | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
787 // byval arg, but expr has no storage yet |
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
215
diff
changeset
|
788 else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isComplex() || arg->isNull())) |
131 | 789 { |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
790 LLValue* alloc = new llvm::AllocaInst(DtoType(argexp->type), "tmpparam", gIR->topallocapoint()); |
131 | 791 DVarValue* vv = new DVarValue(argexp->type, alloc, true); |
792 DtoAssign(vv, arg); | |
793 arg = vv; | |
794 } | |
795 | |
796 return arg; | |
797 } | |
798 | |
799 ////////////////////////////////////////////////////////////////////////////////////////// | |
800 | |
213
7816aafeea3c
[svn r229] Updated the object.d implementation to the latest Tango.
lindquist
parents:
205
diff
changeset
|
801 void DtoVariadicArgument(Expression* argexp, LLValue* dst) |
131 | 802 { |
803 Logger::println("DtoVariadicArgument"); | |
804 LOG_SCOPE; | |
805 DVarValue* vv = new DVarValue(argexp->type, dst, true); | |
215
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
213
diff
changeset
|
806 gIR->exps.push_back(IRExp(NULL, argexp, vv)); |
131 | 807 DtoAssign(vv, argexp->toElem(gIR)); |
215
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
213
diff
changeset
|
808 gIR->exps.pop_back(); |
131 | 809 } |
810 | |
811 ////////////////////////////////////////////////////////////////////////////////////////// |