Mercurial > projects > ldc
comparison gen/toobj.c @ 31:2841234d2aea trunk
[svn r35] * Attributes on struct fields/methods now work
* Updated object.d to 1.021
* Added -novalidate command line option. this is sometimes useful when debugging as it may let you read the .ll even if it's invalid.
author | lindquist |
---|---|
date | Thu, 04 Oct 2007 16:44:07 +0200 |
parents | 1c80c18f3c82 |
children | 27b2f40bdb58 |
comparison
equal
deleted
inserted
replaced
30:881158a93592 | 31:2841234d2aea |
---|---|
85 if (ir.emitMain) { | 85 if (ir.emitMain) { |
86 LLVM_DtoMain(); | 86 LLVM_DtoMain(); |
87 } | 87 } |
88 | 88 |
89 // verify the llvm | 89 // verify the llvm |
90 std::string verifyErr; | 90 if (!global.params.novalidate) { |
91 Logger::println("Verifying module..."); | 91 std::string verifyErr; |
92 if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr)) | 92 Logger::println("Verifying module..."); |
93 { | 93 if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr)) |
94 error("%s", verifyErr.c_str()); | 94 { |
95 fatal(); | 95 error("%s", verifyErr.c_str()); |
96 } | 96 fatal(); |
97 else | 97 } |
98 Logger::println("Verification passed!"); | 98 else { |
99 Logger::println("Verification passed!"); | |
100 } | |
101 } | |
99 | 102 |
100 // run passes | 103 // run passes |
101 // TODO | 104 // TODO |
102 | 105 |
103 /*if (global.params.llvmLL) { | 106 /*if (global.params.llvmLL) { |
217 Logger::print("StructDeclaration::toObjFile(%d): %s\n", sdi++, toChars()); | 220 Logger::print("StructDeclaration::toObjFile(%d): %s\n", sdi++, toChars()); |
218 LOG_SCOPE; | 221 LOG_SCOPE; |
219 | 222 |
220 gIR->structs.push_back(IRStruct(ts)); | 223 gIR->structs.push_back(IRStruct(ts)); |
221 | 224 |
222 std::vector<FuncDeclaration*> mfs; | |
223 | |
224 for (int k=0; k < members->dim; k++) { | 225 for (int k=0; k < members->dim; k++) { |
225 Dsymbol* dsym = (Dsymbol*)(members->data[k]); | 226 Dsymbol* dsym = (Dsymbol*)(members->data[k]); |
226 | 227 dsym->toObjFile(); |
227 // need late generation of member functions | |
228 // they need the llvm::StructType to exist to take the 'this' parameter | |
229 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { | |
230 mfs.push_back(fd); | |
231 } | |
232 else { | |
233 dsym->toObjFile(); | |
234 } | |
235 } | 228 } |
236 | 229 |
237 if (gIR->topstruct().fields.empty()) | 230 if (gIR->topstruct().fields.empty()) |
238 { | 231 { |
239 gIR->topstruct().fields.push_back(llvm::Type::Int8Ty); | 232 gIR->topstruct().fields.push_back(llvm::Type::Int8Ty); |
291 std::string initname(mangle()); | 284 std::string initname(mangle()); |
292 initname.append("__initZ"); | 285 initname.append("__initZ"); |
293 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType, true, _linkage, _init, initname, gIR->module); | 286 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType, true, _linkage, _init, initname, gIR->module); |
294 ts->llvmInit = initvar; | 287 ts->llvmInit = initvar; |
295 | 288 |
296 // generate member functions | 289 // generate member function definitions |
290 gIR->topstruct().queueFuncs = false; | |
291 IRState::FuncDeclVec& mfs = gIR->topstruct().funcs; | |
297 size_t n = mfs.size(); | 292 size_t n = mfs.size(); |
298 for (size_t i=0; i<n; ++i) { | 293 for (size_t i=0; i<n; ++i) { |
299 mfs[i]->toObjFile(); | 294 mfs[i]->toObjFile(); |
300 } | 295 } |
301 | 296 |
339 Logger::print("ClassDeclaration::toObjFile(%d): %s\n", fdi++, toChars()); | 334 Logger::print("ClassDeclaration::toObjFile(%d): %s\n", fdi++, toChars()); |
340 LOG_SCOPE; | 335 LOG_SCOPE; |
341 | 336 |
342 gIR->structs.push_back(IRStruct(ts)); | 337 gIR->structs.push_back(IRStruct(ts)); |
343 gIR->classes.push_back(this); | 338 gIR->classes.push_back(this); |
344 gIR->classmethods.push_back(IRState::FuncDeclVec()); | |
345 gIR->queueClassMethods.push_back(true); | |
346 | 339 |
347 // add vtable | 340 // add vtable |
348 llvm::PATypeHolder pa = llvm::OpaqueType::get(); | 341 llvm::PATypeHolder pa = llvm::OpaqueType::get(); |
349 const llvm::Type* vtabty = llvm::PointerType::get(pa); | 342 const llvm::Type* vtabty = llvm::PointerType::get(pa); |
350 gIR->topstruct().fields.push_back(vtabty); | 343 gIR->topstruct().fields.push_back(vtabty); |
457 if (define_vtable) { | 450 if (define_vtable) { |
458 initvar->setInitializer(_init); | 451 initvar->setInitializer(_init); |
459 } | 452 } |
460 | 453 |
461 // generate member function definitions | 454 // generate member function definitions |
462 gIR->queueClassMethods.back() = false; | 455 gIR->topstruct().queueFuncs = false; |
463 IRState::FuncDeclVec& mfs = gIR->classmethods.back(); | 456 IRState::FuncDeclVec& mfs = gIR->topstruct().funcs; |
464 size_t n = mfs.size(); | 457 size_t n = mfs.size(); |
465 for (size_t i=0; i<n; ++i) { | 458 for (size_t i=0; i<n; ++i) { |
466 mfs[i]->toObjFile(); | 459 mfs[i]->toObjFile(); |
467 } | 460 } |
468 | 461 |
469 gIR->queueClassMethods.pop_back(); | |
470 gIR->classmethods.pop_back(); | |
471 gIR->classes.pop_back(); | 462 gIR->classes.pop_back(); |
472 gIR->structs.pop_back(); | 463 gIR->structs.pop_back(); |
473 | 464 |
474 llvmInProgress = false; | 465 llvmInProgress = false; |
475 } | 466 } |
642 return; | 633 return; |
643 } | 634 } |
644 | 635 |
645 llvm::Function* func = LLVM_DtoDeclareFunction(this); | 636 llvm::Function* func = LLVM_DtoDeclareFunction(this); |
646 | 637 |
647 if (!gIR->queueClassMethods.empty() && gIR->queueClassMethods.back()) { | 638 if (!gIR->structs.empty() && gIR->topstruct().queueFuncs) { |
648 if (!llvmQueued) { | 639 if (!llvmQueued) { |
649 Logger::println("queueing %s", toChars()); | 640 Logger::println("queueing %s", toChars()); |
650 assert(!gIR->classmethods.empty()); | 641 gIR->topstruct().funcs.push_back(this); |
651 gIR->classmethods.back().push_back(this); | |
652 llvmQueued = true; | 642 llvmQueued = true; |
653 } | 643 } |
654 return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete | 644 return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete |
655 } | 645 } |
656 | 646 |
696 { | 686 { |
697 gIR->funcdecls.push_back(this); | 687 gIR->funcdecls.push_back(this); |
698 | 688 |
699 // first make absolutely sure the type is up to date | 689 // first make absolutely sure the type is up to date |
700 f->llvmType = llvmValue->getType()->getContainedType(0); | 690 f->llvmType = llvmValue->getType()->getContainedType(0); |
691 | |
692 Logger::cout() << "func type: " << *f->llvmType << '\n'; | |
701 | 693 |
702 // this handling | 694 // this handling |
703 if (f->llvmUsesThis) { | 695 if (f->llvmUsesThis) { |
704 if (f->llvmRetInPtr) | 696 if (f->llvmRetInPtr) |
705 llvmThisVar = ++func->arg_begin(); | 697 llvmThisVar = ++func->arg_begin(); |