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