Mercurial > projects > ldc
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 } |