Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/gen/typinf.cpp

Revision 1607:207a8a438dea, 21.1 kB (checked in by Leandro Lucarella <llucax@gmail.com>, 2 years ago)

Merge DMD r253: refactor: Argument => Parameter
---

dmd/arrayop.c | 30 ++++----
dmd/arraytypes.h | 2 +-
dmd/class.c | 8 +-
dmd/declaration.c | 10 ++--
dmd/declaration.h | 16 ++--
dmd/doc.c | 12 ++--
dmd/dsymbol.c | 4 +-
dmd/expression.c | 48 +++++++-------
dmd/expression.h | 32 +++++-----
dmd/func.c | 78 +++++++++++-----------
dmd/init.c | 2 +-
dmd/interpret.c | 8 +-
dmd/mtype.c | 190 ++++++++++++++++++++++++++--------------------------
dmd/mtype.h | 32 +++++-----
dmd/opover.c | 34 +++++-----
dmd/parse.c | 40 ++++++------
dmd/parse.h | 2 +-
dmd/statement.c | 90 +++++++++++++-------------
dmd/statement.h | 14 ++--
dmd/struct.c | 8 +-
dmd/template.c | 30 ++++----
gen/functions.cpp | 10 ++--
gen/functions.h | 2 +-
gen/tocall.cpp | 10 ++--
gen/typinf.cpp | 6 +-
25 files changed, 359 insertions(+), 359 deletions(-)

