Mercurial > projects > ldc
comparison gen/functions.cpp @ 102:027b8d8b71ec trunk
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
Basically it tries to do the following in order: Resolve types, Declare symbols, Create constant initializers, Apply initializers, Generate functions bodies.
ClassInfo is now has the most useful(biased?) members working.
Probably other stuf...
author | lindquist |
---|---|
date | Sun, 18 Nov 2007 06:52:57 +0100 |
parents | 5071469303d4 |
children | 288fe1029e1f |
comparison
equal
deleted
inserted
replaced
101:169fda3a77d4 | 102:027b8d8b71ec |
---|---|
69 } | 69 } |
70 | 70 |
71 if (typesafeVararg) { | 71 if (typesafeVararg) { |
72 ClassDeclaration* ti = Type::typeinfo; | 72 ClassDeclaration* ti = Type::typeinfo; |
73 ti->toObjFile(); | 73 ti->toObjFile(); |
74 DtoConstInitClass(ti); | 74 DtoForceConstInitDsymbol(ti); |
75 assert(ti->llvmInitZ); | 75 assert(ti->llvmInitZ); |
76 std::vector<const llvm::Type*> types; | 76 std::vector<const llvm::Type*> types; |
77 types.push_back(DtoSize_t()); | 77 types.push_back(DtoSize_t()); |
78 types.push_back(llvm::PointerType::get(llvm::PointerType::get(ti->llvmInitZ->getType()))); | 78 types.push_back(llvm::PointerType::get(llvm::PointerType::get(ti->llvmInitZ->getType()))); |
79 const llvm::Type* t1 = llvm::StructType::get(types); | 79 const llvm::Type* t1 = llvm::StructType::get(types); |
129 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); | 129 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); |
130 | 130 |
131 f->llvmRetInPtr = retinptr; | 131 f->llvmRetInPtr = retinptr; |
132 f->llvmUsesThis = usesthis; | 132 f->llvmUsesThis = usesthis; |
133 | 133 |
134 if (!f->llvmType) | 134 //if (!f->llvmType) |
135 f->llvmType = new llvm::PATypeHolder(functype); | 135 f->llvmType = new llvm::PATypeHolder(functype); |
136 else | 136 //else |
137 assert(functype == f->llvmType->get()); | 137 //assert(functype == f->llvmType->get()); |
138 | 138 |
139 return functype; | 139 return functype; |
140 } | 140 } |
141 | 141 |
142 ////////////////////////////////////////////////////////////////////////////////////////// | 142 ////////////////////////////////////////////////////////////////////////////////////////// |
143 | 143 |
144 static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl) | 144 static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl) |
145 { | 145 { |
146 // type has already been resolved | |
147 if (fdecl->type->llvmType != 0) { | |
148 return llvm::cast<llvm::FunctionType>(fdecl->type->llvmType->get()); | |
149 } | |
150 | |
146 TypeFunction* f = (TypeFunction*)fdecl->type; | 151 TypeFunction* f = (TypeFunction*)fdecl->type; |
147 assert(f != 0); | 152 assert(f != 0); |
148 | 153 |
149 const llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); | 154 const llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); |
150 std::vector<const llvm::Type*> args; | 155 std::vector<const llvm::Type*> args; |
161 else | 166 else |
162 assert(0); | 167 assert(0); |
163 | 168 |
164 const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::VoidTy, args, false); | 169 const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::VoidTy, args, false); |
165 | 170 |
166 if (!f->llvmType) | 171 f->llvmType = new llvm::PATypeHolder(fty); |
167 f->llvmType = new llvm::PATypeHolder(fty); | |
168 else | |
169 assert(fty == f->llvmType->get()); | |
170 | 172 |
171 return fty; | 173 return fty; |
172 } | 174 } |
173 | 175 |
174 ////////////////////////////////////////////////////////////////////////////////////////// | 176 ////////////////////////////////////////////////////////////////////////////////////////// |
188 if (fdecl->needThis()) { | 190 if (fdecl->needThis()) { |
189 if (AggregateDeclaration* ad = fdecl->isMember()) { | 191 if (AggregateDeclaration* ad = fdecl->isMember()) { |
190 Logger::print("isMember = this is: %s\n", ad->type->toChars()); | 192 Logger::print("isMember = this is: %s\n", ad->type->toChars()); |
191 thisty = DtoType(ad->type); | 193 thisty = DtoType(ad->type); |
192 Logger::cout() << "this llvm type: " << *thisty << '\n'; | 194 Logger::cout() << "this llvm type: " << *thisty << '\n'; |
193 if (isaStruct(thisty) || thisty == gIR->topstruct()->recty.get()) | 195 if (isaStruct(thisty) || (!gIR->structs.empty() && thisty == gIR->topstruct()->recty.get())) |
194 thisty = llvm::PointerType::get(thisty); | 196 thisty = llvm::PointerType::get(thisty); |
195 } | 197 } |
196 else | 198 else |
197 assert(0); | 199 assert(0); |
198 } | 200 } |
231 return func; | 233 return func; |
232 } | 234 } |
233 | 235 |
234 ////////////////////////////////////////////////////////////////////////////////////////// | 236 ////////////////////////////////////////////////////////////////////////////////////////// |
235 | 237 |
238 void DtoResolveFunction(FuncDeclaration* fdecl) | |
239 { | |
240 if (fdecl->llvmResolved) return; | |
241 fdecl->llvmResolved = true; | |
242 | |
243 Logger::println("DtoResolveFunction(%s)", fdecl->toPrettyChars()); | |
244 LOG_SCOPE; | |
245 | |
246 if (fdecl->llvmRunTimeHack) { | |
247 gIR->declareList.push_back(fdecl); | |
248 return; | |
249 } | |
250 | |
251 if (fdecl->isUnitTestDeclaration()) { | |
252 Logger::attention("ignoring unittest declaration: %s", fdecl->toChars()); | |
253 return; | |
254 } | |
255 | |
256 if (fdecl->parent) | |
257 if (TemplateInstance* tinst = fdecl->parent->isTemplateInstance()) | |
258 { | |
259 TemplateDeclaration* tempdecl = tinst->tempdecl; | |
260 if (tempdecl->llvmInternal == LLVMva_arg) | |
261 { | |
262 Logger::println("magic va_arg found"); | |
263 fdecl->llvmInternal = LLVMva_arg; | |
264 fdecl->llvmDeclared = true; | |
265 fdecl->llvmInitialized = true; | |
266 fdecl->llvmDefined = true; | |
267 return; // this gets mapped to an instruction so a declaration makes no sence | |
268 } | |
269 else if (tempdecl->llvmInternal == LLVMva_start) | |
270 { | |
271 Logger::println("magic va_start found"); | |
272 fdecl->llvmInternal = LLVMva_start; | |
273 } | |
274 } | |
275 | |
276 DtoFunctionType(fdecl); | |
277 | |
278 // queue declaration | |
279 gIR->declareList.push_back(fdecl); | |
280 } | |
281 | |
282 ////////////////////////////////////////////////////////////////////////////////////////// | |
283 | |
236 void DtoDeclareFunction(FuncDeclaration* fdecl) | 284 void DtoDeclareFunction(FuncDeclaration* fdecl) |
237 { | 285 { |
286 if (fdecl->llvmDeclared) return; | |
287 fdecl->llvmDeclared = true; | |
288 | |
238 Logger::println("DtoDeclareFunction(%s)", fdecl->toPrettyChars()); | 289 Logger::println("DtoDeclareFunction(%s)", fdecl->toPrettyChars()); |
239 LOG_SCOPE; | 290 LOG_SCOPE; |
240 | 291 |
241 if (fdecl->llvmRunTimeHack) { | 292 if (fdecl->llvmRunTimeHack) { |
242 Logger::println("runtime hack func chars: %s", fdecl->toChars()); | 293 Logger::println("runtime hack func chars: %s", fdecl->toChars()); |
243 if (!fdecl->llvmValue) | 294 if (!fdecl->llvmValue) |
244 fdecl->llvmValue = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars()); | 295 fdecl->llvmValue = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars()); |
245 return; | 296 return; |
246 } | 297 } |
247 | 298 |
248 if (fdecl->isUnitTestDeclaration()) { | |
249 Logger::attention("ignoring unittest declaration: %s", fdecl->toChars()); | |
250 return; | |
251 } | |
252 | |
253 bool declareOnly = false; | 299 bool declareOnly = false; |
254 if (fdecl->parent) | 300 bool templInst = fdecl->parent && DtoIsTemplateInstance(fdecl->parent); |
255 { | 301 if (!templInst && fdecl->getModule() != gIR->dmodule) |
256 if (TemplateInstance* tinst = fdecl->parent->isTemplateInstance()) | 302 declareOnly = true; |
257 { | 303 else if (fdecl->llvmInternal == LLVMva_start) |
258 TemplateDeclaration* tempdecl = tinst->tempdecl; | 304 declareOnly = true; |
259 if (tempdecl->llvmInternal == LLVMva_start) | |
260 { | |
261 Logger::println("magic va_start found"); | |
262 fdecl->llvmInternal = LLVMva_start; | |
263 declareOnly = true; | |
264 } | |
265 else if (tempdecl->llvmInternal == LLVMva_arg) | |
266 { | |
267 Logger::println("magic va_arg found"); | |
268 fdecl->llvmInternal = LLVMva_arg; | |
269 return; | |
270 } | |
271 } | |
272 } | |
273 | |
274 if (fdecl->llvmTouched) return; | |
275 fdecl->llvmTouched = true; | |
276 | 305 |
277 if (!fdecl->llvmIRFunc) { | 306 if (!fdecl->llvmIRFunc) { |
278 fdecl->llvmIRFunc = new IRFunction(fdecl); | 307 fdecl->llvmIRFunc = new IRFunction(fdecl); |
279 } | 308 } |
280 | 309 |
382 iarg->setName("unnamed"); | 411 iarg->setName("unnamed"); |
383 } | 412 } |
384 } | 413 } |
385 | 414 |
386 if (!declareOnly) | 415 if (!declareOnly) |
387 gIR->defineQueue.push_back(fdecl); | 416 gIR->defineList.push_back(fdecl); |
388 | 417 |
389 Logger::cout() << "func decl: " << *func << '\n'; | 418 Logger::cout() << "func decl: " << *func << '\n'; |
390 } | 419 } |
391 | 420 |
392 ////////////////////////////////////////////////////////////////////////////////////////// | 421 ////////////////////////////////////////////////////////////////////////////////////////// |
393 | 422 |
394 // TODO split this monster up | 423 // TODO split this monster up |
395 void DtoDefineFunc(FuncDeclaration* fd) | 424 void DtoDefineFunc(FuncDeclaration* fd) |
396 { | 425 { |
426 if (fd->llvmDefined) return; | |
427 fd->llvmDefined = true; | |
428 | |
429 Logger::println("DtoDefineFunc(%s)", fd->toPrettyChars()); | |
430 LOG_SCOPE; | |
431 | |
397 // debug info | 432 // debug info |
398 if (global.params.symdebug) { | 433 if (global.params.symdebug) { |
399 Module* mo = fd->getModule(); | 434 Module* mo = fd->getModule(); |
400 if (!mo->llvmCompileUnit) { | 435 if (!mo->llvmCompileUnit) { |
401 mo->llvmCompileUnit = DtoDwarfCompileUnit(mo,false); | 436 mo->llvmCompileUnit = DtoDwarfCompileUnit(mo,false); |