comparison gen/toobj.c @ 6:35d93ce68cf4 trunk

[svn r10] Updated for LLVM rev. 20070913 Applied fixes from wilsonk on the forum Some tweaks to work with gc 7.0 Fixed aggregate members of aggregates Fixed cyclic/recursive class declarations Other minor tweaks
author lindquist
date Wed, 26 Sep 2007 19:05:18 +0200
parents e116aa1488e6
children 5e69b77a5c51
comparison
equal deleted inserted replaced
5:3d60e549b0c2 6:35d93ce68cf4
46 Module::genobjfile() 46 Module::genobjfile()
47 { 47 {
48 Logger::cout() << "Generating module: " << (md ? md->toChars() : toChars()) << '\n'; 48 Logger::cout() << "Generating module: " << (md ? md->toChars() : toChars()) << '\n';
49 LOG_SCOPE; 49 LOG_SCOPE;
50 50
51 // start by deleting the old object file
51 deleteObjFile(); 52 deleteObjFile();
52 53
54 // creaet a new ir state
53 IRState ir; 55 IRState ir;
54 gIR = &ir; 56 gIR = &ir;
55
56 ir.dmodule = this; 57 ir.dmodule = this;
57 58
59 // name the module
58 std::string mname(toChars()); 60 std::string mname(toChars());
59 if (md != 0) 61 if (md != 0)
60 mname = md->toChars(); 62 mname = md->toChars();
61 ir.module = new llvm::Module(mname); 63 ir.module = new llvm::Module(mname);
62 64
65 // set target stuff
63 std::string target_triple(global.params.tt_arch); 66 std::string target_triple(global.params.tt_arch);
64 target_triple.append(global.params.tt_os); 67 target_triple.append(global.params.tt_os);
65 ir.module->setTargetTriple(target_triple); 68 ir.module->setTargetTriple(target_triple);
66 ir.module->setDataLayout(global.params.data_layout); 69 ir.module->setDataLayout(global.params.data_layout);
67 70
68 gTargetData = new llvm::TargetData(ir.module); 71 gTargetData = new llvm::TargetData(ir.module);
69 72
73 // process module members
70 for (int k=0; k < members->dim; k++) { 74 for (int k=0; k < members->dim; k++) {
71 Dsymbol* dsym = (Dsymbol*)(members->data[k]); 75 Dsymbol* dsym = (Dsymbol*)(members->data[k]);
72 assert(dsym); 76 assert(dsym);
73 dsym->toObjFile(); 77 dsym->toObjFile();
74 } 78 }
75 79
76 delete gTargetData; 80 delete gTargetData;
77 gTargetData = 0; 81 gTargetData = 0;
78 82
83 // verify the llvm
79 std::string verifyErr; 84 std::string verifyErr;
80 if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr)) 85 if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr))
81 { 86 {
82 error("%s", verifyErr.c_str()); 87 error("%s", verifyErr.c_str());
83 fatal(); 88 fatal();
84 } 89 }
85 90
91 // emit the llvm main function if necessary
86 if (ir.emitMain) { 92 if (ir.emitMain) {
87 LLVM_DtoMain(); 93 LLVM_DtoMain();
88 } 94 }
89 95
90 // run passes 96 // run passes
95 std::ofstream os(llfile->name->toChars()); 101 std::ofstream os(llfile->name->toChars());
96 //llvm::WriteAssemblyToFile(ir.module, os); 102 //llvm::WriteAssemblyToFile(ir.module, os);
97 ir.module->print(os); 103 ir.module->print(os);
98 }*/ 104 }*/
99 105
106 // write bytecode
100 //if (global.params.llvmBC) { 107 //if (global.params.llvmBC) {
101 Logger::println("Writing LLVM bitcode\n"); 108 Logger::println("Writing LLVM bitcode\n");
102 std::ofstream os(bcfile->name->toChars(), std::ios::binary); 109 std::ofstream os(bcfile->name->toChars(), std::ios::binary);
103 llvm::WriteBitcodeToFile(ir.module, os); 110 llvm::WriteBitcodeToFile(ir.module, os);
104 //} 111 //}
129 warning("Ignoring Declaration::toObjFile for %s", toChars()); 136 warning("Ignoring Declaration::toObjFile for %s", toChars());
130 } 137 }
131 138
132 /* ================================================================== */ 139 /* ================================================================== */
133 140
141 /// Returns the LLVM style index from a DMD style offset
134 unsigned AggregateDeclaration::offsetToIndex(unsigned os) 142 unsigned AggregateDeclaration::offsetToIndex(unsigned os)
135 { 143 {
136 for (unsigned i=0; i<fields.dim; ++i) { 144 for (unsigned i=0; i<fields.dim; ++i) {
137 VarDeclaration* vd = (VarDeclaration*)fields.data[i]; 145 VarDeclaration* vd = (VarDeclaration*)fields.data[i];
138 if (os == vd->offset) 146 if (os == vd->offset)
163 idx += i; 171 idx += i;
164 172
165 return (unsigned)-1; 173 return (unsigned)-1;
166 } 174 }
167 175
176 /// Returns the LLVM style index from a DMD style offset
177 /// Handles class inheritance
168 unsigned ClassDeclaration::offsetToIndex(unsigned os) 178 unsigned ClassDeclaration::offsetToIndex(unsigned os)
169 { 179 {
170 unsigned idx = 0; 180 unsigned idx = 0;
171 unsigned r = LLVM_ClassOffsetToIndex(this, os, idx); 181 unsigned r = LLVM_ClassOffsetToIndex(this, os, idx);
172 assert(r != (unsigned)-1 && "Offset not found in any aggregate field"); 182 assert(r != (unsigned)-1 && "Offset not found in any aggregate field");
306 316
307 static int fdi = 0; 317 static int fdi = 0;
308 Logger::print("ClassDeclaration::toObjFile(%d): %s\n", fdi++, toChars()); 318 Logger::print("ClassDeclaration::toObjFile(%d): %s\n", fdi++, toChars());
309 LOG_SCOPE; 319 LOG_SCOPE;
310 320
311 gIR->structs.push_back(IRStruct()); 321 gIR->structs.push_back(IRStruct(ts));
312 gIR->classes.push_back(this); 322 gIR->classes.push_back(this);
313 gIR->classmethods.push_back(IRState::FuncDeclVec()); 323 gIR->classmethods.push_back(IRState::FuncDeclVec());
314 gIR->queueClassMethods.push_back(true); 324 gIR->queueClassMethods.push_back(true);
315 325
316 // add vtable 326 // add vtable
326 Dsymbol* dsym = (Dsymbol*)(members->data[k]); 336 Dsymbol* dsym = (Dsymbol*)(members->data[k]);
327 dsym->toObjFile(); 337 dsym->toObjFile();
328 } 338 }
329 339
330 llvm::StructType* structtype = llvm::StructType::get(gIR->topstruct().fields); 340 llvm::StructType* structtype = llvm::StructType::get(gIR->topstruct().fields);
341 // refine abstract types for stuff like: class C {C next;}
342 if (gIR->topstruct().recty != 0)
343 {
344 llvm::PATypeHolder& pa = gIR->topstruct().recty;
345 llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(structtype);
346 structtype = llvm::cast<llvm::StructType>(pa.get());
347 }
348
331 ts->llvmType = structtype; 349 ts->llvmType = structtype;
332 llvmType = structtype; 350 llvmType = structtype;
333 351
334 bool emit_vtable = false; 352 bool emit_vtable = false;
335 bool define_vtable = false; 353 bool define_vtable = false;
525 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(_type); 543 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(_type);
526 uint64_t n = arrty->getNumElements(); 544 uint64_t n = arrty->getNumElements();
527 std::vector<llvm::Constant*> vals(n,_init); 545 std::vector<llvm::Constant*> vals(n,_init);
528 _init = llvm::ConstantArray::get(arrty, vals); 546 _init = llvm::ConstantArray::get(arrty, vals);
529 } 547 }
548 else if (llvm::isa<llvm::StructType>(_type)) {
549 const llvm::StructType* structty = llvm::cast<llvm::StructType>(_type);
550 TypeStruct* ts = (TypeStruct*)type;
551 assert(ts->sym->llvmInitZ);
552 _init = ts->sym->llvmInitZ;
553 }
530 else 554 else
531 assert(0); 555 assert(0);
532 } 556 }
533 gIR->topstruct().inits.push_back(_init); 557 gIR->topstruct().inits.push_back(_init);
534 } 558 }