Mercurial > projects > ldc
comparison gen/typinf.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 | 182b41f56b7f |
comparison
equal
deleted
inserted
replaced
101:169fda3a77d4 | 102:027b8d8b71ec |
---|---|
5 // written by Walter Bright | 5 // written by Walter Bright |
6 // www.digitalmars.com | 6 // www.digitalmars.com |
7 // License for redistribution is by either the Artistic License | 7 // License for redistribution is by either the Artistic License |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | 8 // in artistic.txt, or the GNU General Public License in gnu.txt. |
9 // See the included readme.txt for details. | 9 // See the included readme.txt for details. |
10 | |
11 // Modifications for LLVMDC: | |
12 // Copyright (c) 2007 by Tomas Lindquist Olsen | |
13 // tomas at famolsen dk | |
10 | 14 |
11 #include <cstdio> | 15 #include <cstdio> |
12 #include <cassert> | 16 #include <cassert> |
13 | 17 |
14 #include "gen/llvm.h" | 18 #include "gen/llvm.h" |
236 // MAGIC PLACE | 240 // MAGIC PLACE |
237 ////////////////////////////////////////////////////////////////////////////// | 241 ////////////////////////////////////////////////////////////////////////////// |
238 | 242 |
239 void TypeInfoDeclaration::toObjFile() | 243 void TypeInfoDeclaration::toObjFile() |
240 { | 244 { |
241 if (llvmTouched) return; | 245 gIR->resolveList.push_back(this); |
242 else llvmTouched = true; | 246 } |
243 | 247 |
244 Logger::println("TypeInfoDeclaration::toObjFile()"); | 248 void DtoResolveTypeInfo(TypeInfoDeclaration* tid) |
245 LOG_SCOPE; | 249 { |
246 | 250 if (tid->llvmResolved) return; |
247 std::string mangled(mangle()); | 251 tid->llvmResolved = true; |
248 | 252 |
249 Logger::println("type = '%s'", tinfo->toChars()); | 253 Logger::println("* DtoResolveTypeInfo(%s)", tid->toChars()); |
254 LOG_SCOPE; | |
255 | |
256 tid->llvmIRGlobal = new IRGlobal(tid); | |
257 | |
258 gIR->declareList.push_back(tid); | |
259 } | |
260 | |
261 void DtoDeclareTypeInfo(TypeInfoDeclaration* tid) | |
262 { | |
263 if (tid->llvmDeclared) return; | |
264 tid->llvmDeclared = true; | |
265 | |
266 Logger::println("* DtoDeclareTypeInfo(%s)", tid->toChars()); | |
267 LOG_SCOPE; | |
268 | |
269 std::string mangled(tid->mangle()); | |
270 | |
271 Logger::println("type = '%s'", tid->tinfo->toChars()); | |
250 Logger::println("typeinfo mangle: %s", mangled.c_str()); | 272 Logger::println("typeinfo mangle: %s", mangled.c_str()); |
251 | 273 |
252 // this is a declaration of a builtin __initZ var | 274 // this is a declaration of a builtin __initZ var |
253 if (tinfo->builtinTypeInfo()) { | 275 if (tid->tinfo->builtinTypeInfo()) { |
254 llvmValue = LLVM_D_GetRuntimeGlobal(gIR->module, mangled.c_str()); | 276 tid->llvmValue = LLVM_D_GetRuntimeGlobal(gIR->module, mangled.c_str()); |
255 assert(llvmValue); | 277 assert(tid->llvmValue); |
256 mangled.append("__TYPE"); | 278 mangled.append("__TYPE"); |
257 gIR->module->addTypeName(mangled, llvmValue->getType()->getContainedType(0)); | 279 gIR->module->addTypeName(mangled, tid->llvmValue->getType()->getContainedType(0)); |
258 Logger::println("Got typeinfo var: %s", llvmValue->getName().c_str()); | 280 Logger::println("Got typeinfo var: %s", tid->llvmValue->getName().c_str()); |
281 tid->llvmInitialized = true; | |
282 tid->llvmDefined = true; | |
259 } | 283 } |
260 // custom typedef | 284 // custom typedef |
261 else { | 285 else { |
262 // emit globals | 286 gIR->constInitList.push_back(tid); |
263 toDt(NULL); | 287 } |
264 } | 288 } |
289 | |
290 void DtoConstInitTypeInfo(TypeInfoDeclaration* tid) | |
291 { | |
292 if (tid->llvmInitialized) return; | |
293 tid->llvmInitialized = true; | |
294 | |
295 Logger::println("* DtoConstInitTypeInfo(%s)", tid->toChars()); | |
296 LOG_SCOPE; | |
297 | |
298 tid->toDt(NULL); | |
299 | |
300 tid->llvmDefined = true; | |
301 //gIR->defineList.push_back(tid); | |
302 } | |
303 | |
304 void DtoDefineTypeInfo(TypeInfoDeclaration* tid) | |
305 { | |
306 if (tid->llvmDefined) return; | |
307 tid->llvmDefined = true; | |
308 | |
309 Logger::println("* DtoDefineTypeInfo(%s)", tid->toChars()); | |
310 LOG_SCOPE; | |
311 | |
312 assert(0); | |
265 } | 313 } |
266 | 314 |
267 /* ========================================================================= */ | 315 /* ========================================================================= */ |
268 | 316 |
269 void TypeInfoDeclaration::toDt(dt_t **pdt) | 317 void TypeInfoDeclaration::toDt(dt_t **pdt) |
277 { | 325 { |
278 Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars()); | 326 Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars()); |
279 LOG_SCOPE; | 327 LOG_SCOPE; |
280 | 328 |
281 ClassDeclaration* base = Type::typeinfotypedef; | 329 ClassDeclaration* base = Type::typeinfotypedef; |
282 base->toObjFile(); | 330 DtoForceConstInitDsymbol(base); |
283 | 331 |
284 const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); | 332 const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); |
333 Logger::cout() << "got stype: " << *stype << '\n'; | |
285 | 334 |
286 std::vector<llvm::Constant*> sinits; | 335 std::vector<llvm::Constant*> sinits; |
287 sinits.push_back(base->llvmVtbl); | 336 sinits.push_back(base->llvmVtbl); |
288 | 337 |
289 assert(tinfo->ty == Ttypedef); | 338 assert(tinfo->ty == Ttypedef); |
293 // TypeInfo base | 342 // TypeInfo base |
294 //const llvm::PointerType* basept = isaPointer(initZ->getOperand(1)->getType()); | 343 //const llvm::PointerType* basept = isaPointer(initZ->getOperand(1)->getType()); |
295 //sinits.push_back(llvm::ConstantPointerNull::get(basept)); | 344 //sinits.push_back(llvm::ConstantPointerNull::get(basept)); |
296 Logger::println("generating base typeinfo"); | 345 Logger::println("generating base typeinfo"); |
297 //sd->basetype = sd->basetype->merge(); | 346 //sd->basetype = sd->basetype->merge(); |
347 | |
298 sd->basetype->getTypeInfo(NULL); // generate vtinfo | 348 sd->basetype->getTypeInfo(NULL); // generate vtinfo |
299 assert(sd->basetype->vtinfo); | 349 assert(sd->basetype->vtinfo); |
300 if (!sd->basetype->vtinfo->llvmValue) | 350 if (!sd->basetype->vtinfo->llvmValue) |
301 sd->basetype->vtinfo->toObjFile(); | 351 DtoForceConstInitDsymbol(sd->basetype->vtinfo); |
352 | |
353 assert(sd->basetype->vtinfo->llvmValue); | |
302 assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->llvmValue)); | 354 assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->llvmValue)); |
303 llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->basetype->vtinfo->llvmValue); | 355 llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->basetype->vtinfo->llvmValue); |
304 castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(1)); | 356 castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(1)); |
305 sinits.push_back(castbase); | 357 sinits.push_back(castbase); |
306 | 358 |
339 { | 391 { |
340 Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars()); | 392 Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars()); |
341 LOG_SCOPE; | 393 LOG_SCOPE; |
342 | 394 |
343 ClassDeclaration* base = Type::typeinfoenum; | 395 ClassDeclaration* base = Type::typeinfoenum; |
344 base->toObjFile(); | 396 DtoForceConstInitDsymbol(base); |
345 | 397 |
346 const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); | 398 const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); |
347 | 399 |
348 std::vector<llvm::Constant*> sinits; | 400 std::vector<llvm::Constant*> sinits; |
349 sinits.push_back(base->llvmVtbl); | 401 sinits.push_back(base->llvmVtbl); |
355 // TypeInfo base | 407 // TypeInfo base |
356 //const llvm::PointerType* basept = isaPointer(initZ->getOperand(1)->getType()); | 408 //const llvm::PointerType* basept = isaPointer(initZ->getOperand(1)->getType()); |
357 //sinits.push_back(llvm::ConstantPointerNull::get(basept)); | 409 //sinits.push_back(llvm::ConstantPointerNull::get(basept)); |
358 Logger::println("generating base typeinfo"); | 410 Logger::println("generating base typeinfo"); |
359 //sd->basetype = sd->basetype->merge(); | 411 //sd->basetype = sd->basetype->merge(); |
412 | |
360 sd->memtype->getTypeInfo(NULL); // generate vtinfo | 413 sd->memtype->getTypeInfo(NULL); // generate vtinfo |
361 assert(sd->memtype->vtinfo); | 414 assert(sd->memtype->vtinfo); |
362 if (!sd->memtype->vtinfo->llvmValue) | 415 if (!sd->memtype->vtinfo->llvmValue) |
363 sd->memtype->vtinfo->toObjFile(); | 416 DtoForceConstInitDsymbol(sd->memtype->vtinfo); |
417 | |
364 assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->llvmValue)); | 418 assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->llvmValue)); |
365 llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->llvmValue); | 419 llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->llvmValue); |
366 castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(1)); | 420 castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(1)); |
367 sinits.push_back(castbase); | 421 sinits.push_back(castbase); |
368 | 422 |
399 /* ========================================================================= */ | 453 /* ========================================================================= */ |
400 | 454 |
401 static llvm::Constant* LLVM_D_Create_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd) | 455 static llvm::Constant* LLVM_D_Create_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd) |
402 { | 456 { |
403 ClassDeclaration* base = cd; | 457 ClassDeclaration* base = cd; |
404 base->toObjFile(); | 458 DtoForceConstInitDsymbol(base); |
405 | 459 |
406 const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); | 460 const llvm::StructType* stype = isaStruct(base->type->llvmType->get()); |
407 | 461 |
408 std::vector<llvm::Constant*> sinits; | 462 std::vector<llvm::Constant*> sinits; |
409 sinits.push_back(base->llvmVtbl); | 463 sinits.push_back(base->llvmVtbl); |
411 // TypeInfo base | 465 // TypeInfo base |
412 Logger::println("generating base typeinfo"); | 466 Logger::println("generating base typeinfo"); |
413 basetype->getTypeInfo(NULL); | 467 basetype->getTypeInfo(NULL); |
414 assert(basetype->vtinfo); | 468 assert(basetype->vtinfo); |
415 if (!basetype->vtinfo->llvmValue) | 469 if (!basetype->vtinfo->llvmValue) |
416 basetype->vtinfo->toObjFile(); | 470 DtoForceConstInitDsymbol(basetype->vtinfo); |
417 assert(llvm::isa<llvm::Constant>(basetype->vtinfo->llvmValue)); | 471 assert(llvm::isa<llvm::Constant>(basetype->vtinfo->llvmValue)); |
418 llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->llvmValue); | 472 llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->llvmValue); |
419 castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(1)); | 473 castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(1)); |
420 sinits.push_back(castbase); | 474 sinits.push_back(castbase); |
421 | 475 |
531 LOG_SCOPE; | 585 LOG_SCOPE; |
532 | 586 |
533 assert(tinfo->ty == Tstruct); | 587 assert(tinfo->ty == Tstruct); |
534 TypeStruct *tc = (TypeStruct *)tinfo; | 588 TypeStruct *tc = (TypeStruct *)tinfo; |
535 StructDeclaration *sd = tc->sym; | 589 StructDeclaration *sd = tc->sym; |
536 sd->toObjFile(); | 590 DtoForceConstInitDsymbol(sd); |
537 DtoConstInitStruct(sd); | |
538 | 591 |
539 ClassDeclaration* base = Type::typeinfostruct; | 592 ClassDeclaration* base = Type::typeinfostruct; |
540 base->toObjFile(); | 593 DtoForceConstInitDsymbol(base); |
541 | 594 |
542 const llvm::StructType* stype = isaStruct(((TypeClass*)base->type)->llvmType->get()); | 595 const llvm::StructType* stype = isaStruct(((TypeClass*)base->type)->llvmType->get()); |
543 | 596 |
544 std::vector<llvm::Constant*> sinits; | 597 std::vector<llvm::Constant*> sinits; |
545 sinits.push_back(base->llvmVtbl); | 598 sinits.push_back(base->llvmVtbl); |