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);