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