Mercurial > projects > ldc
comparison gen/typinf.cpp @ 1374:e630ff79e10d
Cleaned up TypeInfo generation, still need to do TypeInfo_Struct/Tuple. Eventually do ClassInfo and ModuleInfo as well using same interface.
author | Tomas Lindquist Olsen <tomas.l.olsen gmail com> |
---|---|
date | Sun, 17 May 2009 03:10:55 +0200 |
parents | 8026319762be |
children | 63f4afd01036 |
comparison
equal
deleted
inserted
replaced
1373:551b01341728 | 1374:e630ff79e10d |
---|---|
39 #include "gen/arrays.h" | 39 #include "gen/arrays.h" |
40 #include "gen/structs.h" | 40 #include "gen/structs.h" |
41 #include "gen/classes.h" | 41 #include "gen/classes.h" |
42 #include "gen/linkage.h" | 42 #include "gen/linkage.h" |
43 #include "gen/metadata.h" | 43 #include "gen/metadata.h" |
44 #include "gen/rttibuilder.h" | |
44 | 45 |
45 #include "ir/irvar.h" | 46 #include "ir/irvar.h" |
46 #include "ir/irtype.h" | 47 #include "ir/irtype.h" |
47 | 48 |
48 /******************************************* | 49 /******************************************* |
269 | 270 |
270 /* ========================================================================= */ | 271 /* ========================================================================= */ |
271 | 272 |
272 ////////////////////////////////////////////////////////////////////////////// | 273 ////////////////////////////////////////////////////////////////////////////// |
273 // MAGIC PLACE | 274 // MAGIC PLACE |
275 // (wut?) | |
274 ////////////////////////////////////////////////////////////////////////////// | 276 ////////////////////////////////////////////////////////////////////////////// |
275 | 277 |
276 void DtoResolveTypeInfo(TypeInfoDeclaration* tid); | 278 void DtoResolveTypeInfo(TypeInfoDeclaration* tid); |
277 void DtoDeclareTypeInfo(TypeInfoDeclaration* tid); | 279 void DtoDeclareTypeInfo(TypeInfoDeclaration* tid); |
278 void DtoConstInitTypeInfo(TypeInfoDeclaration* tid); | |
279 | 280 |
280 void TypeInfoDeclaration::codegen(Ir*) | 281 void TypeInfoDeclaration::codegen(Ir*) |
281 { | 282 { |
282 DtoResolveTypeInfo(this); | 283 DtoResolveTypeInfo(this); |
283 } | 284 } |
332 tid->ir.declared = true; | 333 tid->ir.declared = true; |
333 | 334 |
334 Logger::println("DtoDeclareTypeInfo(%s)", tid->toChars()); | 335 Logger::println("DtoDeclareTypeInfo(%s)", tid->toChars()); |
335 LOG_SCOPE; | 336 LOG_SCOPE; |
336 | 337 |
338 if (Logger::enabled()) | |
339 { | |
340 std::string mangled(tid->mangle()); | |
341 Logger::println("type = '%s'", tid->tinfo->toChars()); | |
342 Logger::println("typeinfo mangle: %s", mangled.c_str()); | |
343 } | |
344 | |
337 IrGlobal* irg = tid->ir.irGlobal; | 345 IrGlobal* irg = tid->ir.irGlobal; |
338 | |
339 std::string mangled(tid->mangle()); | |
340 | |
341 Logger::println("type = '%s'", tid->tinfo->toChars()); | |
342 Logger::println("typeinfo mangle: %s", mangled.c_str()); | |
343 | |
344 assert(irg->value != NULL); | 346 assert(irg->value != NULL); |
345 | 347 |
346 // this is a declaration of a builtin __initZ var | 348 // this is a declaration of a builtin __initZ var |
347 if (tid->tinfo->builtinTypeInfo()) { | 349 if (tid->tinfo->builtinTypeInfo()) { |
348 // fixup the global | 350 // fixup the global |
349 const llvm::Type* rty = Type::typeinfo->type->irtype->getPA().get(); | 351 const llvm::Type* rty = Type::typeinfo->type->irtype->getPA(); |
350 llvm::cast<llvm::OpaqueType>(irg->type.get())->refineAbstractTypeTo(rty); | 352 llvm::cast<llvm::OpaqueType>(irg->type.get())->refineAbstractTypeTo(rty); |
351 LLGlobalVariable* g = isaGlobalVar(irg->value); | 353 LLGlobalVariable* g = isaGlobalVar(irg->value); |
352 g->setLinkage(llvm::GlobalValue::ExternalLinkage); | 354 g->setLinkage(llvm::GlobalValue::ExternalLinkage); |
353 return; | 355 return; |
354 } | 356 } |
355 | 357 |
356 // custom typedef | 358 // define custom typedef |
357 DtoConstInitTypeInfo(tid); | |
358 } | |
359 | |
360 void DtoConstInitTypeInfo(TypeInfoDeclaration* tid) | |
361 { | |
362 if (tid->ir.initialized) return; | |
363 tid->ir.initialized = true; | |
364 | |
365 Logger::println("DtoConstInitTypeInfo(%s)", tid->toChars()); | |
366 LOG_SCOPE; | |
367 | |
368 tid->llvmDefine(); | 359 tid->llvmDefine(); |
369 } | 360 } |
370 | 361 |
371 /* ========================================================================= */ | 362 /* ========================================================================= */ |
372 | 363 |
373 void TypeInfoDeclaration::llvmDefine() | 364 void TypeInfoDeclaration::llvmDefine() |
374 { | 365 { |
375 assert(0 && "TypeInfoDeclaration::llvmDeclare"); | 366 assert(0 && "cannot generate generic typeinfo"); |
376 } | 367 } |
377 | 368 |
378 /* ========================================================================= */ | 369 /* ========================================================================= */ |
379 | 370 |
380 void TypeInfoTypedefDeclaration::llvmDefine() | 371 void TypeInfoTypedefDeclaration::llvmDefine() |
381 { | 372 { |
382 Logger::println("TypeInfoTypedefDeclaration::llvmDefine() %s", toChars()); | 373 Logger::println("TypeInfoTypedefDeclaration::llvmDefine() %s", toChars()); |
383 LOG_SCOPE; | 374 LOG_SCOPE; |
384 | 375 |
385 ClassDeclaration* base = Type::typeinfotypedef; | 376 TypeInfoBuilder b(Type::typeinfotypedef); |
386 base->codegen(Type::sir); | |
387 | |
388 // vtbl | |
389 std::vector<LLConstant*> sinits; | |
390 sinits.push_back(base->ir.irStruct->getVtblSymbol()); | |
391 | |
392 // monitor | |
393 sinits.push_back(getNullPtr(getPtrToType(LLType::Int8Ty))); | |
394 | 377 |
395 assert(tinfo->ty == Ttypedef); | 378 assert(tinfo->ty == Ttypedef); |
396 TypeTypedef *tc = (TypeTypedef *)tinfo; | 379 TypeTypedef *tc = (TypeTypedef *)tinfo; |
397 TypedefDeclaration *sd = tc->sym; | 380 TypedefDeclaration *sd = tc->sym; |
398 | 381 |
399 // TypeInfo base | 382 // TypeInfo base |
400 sd->basetype = sd->basetype->merge(); // DMD does this! | 383 sd->basetype = sd->basetype->merge(); // dmd does it ... why? |
401 LLConstant* castbase = DtoTypeInfoOf(sd->basetype, true); | 384 b.push_typeinfo(sd->basetype); |
402 sinits.push_back(castbase); | |
403 | 385 |
404 // char[] name | 386 // char[] name |
405 char *name = sd->toPrettyChars(); | 387 b.push_string(sd->toPrettyChars()); |
406 sinits.push_back(DtoConstString(name)); | |
407 | 388 |
408 // void[] init | 389 // void[] init |
409 const LLPointerType* initpt = getPtrToType(LLType::Int8Ty); | 390 // emit null array if we should use the basetype, or if the basetype |
410 if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type | 391 // uses default initialization. |
411 { | 392 if (!sd->init || tinfo->isZeroInit(0)) |
412 sinits.push_back(DtoConstSlice(DtoConstSize_t(0), getNullPtr(initpt))); | 393 { |
413 } | 394 b.push_null_void_array(); |
395 } | |
396 // otherwise emit a void[] with the default initializer | |
414 else | 397 else |
415 { | 398 { |
416 LLConstant* ci = DtoConstInitializer(sd->loc, sd->basetype, sd->init); | 399 LLConstant* C = DtoConstInitializer(sd->loc, sd->basetype, sd->init); |
417 std::string ciname(sd->mangle()); | 400 b.push_void_array(C, sd->basetype, sd); |
418 ciname.append("__init"); | 401 } |
419 llvm::GlobalVariable* civar = new llvm::GlobalVariable(DtoType(sd->basetype),true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module); | 402 |
420 LLConstant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt); | 403 // finish |
421 size_t cisize = getTypeStoreSize(DtoType(sd->basetype)); | 404 b.finalize(ir.irGlobal); |
422 sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast)); | |
423 } | |
424 | |
425 // create the inititalizer | |
426 LLConstant* tiInit = llvm::ConstantStruct::get(sinits); | |
427 | |
428 // refine global type | |
429 llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); | |
430 | |
431 // set the initializer | |
432 isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); | |
433 } | 405 } |
434 | 406 |
435 /* ========================================================================= */ | 407 /* ========================================================================= */ |
436 | 408 |
437 void TypeInfoEnumDeclaration::llvmDefine() | 409 void TypeInfoEnumDeclaration::llvmDefine() |
438 { | 410 { |
439 Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s", toChars()); | 411 Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s", toChars()); |
440 LOG_SCOPE; | 412 LOG_SCOPE; |
441 | 413 |
442 ClassDeclaration* base = Type::typeinfoenum; | 414 TypeInfoBuilder b(Type::typeinfoenum); |
443 base->codegen(Type::sir); | |
444 | |
445 // vtbl | |
446 std::vector<LLConstant*> sinits; | |
447 sinits.push_back(base->ir.irStruct->getVtblSymbol()); | |
448 | |
449 // monitor | |
450 sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); | |
451 | 415 |
452 assert(tinfo->ty == Tenum); | 416 assert(tinfo->ty == Tenum); |
453 TypeEnum *tc = (TypeEnum *)tinfo; | 417 TypeEnum *tc = (TypeEnum *)tinfo; |
454 EnumDeclaration *sd = tc->sym; | 418 EnumDeclaration *sd = tc->sym; |
455 | 419 |
456 // TypeInfo base | 420 // TypeInfo base |
457 LLConstant* castbase = DtoTypeInfoOf(sd->memtype, true); | 421 b.push_typeinfo(sd->memtype); |
458 sinits.push_back(castbase); | |
459 | 422 |
460 // char[] name | 423 // char[] name |
461 char *name = sd->toPrettyChars(); | 424 b.push_string(sd->toPrettyChars()); |
462 sinits.push_back(DtoConstString(name)); | |
463 | 425 |
464 // void[] init | 426 // void[] init |
465 const LLPointerType* initpt = getPtrToType(LLType::Int8Ty); | 427 // emit void[] with the default initialier, the array is null if the default |
466 if (tinfo->isZeroInit() || !sd->defaultval) // 0 initializer, or the same as the base type | 428 // initializer is zero |
467 { | 429 if (!sd->defaultval || tinfo->isZeroInit(0)) |
468 sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt))); | 430 { |
469 } | 431 b.push_null_void_array(); |
432 } | |
433 // otherwise emit a void[] with the default initializer | |
470 else | 434 else |
471 { | 435 { |
472 #if DMDV2 | |
473 assert(0 && "initializer not implemented"); | |
474 #else | |
475 const LLType* memty = DtoType(sd->memtype); | 436 const LLType* memty = DtoType(sd->memtype); |
476 LLConstant* ci = llvm::ConstantInt::get(memty, sd->defaultval, !sd->memtype->isunsigned()); | 437 LLConstant* C = llvm::ConstantInt::get(memty, sd->defaultval, !sd->memtype->isunsigned()); |
477 std::string ciname(sd->mangle()); | 438 b.push_void_array(C, sd->memtype, sd); |
478 ciname.append("__init"); | 439 } |
479 llvm::GlobalVariable* civar = new llvm::GlobalVariable(memty,true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module); | 440 |
480 LLConstant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt); | 441 // finish |
481 size_t cisize = getTypeStoreSize(memty); | 442 b.finalize(ir.irGlobal); |
482 sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast)); | |
483 #endif | |
484 } | |
485 | |
486 // create the inititalizer | |
487 LLConstant* tiInit = llvm::ConstantStruct::get(sinits); | |
488 | |
489 // refine global type | |
490 llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); | |
491 | |
492 // set the initializer | |
493 isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); | |
494 } | |
495 | |
496 /* ========================================================================= */ | |
497 | |
498 static void LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd) | |
499 { | |
500 ClassDeclaration* base = cd; | |
501 base->codegen(Type::sir); | |
502 | |
503 // vtbl | |
504 std::vector<LLConstant*> sinits; | |
505 sinits.push_back(base->ir.irStruct->getVtblSymbol()); | |
506 | |
507 // monitor | |
508 sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); | |
509 | |
510 // TypeInfo base | |
511 LLConstant* castbase = DtoTypeInfoOf(basetype, true); | |
512 sinits.push_back(castbase); | |
513 | |
514 // create the inititalizer | |
515 LLConstant* tiInit = llvm::ConstantStruct::get(sinits); | |
516 | |
517 // refine global type | |
518 llvm::cast<llvm::OpaqueType>(tid->ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); | |
519 | |
520 // set the initializer | |
521 isaGlobalVar(tid->ir.irGlobal->value)->setInitializer(tiInit); | |
522 } | 443 } |
523 | 444 |
524 /* ========================================================================= */ | 445 /* ========================================================================= */ |
525 | 446 |
526 void TypeInfoPointerDeclaration::llvmDefine() | 447 void TypeInfoPointerDeclaration::llvmDefine() |
527 { | 448 { |
528 Logger::println("TypeInfoPointerDeclaration::llvmDefine() %s", toChars()); | 449 Logger::println("TypeInfoPointerDeclaration::llvmDefine() %s", toChars()); |
529 LOG_SCOPE; | 450 LOG_SCOPE; |
530 | 451 |
531 assert(tinfo->ty == Tpointer); | 452 TypeInfoBuilder b(Type::typeinfopointer); |
532 TypePointer *tc = (TypePointer *)tinfo; | 453 // TypeInfo base |
533 | 454 b.push_typeinfo(tinfo->nextOf()); |
534 LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfopointer); | 455 // finish |
456 b.finalize(ir.irGlobal); | |
535 } | 457 } |
536 | 458 |
537 /* ========================================================================= */ | 459 /* ========================================================================= */ |
538 | 460 |
539 void TypeInfoArrayDeclaration::llvmDefine() | 461 void TypeInfoArrayDeclaration::llvmDefine() |
540 { | 462 { |
541 Logger::println("TypeInfoArrayDeclaration::llvmDefine() %s", toChars()); | 463 Logger::println("TypeInfoArrayDeclaration::llvmDefine() %s", toChars()); |
542 LOG_SCOPE; | 464 LOG_SCOPE; |
543 | 465 |
544 assert(tinfo->ty == Tarray); | 466 TypeInfoBuilder b(Type::typeinfoarray); |
545 TypeDArray *tc = (TypeDArray *)tinfo; | 467 // TypeInfo base |
546 | 468 b.push_typeinfo(tinfo->nextOf()); |
547 LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfoarray); | 469 // finish |
470 b.finalize(ir.irGlobal); | |
548 } | 471 } |
549 | 472 |
550 /* ========================================================================= */ | 473 /* ========================================================================= */ |
551 | 474 |
552 void TypeInfoStaticArrayDeclaration::llvmDefine() | 475 void TypeInfoStaticArrayDeclaration::llvmDefine() |
553 { | 476 { |
554 Logger::println("TypeInfoStaticArrayDeclaration::llvmDefine() %s", toChars()); | 477 Logger::println("TypeInfoStaticArrayDeclaration::llvmDefine() %s", toChars()); |
555 LOG_SCOPE; | 478 LOG_SCOPE; |
556 | 479 |
557 // init typeinfo class | |
558 ClassDeclaration* base = Type::typeinfostaticarray; | |
559 base->codegen(Type::sir); | |
560 | |
561 // get type of typeinfo class | |
562 const LLStructType* stype = isaStruct(base->type->irtype->getPA().get()); | |
563 | |
564 // initializer vector | |
565 std::vector<LLConstant*> sinits; | |
566 // first is always the vtable | |
567 sinits.push_back(base->ir.irStruct->getVtblSymbol()); | |
568 | |
569 // monitor | |
570 sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); | |
571 | |
572 // value typeinfo | |
573 assert(tinfo->ty == Tsarray); | 480 assert(tinfo->ty == Tsarray); |
574 TypeSArray *tc = (TypeSArray *)tinfo; | 481 TypeSArray *tc = (TypeSArray *)tinfo; |
575 LLConstant* castbase = DtoTypeInfoOf(tc->next, true); | 482 |
576 assert(castbase->getType() == stype->getElementType(2)); | 483 TypeInfoBuilder b(Type::typeinfostaticarray); |
577 sinits.push_back(castbase); | 484 |
485 // value typeinfo | |
486 b.push_typeinfo(tc->nextOf()); | |
578 | 487 |
579 // length | 488 // length |
580 sinits.push_back(DtoConstSize_t(tc->dim->toInteger())); | 489 b.push(DtoConstSize_t((size_t)tc->dim->toUInteger())); |
581 | 490 |
582 // create the inititalizer | 491 // finish |
583 LLConstant* tiInit = llvm::ConstantStruct::get(sinits); | 492 b.finalize(ir.irGlobal); |
584 | |
585 // refine global type | |
586 llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); | |
587 | |
588 // set the initializer | |
589 isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); | |
590 } | 493 } |
591 | 494 |
592 /* ========================================================================= */ | 495 /* ========================================================================= */ |
593 | 496 |
594 void TypeInfoAssociativeArrayDeclaration::llvmDefine() | 497 void TypeInfoAssociativeArrayDeclaration::llvmDefine() |
595 { | 498 { |
596 Logger::println("TypeInfoAssociativeArrayDeclaration::llvmDefine() %s", toChars()); | 499 Logger::println("TypeInfoAssociativeArrayDeclaration::llvmDefine() %s", toChars()); |
597 LOG_SCOPE; | 500 LOG_SCOPE; |
598 | 501 |
599 // init typeinfo class | |
600 ClassDeclaration* base = Type::typeinfoassociativearray; | |
601 base->codegen(Type::sir); | |
602 | |
603 // initializer vector | |
604 std::vector<LLConstant*> sinits; | |
605 // first is always the vtable | |
606 sinits.push_back(base->ir.irStruct->getVtblSymbol()); | |
607 | |
608 // monitor | |
609 sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); | |
610 | |
611 // get type | |
612 assert(tinfo->ty == Taarray); | 502 assert(tinfo->ty == Taarray); |
613 TypeAArray *tc = (TypeAArray *)tinfo; | 503 TypeAArray *tc = (TypeAArray *)tinfo; |
614 | 504 |
505 TypeInfoBuilder b(Type::typeinfoassociativearray); | |
506 | |
615 // value typeinfo | 507 // value typeinfo |
616 LLConstant* castbase = DtoTypeInfoOf(tc->next, true); | 508 b.push_typeinfo(tc->nextOf()); |
617 sinits.push_back(castbase); | |
618 | 509 |
619 // key typeinfo | 510 // key typeinfo |
620 castbase = DtoTypeInfoOf(tc->index, true); | 511 b.push_typeinfo(tc->index); |
621 sinits.push_back(castbase); | 512 |
622 | 513 // finish |
623 // create the inititalizer | 514 b.finalize(ir.irGlobal); |
624 LLConstant* tiInit = llvm::ConstantStruct::get(sinits); | |
625 | |
626 // refine global type | |
627 llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); | |
628 | |
629 // set the initializer | |
630 isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); | |
631 } | 515 } |
632 | 516 |
633 /* ========================================================================= */ | 517 /* ========================================================================= */ |
634 | 518 |
635 void TypeInfoFunctionDeclaration::llvmDefine() | 519 void TypeInfoFunctionDeclaration::llvmDefine() |
636 { | 520 { |
637 Logger::println("TypeInfoFunctionDeclaration::llvmDefine() %s", toChars()); | 521 Logger::println("TypeInfoFunctionDeclaration::llvmDefine() %s", toChars()); |
638 LOG_SCOPE; | 522 LOG_SCOPE; |
639 | 523 |
640 assert(tinfo->ty == Tfunction); | 524 TypeInfoBuilder b(Type::typeinfofunction); |
641 TypeFunction *tc = (TypeFunction *)tinfo; | 525 // TypeInfo base |
642 | 526 b.push_typeinfo(tinfo->nextOf()); |
643 LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfofunction); | 527 // finish |
528 b.finalize(ir.irGlobal); | |
644 } | 529 } |
645 | 530 |
646 /* ========================================================================= */ | 531 /* ========================================================================= */ |
647 | 532 |
648 void TypeInfoDelegateDeclaration::llvmDefine() | 533 void TypeInfoDelegateDeclaration::llvmDefine() |
649 { | 534 { |
650 Logger::println("TypeInfoDelegateDeclaration::llvmDefine() %s", toChars()); | 535 Logger::println("TypeInfoDelegateDeclaration::llvmDefine() %s", toChars()); |
651 LOG_SCOPE; | 536 LOG_SCOPE; |
652 | 537 |
653 assert(tinfo->ty == Tdelegate); | 538 assert(tinfo->ty == Tdelegate); |
654 TypeDelegate *tc = (TypeDelegate *)tinfo; | 539 Type* ret_type = tinfo->nextOf()->nextOf(); |
655 | 540 |
656 LLVM_D_Define_TypeInfoBase(tc->nextOf()->nextOf(), this, Type::typeinfodelegate); | 541 TypeInfoBuilder b(Type::typeinfodelegate); |
542 // TypeInfo base | |
543 b.push_typeinfo(ret_type); | |
544 // finish | |
545 b.finalize(ir.irGlobal); | |
657 } | 546 } |
658 | 547 |
659 /* ========================================================================= */ | 548 /* ========================================================================= */ |
660 | 549 |
661 void TypeInfoStructDeclaration::llvmDefine() | 550 void TypeInfoStructDeclaration::llvmDefine() |
872 // make sure class is resolved | 761 // make sure class is resolved |
873 assert(tinfo->ty == Tclass); | 762 assert(tinfo->ty == Tclass); |
874 TypeClass *tc = (TypeClass *)tinfo; | 763 TypeClass *tc = (TypeClass *)tinfo; |
875 tc->sym->codegen(Type::sir); | 764 tc->sym->codegen(Type::sir); |
876 | 765 |
766 TypeInfoBuilder b(Type::typeinfoclass); | |
767 | |
768 // TypeInfo base | |
769 b.push_classinfo(tc->sym); | |
770 | |
771 // finish | |
772 b.finalize(ir.irGlobal); | |
773 } | |
774 | |
775 /* ========================================================================= */ | |
776 | |
777 void TypeInfoInterfaceDeclaration::llvmDefine() | |
778 { | |
779 Logger::println("TypeInfoInterfaceDeclaration::llvmDefine() %s", toChars()); | |
780 LOG_SCOPE; | |
781 | |
782 // make sure interface is resolved | |
783 assert(tinfo->ty == Tclass); | |
784 TypeClass *tc = (TypeClass *)tinfo; | |
785 tc->sym->codegen(Type::sir); | |
786 | |
787 TypeInfoBuilder b(Type::typeinfointerface); | |
788 | |
789 // TypeInfo base | |
790 b.push_classinfo(tc->sym); | |
791 | |
792 // finish | |
793 b.finalize(ir.irGlobal); | |
794 } | |
795 | |
796 /* ========================================================================= */ | |
797 | |
798 void TypeInfoTupleDeclaration::llvmDefine() | |
799 { | |
800 Logger::println("TypeInfoTupleDeclaration::llvmDefine() %s", toChars()); | |
801 LOG_SCOPE; | |
802 | |
877 // init typeinfo class | 803 // init typeinfo class |
878 ClassDeclaration* base = Type::typeinfoclass; | 804 ClassDeclaration* base = Type::typeinfotypelist; |
879 assert(base); | 805 assert(base); |
880 base->codegen(Type::sir); | 806 base->codegen(Type::sir); |
807 | |
808 // get type of typeinfo class | |
809 const LLStructType* stype = isaStruct(base->type->irtype->getPA()); | |
881 | 810 |
882 // initializer vector | 811 // initializer vector |
883 std::vector<LLConstant*> sinits; | 812 std::vector<LLConstant*> sinits; |
884 // first is always the vtable | 813 // first is always the vtable |
885 sinits.push_back(base->ir.irStruct->getVtblSymbol()); | 814 sinits.push_back(base->ir.irStruct->getVtblSymbol()); |
886 | 815 |
887 // monitor | 816 // monitor |
888 sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); | 817 sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); |
889 | 818 |
890 // get classinfo | |
891 sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol()); | |
892 | |
893 // create the inititalizer | |
894 LLConstant* tiInit = llvm::ConstantStruct::get(sinits); | |
895 | |
896 // refine global type | |
897 llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); | |
898 | |
899 // set the initializer | |
900 isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); | |
901 } | |
902 | |
903 /* ========================================================================= */ | |
904 | |
905 void TypeInfoInterfaceDeclaration::llvmDefine() | |
906 { | |
907 Logger::println("TypeInfoInterfaceDeclaration::llvmDefine() %s", toChars()); | |
908 LOG_SCOPE; | |
909 | |
910 // make sure interface is resolved | |
911 assert(tinfo->ty == Tclass); | |
912 TypeClass *tc = (TypeClass *)tinfo; | |
913 tc->sym->codegen(Type::sir); | |
914 | |
915 // init typeinfo class | |
916 ClassDeclaration* base = Type::typeinfointerface; | |
917 assert(base); | |
918 base->codegen(Type::sir); | |
919 | |
920 // get type of typeinfo class | |
921 const LLStructType* stype = isaStruct(base->type->irtype->getPA()); | |
922 | |
923 // initializer vector | |
924 std::vector<LLConstant*> sinits; | |
925 // first is always the vtable | |
926 sinits.push_back(base->ir.irStruct->getVtblSymbol()); | |
927 | |
928 // monitor | |
929 sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); | |
930 | |
931 // get classinfo | |
932 sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol()); | |
933 | |
934 // create the inititalizer | |
935 LLConstant* tiInit = llvm::ConstantStruct::get(sinits); | |
936 | |
937 // refine global type | |
938 llvm::cast<llvm::OpaqueType>(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); | |
939 | |
940 // set the initializer | |
941 isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); | |
942 } | |
943 | |
944 /* ========================================================================= */ | |
945 | |
946 void TypeInfoTupleDeclaration::llvmDefine() | |
947 { | |
948 Logger::println("TypeInfoTupleDeclaration::llvmDefine() %s", toChars()); | |
949 LOG_SCOPE; | |
950 | |
951 // init typeinfo class | |
952 ClassDeclaration* base = Type::typeinfotypelist; | |
953 assert(base); | |
954 base->codegen(Type::sir); | |
955 | |
956 // get type of typeinfo class | |
957 const LLStructType* stype = isaStruct(base->type->irtype->getPA()); | |
958 | |
959 // initializer vector | |
960 std::vector<LLConstant*> sinits; | |
961 // first is always the vtable | |
962 sinits.push_back(base->ir.irStruct->getVtblSymbol()); | |
963 | |
964 // monitor | |
965 sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); | |
966 | |
967 // create elements array | 819 // create elements array |
968 assert(tinfo->ty == Ttuple); | 820 assert(tinfo->ty == Ttuple); |
969 TypeTuple *tu = (TypeTuple *)tinfo; | 821 TypeTuple *tu = (TypeTuple *)tinfo; |
970 | 822 |
971 size_t dim = tu->arguments->dim; | 823 size_t dim = tu->arguments->dim; |
1016 void TypeInfoConstDeclaration::llvmDefine() | 868 void TypeInfoConstDeclaration::llvmDefine() |
1017 { | 869 { |
1018 Logger::println("TypeInfoConstDeclaration::llvmDefine() %s", toChars()); | 870 Logger::println("TypeInfoConstDeclaration::llvmDefine() %s", toChars()); |
1019 LOG_SCOPE; | 871 LOG_SCOPE; |
1020 | 872 |
1021 Type *tm = tinfo->mutableOf(); | 873 TypeInfoBuilder b(Type::typeinfoconst); |
1022 tm = tm->merge(); | 874 // TypeInfo base |
1023 | 875 b.push_typeinfo(tinfo->mutableOf()->merge()); |
1024 LLVM_D_Define_TypeInfoBase(tm, this, Type::typeinfoconst); | 876 // finish |
877 b.finalize(ir.irGlobal); | |
1025 } | 878 } |
1026 | 879 |
1027 /* ========================================================================= */ | 880 /* ========================================================================= */ |
1028 | 881 |
1029 void TypeInfoInvariantDeclaration::llvmDefine() | 882 void TypeInfoInvariantDeclaration::llvmDefine() |
1030 { | 883 { |
1031 Logger::println("TypeInfoInvariantDeclaration::llvmDefine() %s", toChars()); | 884 Logger::println("TypeInfoInvariantDeclaration::llvmDefine() %s", toChars()); |
1032 LOG_SCOPE; | 885 LOG_SCOPE; |
1033 | 886 |
1034 Type *tm = tinfo->mutableOf(); | 887 TypeInfoBuilder b(Type::typeinfoinvariant); |
1035 tm = tm->merge(); | 888 // TypeInfo base |
1036 | 889 b.push_typeinfo(tinfo->mutableOf()->merge()); |
1037 LLVM_D_Define_TypeInfoBase(tm, this, Type::typeinfoinvariant); | 890 // finish |
1038 } | 891 b.finalize(ir.irGlobal); |
1039 | 892 } |
1040 #endif | 893 |
894 #endif |