Line 
1 // Copyright (c) 1999-2004 by Digital Mars
2 // All Rights Reserved
3 // written by Walter Bright
4 // www.digitalmars.com
5 // License for redistribution is by either the Artistic License
6 // in artistic.txt, or the GNU General Public License in gnu.txt.
7 // See the included readme.txt for details.
8
9 // Modifications for LDC:
10 // Copyright (c) 2007 by Tomas Lindquist Olsen
11 // tomas at famolsen dk
12
13 #include <cstdio>
14 #include <cassert>
15
16 #include "gen/llvm.h"
17
18 #include "mars.h"
19 #include "module.h"
20 #include "mtype.h"
21 #include "scope.h"
22 #include "init.h"
23 #include "expression.h"
24 #include "attrib.h"
25 #include "declaration.h"
26 #include "template.h"
27 #include "id.h"
28 #include "enum.h"
29 #include "import.h"
30 #include "aggregate.h"
31
32 #include "gen/irstate.h"
33 #include "gen/logger.h"
34 #include "gen/runtime.h"
35 #include "gen/tollvm.h"
36 #include "gen/llvmhelpers.h"
37 #include "gen/arrays.h"
38 #include "gen/structs.h"
39 #include "gen/classes.h"
40 #include "gen/linkage.h"
41 #include "gen/metadata.h"
42 #include "gen/rttibuilder.h"
43
44 #include "ir/irvar.h"
45 #include "ir/irtype.h"
46
47 /*******************************************
48  * Get a canonicalized form of the TypeInfo for use with the internal
49  * runtime library routines. Canonicalized in that static arrays are
50  * represented as dynamic arrays, enums are represented by their
51  * underlying type, etc. This reduces the number of TypeInfo's needed,
52  * so we can use the custom internal ones more.
53  */
54
55 Expression *Type::getInternalTypeInfo(Scope *sc)
56 {   TypeInfoDeclaration *tid;
57     Expression *e;
58     Type *t;
59     static TypeInfoDeclaration *internalTI[TMAX];
60
61     //printf("Type::getInternalTypeInfo() %s\n", toChars());
62     t = toBasetype();
63     switch (t->ty)
64     {
65     case Tsarray:
66 #if 0
67         // convert to corresponding dynamic array type
68         t = t->nextOf()->mutableOf()->arrayOf();
69 #endif
70         break;
71
72     case Tclass:
73         if (((TypeClass *)t)->sym->isInterfaceDeclaration())
74         break;
75         goto Linternal;
76
77     case Tarray:
78     #if DMDV2
79         // convert to corresponding dynamic array type
80         t = t->nextOf()->mutableOf()->arrayOf();
81     #endif
82         if (t->nextOf()->ty != Tclass)
83         break;
84         goto Linternal;
85
86     case Tfunction:
87     case Tdelegate:
88     case Tpointer:
89     Linternal:
90         tid = internalTI[t->ty];
91         if (!tid)
92         {   tid = new TypeInfoDeclaration(t, 1);
93         internalTI[t->ty] = tid;
94         }
95         e = new VarExp(0, tid);
96         e = e->addressOf(sc);
97         e->type = tid->type;    // do this so we don't get redundant dereference
98         return e;
99
100     default:
101         break;
102     }
103     //printf("\tcalling getTypeInfo() %s\n", t->toChars());
104     return t->getTypeInfo(sc);
105 }
106
107 /****************************************************
108  * Get the exact TypeInfo.
109  */
110
111 Expression *Type::getTypeInfo(Scope *sc)
112 {
113     Expression *e;
114     Type *t;
115
116     //printf("Type::getTypeInfo() %p, %s\n", this, toChars());
117     t = merge();    // do this since not all Type's are merge'd
118     if (!t->vtinfo)
119     {
120 #if DMDV2
121     if (t->isConst())
122         t->vtinfo = new TypeInfoConstDeclaration(t);
123     else if (t->isInvariant())
124         t->vtinfo = new TypeInfoInvariantDeclaration(t);
125     else
126 #endif
127         t->vtinfo = t->getTypeInfoDeclaration();
128     assert(t->vtinfo);
129
130     /* If this has a custom implementation in std/typeinfo, then
131      * do not generate a COMDAT for it.
132      */
133     if (!t->builtinTypeInfo())
134     {   // Generate COMDAT
135         if (sc)         // if in semantic() pass
136         {   // Find module that will go all the way to an object file
137         Module *m = sc->module->importedFrom;
138         m->members->push(t->vtinfo);
139         }
140         else            // if in obj generation pass
141         {
142 #if IN_DMD
143         t->vtinfo->toObjFile(0); // TODO: multiobj
144 #else
145         t->vtinfo->codegen(sir);
146 #endif
147         }
148     }
149     }
150     e = new VarExp(0, t->vtinfo);
151     e = e->addressOf(sc);
152     e->type = t->vtinfo->type;      // do this so we don't get redundant dereference
153     return e;
154 }
155
156 enum RET TypeFunction::retStyle()
157 {
158     return RETstack;
159 }
160
161 TypeInfoDeclaration *Type::getTypeInfoDeclaration()
162 {
163     //printf("Type::getTypeInfoDeclaration() %s\n", toChars());
164     return new TypeInfoDeclaration(this, 0);
165 }
166
167 TypeInfoDeclaration *TypeTypedef::getTypeInfoDeclaration()
168 {
169     return new TypeInfoTypedefDeclaration(this);
170 }
171
172 TypeInfoDeclaration *TypePointer::getTypeInfoDeclaration()
173 {
174     return new TypeInfoPointerDeclaration(this);
175 }
176
177 TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration()
178 {
179     return new TypeInfoArrayDeclaration(this);
180 }
181
182 TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration()
183 {
184     return new TypeInfoStaticArrayDeclaration(this);
185 }
186
187 TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration()
188 {
189     return new TypeInfoAssociativeArrayDeclaration(this);
190 }
191
192 TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration()
193 {
194     return new TypeInfoStructDeclaration(this);
195 }
196
197 TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration()
198 {
199     if (sym->isInterfaceDeclaration())
200     return new TypeInfoInterfaceDeclaration(this);
201     else
202     return new TypeInfoClassDeclaration(this);
203 }
204
205 TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration()
206 {
207     return new TypeInfoEnumDeclaration(this);
208 }
209
210 TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration()
211 {
212     return new TypeInfoFunctionDeclaration(this);
213 }
214
215 TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration()
216 {
217     return new TypeInfoDelegateDeclaration(this);
218 }
219
220 TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration()
221 {
222     return new TypeInfoTupleDeclaration(this);
223 }
224
225
226 /* ========================================================================= */
227
228 /* These decide if there's an instance for them already in std.typeinfo,
229  * because then the compiler doesn't need to build one.
230  */
231
232 int Type::builtinTypeInfo()
233 {
234     return 0;
235 }
236
237 int TypeBasic::builtinTypeInfo()
238 {
239 #if DMDV2
240     return !mod;
241 #else
242     return 1;
243 #endif
244 }
245
246 int TypeDArray::builtinTypeInfo()
247 {
248 #if DMDV2
249     return !mod && next->isTypeBasic() != NULL && !next->mod;
250 #else
251     return next->isTypeBasic() != NULL;
252 #endif
253 }
254
255 int TypeClass::builtinTypeInfo()
256 {
257     /* This is statically put out with the ClassInfo, so
258      * claim it is built in so it isn't regenerated by each module.
259      */
260 #if IN_DMD
261     return 1;
262 #elif IN_LLVM
263     // FIXME if I enable this, the way LDC does typeinfo will cause a bunch
264     // of linker errors to missing class typeinfo definitions.
265     return 0;
266 #endif
267 }
268
269 /* ========================================================================= */
270
271 //////////////////////////////////////////////////////////////////////////////
272 //                             MAGIC   PLACE
273 //                                (wut?)
274 //////////////////////////////////////////////////////////////////////////////
275
276 void DtoResolveTypeInfo(TypeInfoDeclaration* tid);
277 void DtoDeclareTypeInfo(TypeInfoDeclaration* tid);
278
279 void TypeInfoDeclaration::codegen(Ir*)
280 {
281     DtoResolveTypeInfo(this);
282 }
283
284 void DtoResolveTypeInfo(TypeInfoDeclaration* tid)
285 {
286     if (tid->ir.resolved) return;
287     tid->ir.resolved = true;
288
289     Logger::println("DtoResolveTypeInfo(%s)", tid->toChars());
290     LOG_SCOPE;
291
292     IrGlobal* irg = new IrGlobal(tid);
293
294     std::string mangle(tid->mangle());
295
296     irg->value = gIR->module->getGlobalVariable(mangle);
297     if (!irg->value)
298         irg->value = new llvm::GlobalVariable(*gIR->module, irg->type.get(), true,
299         TYPEINFO_LINKAGE_TYPE, NULL, mangle);
300
301     tid->ir.irGlobal = irg;
302
303 #if USE_METADATA
304     // don't do this for void or llvm will crash
305     if (tid->tinfo->ty != Tvoid) {
306         // Add some metadata for use by optimization passes.
307         std::string metaname = std::string(TD_PREFIX) + mangle;
308         llvm::NamedMDNode* meta = gIR->module->getNamedMetadata(metaname);
309         // Don't generate metadata for non-concrete types
310         // (such as tuple types, slice types, typeof(expr), etc.)
311         if (!meta && tid->tinfo->toBasetype()->ty < Terror) {
312             // Construct the fields
313             MDNodeField* mdVals[TD_NumFields];
314             if (TD_Confirm >= 0)
315                 mdVals[TD_Confirm] = llvm::cast<MDNodeField>(irg->value);
316             mdVals[TD_Type] = llvm::UndefValue::get(DtoType(tid->tinfo));
317             // Construct the metadata
318             llvm::MetadataBase* metadata = llvm::MDNode::get(gIR->context(), mdVals, TD_NumFields);
319             // Insert it into the module
320             llvm::NamedMDNode::Create(gIR->context(), metaname, &metadata, 1, gIR->module);
321         }
322     }
323 #endif // USE_METADATA
324
325     DtoDeclareTypeInfo(tid);
326 }
327
328 void DtoDeclareTypeInfo(TypeInfoDeclaration* tid)
329 {
330     DtoResolveTypeInfo(tid);
331
332     if (tid->ir.declared) return;
333     tid->ir.declared = true;
334
335     Logger::println("DtoDeclareTypeInfo(%s)", tid->toChars());
336     LOG_SCOPE;
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
345     IrGlobal* irg = tid->ir.irGlobal;
346     assert(irg->value != NULL);
347
348     // this is a declaration of a builtin __initZ var
349     if (tid->tinfo->builtinTypeInfo()) {
350         // fixup the global
351         const llvm::Type* rty = Type::typeinfo->type->irtype->getPA();
352         llvm::cast<llvm::OpaqueType>(irg->type.get())->refineAbstractTypeTo(rty);
353         LLGlobalVariable* g = isaGlobalVar(irg->value);
354         g->setLinkage(llvm::GlobalValue::ExternalLinkage);
355         return;
356     }
357
358     // define custom typedef
359     tid->llvmDefine();
360 }
361
362 /* ========================================================================= */
363
364 void TypeInfoDeclaration::llvmDefine()
365 {
366     assert(0 && "cannot generate generic typeinfo");
367 }
368
369 /* ========================================================================= */
370
371 void TypeInfoTypedefDeclaration::llvmDefine()
372 {
373     Logger::println("TypeInfoTypedefDeclaration::llvmDefine() %s", toChars());
374     LOG_SCOPE;
375
376     RTTIBuilder b(Type::typeinfotypedef);
377
378     assert(tinfo->ty == Ttypedef);
379     TypeTypedef *tc = (TypeTypedef *)tinfo;
380     TypedefDeclaration *sd = tc->sym;
381
382     // TypeInfo base
383     sd->basetype = sd->basetype->merge(); // dmd does it ... why?
384     b.push_typeinfo(sd->basetype);
385
386     // char[] name
387     b.push_string(sd->toPrettyChars());
388
389     // void[] init
390     // emit null array if we should use the basetype, or if the basetype
391     // uses default initialization.
392     if (!sd->init || tinfo->isZeroInit(0))
393     {
394         b.push_null_void_array();
395     }
396     // otherwise emit a void[] with the default initializer
397     else
398     {
399         LLConstant* C = DtoConstInitializer(sd->loc, sd->basetype, sd->init);
400         b.push_void_array(C, sd->basetype, sd);
401     }
402
403     // finish
404     b.finalize(ir.irGlobal);
405 }
406
407 /* ========================================================================= */
408
409 void TypeInfoEnumDeclaration::llvmDefine()
410 {
411     Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s", toChars());
412     LOG_SCOPE;
413
414     RTTIBuilder b(Type::typeinfoenum);
415
416     assert(tinfo->ty == Tenum);
417     TypeEnum *tc = (TypeEnum *)tinfo;
418     EnumDeclaration *sd = tc->sym;
419
420     // TypeInfo base
421     b.push_typeinfo(sd->memtype);
422
423     // char[] name
424     b.push_string(sd->toPrettyChars());
425
426     // void[] init
427     // emit void[] with the default initialier, the array is null if the default
428     // initializer is zero
429     if (!sd->defaultval || tinfo->isZeroInit(0))
430     {
431         b.push_null_void_array();
432     }
433     // otherwise emit a void[] with the default initializer
434     else
435     {
436         const LLType* memty = DtoType(sd->memtype);
437 #if DMDV2
438         LLConstant* C = LLConstantInt::get(memty, sd->defaultval->toInteger(), !sd->memtype->isunsigned());
439 #else
440         LLConstant* C = LLConstantInt::get(memty, sd->defaultval, !sd->memtype->isunsigned());
441 #endif
442         b.push_void_array(C, sd->memtype, sd);
443     }
444
445     // finish
446     b.finalize(ir.irGlobal);
447 }
448
449 /* ========================================================================= */
450
451 void TypeInfoPointerDeclaration::llvmDefine()
452 {
453     Logger::println("TypeInfoPointerDeclaration::llvmDefine() %s", toChars());
454     LOG_SCOPE;
455
456     RTTIBuilder b(Type::typeinfopointer);
457     // TypeInfo base
458     b.push_typeinfo(tinfo->nextOf());
459     // finish
460     b.finalize(ir.irGlobal);
461 }
462
463 /* ========================================================================= */
464
465 void TypeInfoArrayDeclaration::llvmDefine()
466 {
467     Logger::println("TypeInfoArrayDeclaration::llvmDefine() %s", toChars());
468     LOG_SCOPE;
469
470     RTTIBuilder b(Type::typeinfoarray);
471     // TypeInfo base
472     b.push_typeinfo(tinfo->nextOf());
473     // finish
474     b.finalize(ir.irGlobal);
475 }
476
477 /* ========================================================================= */
478
479 void TypeInfoStaticArrayDeclaration::llvmDefine()
480 {
481     Logger::println("TypeInfoStaticArrayDeclaration::llvmDefine() %s", toChars());
482     LOG_SCOPE;
483
484     assert(tinfo->ty == Tsarray);
485     TypeSArray *tc = (TypeSArray *)tinfo;
486
487     RTTIBuilder b(Type::typeinfostaticarray);
488
489     // value typeinfo
490     b.push_typeinfo(tc->nextOf());
491
492     // length
493     b.push(DtoConstSize_t((size_t)tc->dim->toUInteger()));
494
495     // finish
496     b.finalize(ir.irGlobal);
497 }
498
499 /* ========================================================================= */
500
501 void TypeInfoAssociativeArrayDeclaration::llvmDefine()
502 {
503     Logger::println("TypeInfoAssociativeArrayDeclaration::llvmDefine() %s", toChars());
504     LOG_SCOPE;
505
506     assert(tinfo->ty == Taarray);
507     TypeAArray *tc = (TypeAArray *)tinfo;
508
509     RTTIBuilder b(Type::typeinfoassociativearray);
510
511     // value typeinfo
512     b.push_typeinfo(tc->nextOf());
513
514     // key typeinfo
515     b.push_typeinfo(tc->index);
516
517     // finish
518     b.finalize(ir.irGlobal);
519 }
520
521 /* ========================================================================= */
522
523 void TypeInfoFunctionDeclaration::llvmDefine()
524 {
525     Logger::println("TypeInfoFunctionDeclaration::llvmDefine() %s", toChars());
526     LOG_SCOPE;
527
528     RTTIBuilder b(Type::typeinfofunction);
529     // TypeInfo base
530     b.push_typeinfo(tinfo->nextOf());
531     // finish
532     b.finalize(ir.irGlobal);
533 }
534
535 /* ========================================================================= */
536
537 void TypeInfoDelegateDeclaration::llvmDefine()
538 {
539     Logger::println("TypeInfoDelegateDeclaration::llvmDefine() %s", toChars());
540     LOG_SCOPE;
541
542     assert(tinfo->ty == Tdelegate);
543     Type* ret_type = tinfo->nextOf()->nextOf();
544
545     RTTIBuilder b(Type::typeinfodelegate);
546     // TypeInfo base
547     b.push_typeinfo(ret_type);
548     // finish
549     b.finalize(ir.irGlobal);
550 }
551
552 /* ========================================================================= */
553
554 static FuncDeclaration* find_method_overload(AggregateDeclaration* ad, Identifier* id, TypeFunction* tf, Module* mod)
555 {
556     Dsymbol *s = search_function(ad, id);
557     FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
558     if (fdx)
559     {
560         FuncDeclaration *fd = fdx->overloadExactMatch(tf, mod);
561         if (fd)
562         {
563             return fd;
564         }
565     }
566     return NULL;
567 }
568
569 void TypeInfoStructDeclaration::llvmDefine()
570 {
571     Logger::println("TypeInfoStructDeclaration::llvmDefine() %s", toChars());
572     LOG_SCOPE;
573
574     // make sure struct is resolved
575     assert(tinfo->ty == Tstruct);
576     TypeStruct *tc = (TypeStruct *)tinfo;
577     StructDeclaration *sd = tc->sym;
578
579     // can't emit typeinfo for forward declarations
580     if (sd->sizeok != 1)
581     {
582         sd->error("cannot emit TypeInfo for forward declaration");
583         fatal();
584     }
585
586     sd->codegen(Type::sir);
587     IrStruct* irstruct = sd->ir.irStruct;
588
589     RTTIBuilder b(Type::typeinfostruct);
590
591     // char[] name
592     b.push_string(sd->toPrettyChars());
593
594     // void[] init
595     // never emit a null array, even for zero initialized typeinfo
596     // the size() method uses this array!
597     size_t init_size = getTypeStoreSize(tc->irtype->getPA());
598     b.push_void_array(init_size, irstruct->getInitSymbol());
599
600     // toX functions ground work
601     static TypeFunction *tftohash;
602     static TypeFunction *tftostring;
603
604     if (!tftohash)
605     {
606         Scope sc;
607         tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
608         tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
609         tftostring = new TypeFunction(NULL, Type::tchar->arrayOf(), 0, LINKd);
610         tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
611     }
612
613     // this one takes a parameter, so we need to build a new one each time
614     // to get the right type. can we avoid this?
615     TypeFunction *tfeqptr;
616     {
617         Scope sc;
618         Parameters *arguments = new Parameters;
619         Parameter *arg = new Parameter(STCin, tc->pointerTo(), NULL, NULL);
620         arguments->push(arg);
621         tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
622         tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc);
623     }
624
625     // well use this module for all overload lookups
626     Module *gm = getModule();
627
628     // toHash
629     FuncDeclaration* fd = find_method_overload(sd, Id::tohash, tftohash, gm);
630     b.push_funcptr(fd);
631
632     // opEquals
633     fd = find_method_overload(sd, Id::eq, tfeqptr, gm);
634     b.push_funcptr(fd);
635
636     // opCmp
637     fd = find_method_overload(sd, Id::cmp, tfeqptr, gm);
638     b.push_funcptr(fd);
639
640     // toString
641     fd = find_method_overload(sd, Id::tostring, tftostring, gm);
642     b.push_funcptr(fd);
643
644     // uint m_flags;
645     unsigned hasptrs = tc->hasPointers() ? 1 : 0;
646     b.push_uint(hasptrs);
647
648 #if DMDV2
649     // FIXME: just emit nulls for now
650
651     ClassDeclaration* tscd = Type::typeinfostruct;
652
653     assert(tscd->fields.dim == 10);
654
655     // const(MemberInfo[]) function(in char[]) xgetMembers;
656     VarDeclaration* xgetMembers = (VarDeclaration*)tscd->fields.data[7];
657     b.push_null(xgetMembers->type);
658
659     //void function(void*)                    xdtor;
660     VarDeclaration* xdtor = (VarDeclaration*)tscd->fields.data[8];
661     b.push_null(xdtor->type);
662
663     //void function(void*)                    xpostblit;
664     VarDeclaration* xpostblit = (VarDeclaration*)tscd->fields.data[9];
665     b.push_null(xpostblit->type);
666 #endif
667
668     // finish
669     b.finalize(ir.irGlobal);
670 }
671
672 /* ========================================================================= */
673
674 void TypeInfoClassDeclaration::llvmDefine()
675 {
676     Logger::println("TypeInfoClassDeclaration::llvmDefine() %s", toChars());
677     LOG_SCOPE;
678
679     // make sure class is resolved
680     assert(tinfo->ty == Tclass);
681     TypeClass *tc = (TypeClass *)tinfo;
682     tc->sym->codegen(Type::sir);
683
684     RTTIBuilder b(Type::typeinfoclass);
685
686     // TypeInfo base
687     b.push_classinfo(tc->sym);
688
689     // finish
690     b.finalize(ir.irGlobal);
691 }
692
693 /* ========================================================================= */
694
695 void TypeInfoInterfaceDeclaration::llvmDefine()
696 {
697     Logger::println("TypeInfoInterfaceDeclaration::llvmDefine() %s", toChars());
698     LOG_SCOPE;
699
700     // make sure interface is resolved
701     assert(tinfo->ty == Tclass);
702     TypeClass *tc = (TypeClass *)tinfo;
703     tc->sym->codegen(Type::sir);
704
705     RTTIBuilder b(Type::typeinfointerface);
706
707     // TypeInfo base
708     b.push_classinfo(tc->sym);
709
710     // finish
711     b.finalize(ir.irGlobal);
712 }
713
714 /* ========================================================================= */
715
716 void TypeInfoTupleDeclaration::llvmDefine()
717 {
718     Logger::println("TypeInfoTupleDeclaration::llvmDefine() %s", toChars());
719     LOG_SCOPE;
720
721     // create elements array
722     assert(tinfo->ty == Ttuple);
723     TypeTuple *tu = (TypeTuple *)tinfo;
724
725     size_t dim = tu->arguments->dim;
726     std::vector<LLConstant*> arrInits;
727     arrInits.reserve(dim);
728
729     const LLType* tiTy = DtoType(Type::typeinfo->type);
730
731     for (size_t i = 0; i < dim; i++)
732     {
733         Parameter *arg = (Parameter *)tu->arguments->data[i];
734         arrInits.push_back(DtoTypeInfoOf(arg->type, true));
735     }
736
737     // build array
738     const LLArrayType* arrTy = LLArrayType::get(tiTy, dim);
739     LLConstant* arrC = LLConstantArray::get(arrTy, arrInits);
740
741     RTTIBuilder b(Type::typeinfotypelist);
742
743     // push TypeInfo[]
744     b.push_array(arrC, dim, Type::typeinfo->type, NULL);
745
746     // finish
747     b.finalize(ir.irGlobal);
748 }
749
750 /* ========================================================================= */
751
752 #if DMDV2
753
754 void TypeInfoConstDeclaration::llvmDefine()
755 {
756     Logger::println("TypeInfoConstDeclaration::llvmDefine() %s", toChars());
757     LOG_SCOPE;
758
759     RTTIBuilder b(Type::typeinfoconst);
760     // TypeInfo base
761     b.push_typeinfo(tinfo->mutableOf()->merge());
762     // finish
763     b.finalize(ir.irGlobal);
764 }
765
766 /* ========================================================================= */
767
768 void TypeInfoInvariantDeclaration::llvmDefine()
769 {
770     Logger::println("TypeInfoInvariantDeclaration::llvmDefine() %s", toChars());
771     LOG_SCOPE;
772
773     RTTIBuilder b(Type::typeinfoinvariant);
774     // TypeInfo base
775     b.push_typeinfo(tinfo->mutableOf()->merge());
776     // finish
777     b.finalize(ir.irGlobal);
778 }
779
780 #endif
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.