2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2007 by Digital Mars
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
11 /* NOTE: This file has been patched from the original DMD distribution to
12 work with the GDC compiler.
14 Modified by David Friedman, September 2004
27 #include "expression.h"
29 #include "declaration.h"
34 #include "aggregate.h"
50 #include "d-dmd-gcc.h"
53 extern Symbol
*static_sym();
55 /*******************************************
56 * Get a canonicalized form of the TypeInfo for use with the internal
57 * runtime library routines. Canonicalized in that static arrays are
58 * represented as dynamic arrays, enums are represented by their
59 * underlying type, etc. This reduces the number of TypeInfo's needed,
60 * so we can use the custom internal ones more.
63 Expression
*Type::getInternalTypeInfo(Scope
*sc
)
64 { TypeInfoDeclaration
*tid
;
67 static TypeInfoDeclaration
*internalTI
[TMAX
];
69 //printf("Type::getInternalTypeInfo() %s\n", toChars());
75 // convert to corresponding dynamic array type
76 t
= t
->nextOf()->mutableOf()->arrayOf();
81 if (((TypeClass
*)t
)->sym
->isInterfaceDeclaration())
86 // convert to corresponding dynamic array type
87 t
= t
->nextOf()->mutableOf()->arrayOf();
88 if (t
->nextOf()->ty
!= Tclass
)
96 tid
= internalTI
[t
->ty
];
98 { tid
= new TypeInfoDeclaration(t
, 1);
99 internalTI
[t
->ty
] = tid
;
101 e
= new VarExp(0, tid
);
102 e
= e
->addressOf(sc
);
103 e
->type
= tid
->type
; // do this so we don't get redundant dereference
109 //printf("\tcalling getTypeInfo() %s\n", t->toChars());
110 return t
->getTypeInfo(sc
);
114 /****************************************************
115 * Get the exact TypeInfo.
118 Expression
*Type::getTypeInfo(Scope
*sc
)
123 //printf("Type::getTypeInfo() %p, %s\n", this, toChars());
124 t
= merge(); // do this since not all Type's are merge'd
128 t
->vtinfo
= new TypeInfoConstDeclaration(t
);
129 else if (t
->isInvariant())
130 t
->vtinfo
= new TypeInfoInvariantDeclaration(t
);
132 t
->vtinfo
= t
->getTypeInfoDeclaration();
135 /* If this has a custom implementation in std/typeinfo, then
136 * do not generate a COMDAT for it.
138 if (!t
->builtinTypeInfo())
140 if (sc
) // if in semantic() pass
141 { // Find module that will go all the way to an object file
142 Module
*m
= sc
->module
->importedFrom
;
143 m
->members
->push(t
->vtinfo
);
145 else // if in obj generation pass
147 t
->vtinfo
->toObjFile(global
.params
.multiobj
);
151 e
= new VarExp(0, t
->vtinfo
);
152 e
= e
->addressOf(sc
);
153 e
->type
= t
->vtinfo
->type
; // do this so we don't get redundant dereference
157 TypeInfoDeclaration
*Type::getTypeInfoDeclaration()
159 //printf("Type::getTypeInfoDeclaration() %s\n", toChars());
160 return new TypeInfoDeclaration(this, 0);
163 TypeInfoDeclaration
*TypeTypedef::getTypeInfoDeclaration()
165 return new TypeInfoTypedefDeclaration(this);
168 TypeInfoDeclaration
*TypePointer::getTypeInfoDeclaration()
170 return new TypeInfoPointerDeclaration(this);
173 TypeInfoDeclaration
*TypeDArray::getTypeInfoDeclaration()
175 return new TypeInfoArrayDeclaration(this);
178 TypeInfoDeclaration
*TypeSArray::getTypeInfoDeclaration()
180 return new TypeInfoStaticArrayDeclaration(this);
183 TypeInfoDeclaration
*TypeAArray::getTypeInfoDeclaration()
185 return new TypeInfoAssociativeArrayDeclaration(this);
188 TypeInfoDeclaration
*TypeStruct::getTypeInfoDeclaration()
190 return new TypeInfoStructDeclaration(this);
193 TypeInfoDeclaration
*TypeClass::getTypeInfoDeclaration()
195 if (sym
->isInterfaceDeclaration())
196 return new TypeInfoInterfaceDeclaration(this);
198 return new TypeInfoClassDeclaration(this);
201 TypeInfoDeclaration
*TypeEnum::getTypeInfoDeclaration()
203 return new TypeInfoEnumDeclaration(this);
206 TypeInfoDeclaration
*TypeFunction::getTypeInfoDeclaration()
208 return new TypeInfoFunctionDeclaration(this);
211 TypeInfoDeclaration
*TypeDelegate::getTypeInfoDeclaration()
213 return new TypeInfoDelegateDeclaration(this);
216 TypeInfoDeclaration
*TypeTuple::getTypeInfoDeclaration()
218 return new TypeInfoTupleDeclaration(this);
222 /****************************************************
227 void TypeInfoDeclaration::toDt(dt_t
**pdt
)
229 //printf("TypeInfoDeclaration::toDt() %s\n", toChars());
230 dtxoff(pdt
, Type::typeinfo
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo
231 dtdword(pdt
, 0); // monitor
234 void TypeInfoConstDeclaration::toDt(dt_t
**pdt
)
236 //printf("TypeInfoConstDeclaration::toDt() %s\n", toChars());
237 dtxoff(pdt
, Type::typeinfoconst
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Const
238 dtdword(pdt
, 0); // monitor
239 Type
*tm
= tinfo
->mutableOf();
241 tm
->getTypeInfo(NULL
);
242 dtxoff(pdt
, tm
->vtinfo
->toSymbol(), 0, TYnptr
);
245 void TypeInfoInvariantDeclaration::toDt(dt_t
**pdt
)
247 //printf("TypeInfoInvariantDeclaration::toDt() %s\n", toChars());
248 dtxoff(pdt
, Type::typeinfoinvariant
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Invariant
249 dtdword(pdt
, 0); // monitor
250 Type
*tm
= tinfo
->mutableOf();
252 tm
->getTypeInfo(NULL
);
253 dtxoff(pdt
, tm
->vtinfo
->toSymbol(), 0, TYnptr
);
256 void TypeInfoTypedefDeclaration::toDt(dt_t
**pdt
)
258 //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars());
260 dtxoff(pdt
, Type::typeinfotypedef
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Typedef
261 dtdword(pdt
, 0); // monitor
263 assert(tinfo
->ty
== Ttypedef
);
265 TypeTypedef
*tc
= (TypeTypedef
*)tinfo
;
266 TypedefDeclaration
*sd
= tc
->sym
;
267 //printf("basetype = %s\n", sd->basetype->toChars());
275 sd
->basetype
= sd
->basetype
->merge();
276 sd
->basetype
->getTypeInfo(NULL
); // generate vtinfo
277 assert(sd
->basetype
->vtinfo
);
278 dtxoff(pdt
, sd
->basetype
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for basetype
280 char *name
= sd
->toPrettyChars();
281 size_t namelen
= strlen(name
);
282 dtdword(pdt
, namelen
);
283 dtabytes(pdt
, TYnptr
, 0, namelen
+ 1, name
);
286 if (tinfo
->isZeroInit() || !sd
->init
)
287 { // 0 initializer, or the same as the base type
288 dtdword(pdt
, 0); // init.length
289 dtdword(pdt
, 0); // init.ptr
293 dtdword(pdt
, sd
->type
->size()); // init.length
294 dtxoff(pdt
, sd
->toInitializer(), 0, TYnptr
); // init.ptr
298 void TypeInfoEnumDeclaration::toDt(dt_t
**pdt
)
300 //printf("TypeInfoEnumDeclaration::toDt()\n");
301 dtxoff(pdt
, Type::typeinfoenum
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Enum
302 dtdword(pdt
, 0); // monitor
304 assert(tinfo
->ty
== Tenum
);
306 TypeEnum
*tc
= (TypeEnum
*)tinfo
;
307 EnumDeclaration
*sd
= tc
->sym
;
316 { sd
->memtype
->getTypeInfo(NULL
);
317 dtxoff(pdt
, sd
->memtype
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for enum members
322 char *name
= sd
->toPrettyChars();
323 size_t namelen
= strlen(name
);
324 dtdword(pdt
, namelen
);
325 dtabytes(pdt
, TYnptr
, 0, namelen
+ 1, name
);
328 if (!sd
->defaultval
|| tinfo
->isZeroInit())
329 { // 0 initializer, or the same as the base type
330 dtdword(pdt
, 0); // init.length
331 dtdword(pdt
, 0); // init.ptr
335 dtdword(pdt
, sd
->type
->size()); // init.length
336 dtxoff(pdt
, sd
->toInitializer(), 0, TYnptr
); // init.ptr
340 void TypeInfoPointerDeclaration::toDt(dt_t
**pdt
)
342 //printf("TypeInfoPointerDeclaration::toDt()\n");
343 dtxoff(pdt
, Type::typeinfopointer
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Pointer
344 dtdword(pdt
, 0); // monitor
346 assert(tinfo
->ty
== Tpointer
);
348 TypePointer
*tc
= (TypePointer
*)tinfo
;
350 tc
->next
->getTypeInfo(NULL
);
351 dtxoff(pdt
, tc
->next
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for type being pointed to
354 void TypeInfoArrayDeclaration::toDt(dt_t
**pdt
)
356 //printf("TypeInfoArrayDeclaration::toDt()\n");
357 dtxoff(pdt
, Type::typeinfoarray
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Array
358 dtdword(pdt
, 0); // monitor
360 assert(tinfo
->ty
== Tarray
);
362 TypeDArray
*tc
= (TypeDArray
*)tinfo
;
364 tc
->next
->getTypeInfo(NULL
);
365 dtxoff(pdt
, tc
->next
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for array of type
368 void TypeInfoStaticArrayDeclaration::toDt(dt_t
**pdt
)
370 //printf("TypeInfoStaticArrayDeclaration::toDt()\n");
371 dtxoff(pdt
, Type::typeinfostaticarray
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_StaticArray
372 dtdword(pdt
, 0); // monitor
374 assert(tinfo
->ty
== Tsarray
);
376 TypeSArray
*tc
= (TypeSArray
*)tinfo
;
378 tc
->next
->getTypeInfo(NULL
);
379 dtxoff(pdt
, tc
->next
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for array of type
381 dtdword(pdt
, tc
->dim
->toInteger()); // length
384 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t
**pdt
)
386 //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
387 dtxoff(pdt
, Type::typeinfoassociativearray
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_AssociativeArray
388 dtdword(pdt
, 0); // monitor
390 assert(tinfo
->ty
== Taarray
);
392 TypeAArray
*tc
= (TypeAArray
*)tinfo
;
394 tc
->next
->getTypeInfo(NULL
);
395 dtxoff(pdt
, tc
->next
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for array of type
397 tc
->index
->getTypeInfo(NULL
);
398 dtxoff(pdt
, tc
->index
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for array of type
401 void TypeInfoFunctionDeclaration::toDt(dt_t
**pdt
)
403 //printf("TypeInfoFunctionDeclaration::toDt()\n");
404 dtxoff(pdt
, Type::typeinfofunction
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Function
405 dtdword(pdt
, 0); // monitor
407 assert(tinfo
->ty
== Tfunction
);
409 TypeFunction
*tc
= (TypeFunction
*)tinfo
;
411 tc
->next
->getTypeInfo(NULL
);
412 dtxoff(pdt
, tc
->next
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for function return value
415 void TypeInfoDelegateDeclaration::toDt(dt_t
**pdt
)
417 //printf("TypeInfoDelegateDeclaration::toDt()\n");
418 dtxoff(pdt
, Type::typeinfodelegate
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Delegate
419 dtdword(pdt
, 0); // monitor
421 assert(tinfo
->ty
== Tdelegate
);
423 TypeDelegate
*tc
= (TypeDelegate
*)tinfo
;
425 tc
->next
->nextOf()->getTypeInfo(NULL
);
426 dtxoff(pdt
, tc
->next
->nextOf()->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for delegate return value
429 void TypeInfoStructDeclaration::toDt(dt_t
**pdt
)
431 //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
433 unsigned offset
= Type::typeinfostruct
->structsize
;
435 dtxoff(pdt
, Type::typeinfostruct
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Struct
436 dtdword(pdt
, 0); // monitor
438 assert(tinfo
->ty
== Tstruct
);
440 TypeStruct
*tc
= (TypeStruct
*)tinfo
;
441 StructDeclaration
*sd
= tc
->sym
;
446 * hash_t function(in void*) xtoHash;
447 * int function(in void*, in void*) xopEquals;
448 * int function(in void*, in void*) xopCmp;
449 * string function(const(void)*) xtoString;
458 char *name
= sd
->toPrettyChars();
459 size_t namelen
= strlen(name
);
460 dtdword(pdt
, namelen
);
461 //dtabytes(pdt, TYnptr, 0, namelen + 1, name);
462 dtxoff(pdt
, toSymbol(), offset
, TYnptr
);
463 offset
+= namelen
+ 1;
466 dtdword(pdt
, sd
->structsize
); // init.length
468 dtdword(pdt
, 0); // NULL for 0 initialization
470 dtxoff(pdt
, sd
->toInitializer(), 0, TYnptr
); // init.ptr
473 FuncDeclaration
*fdx
;
478 static TypeFunction
*tftohash
;
479 static TypeFunction
*tftostring
;
485 tftohash
= new TypeFunction(NULL
, Type::thash_t
, 0, LINKd
);
486 tftohash
->mod
= MODconst
;
487 tftohash
= (TypeFunction
*)tftohash
->semantic(0, &sc
);
489 tftostring
= new TypeFunction(NULL
, Type::tchar
->invariantOf()->arrayOf(), 0, LINKd
);
490 tftostring
= (TypeFunction
*)tftostring
->semantic(0, &sc
);
493 TypeFunction
*tfeqptr
;
496 Arguments
*arguments
= new Arguments
;
497 Argument
*arg
= new Argument(STCin
, tc
->pointerTo(), NULL
, NULL
);
499 arguments
->push(arg
);
500 tfeqptr
= new TypeFunction(arguments
, Type::tint32
, 0, LINKd
);
501 tfeqptr
->mod
= MODconst
;
502 tfeqptr
= (TypeFunction
*)tfeqptr
->semantic(0, &sc
);
509 Array
*arguments
= new Array
;
510 Argument
*arg
= new Argument(In
, tc
, NULL
, NULL
);
512 arguments
->push(arg
);
513 tfeq
= new TypeFunction(arguments
, Type::tint32
, 0, LINKd
);
514 tfeq
= (TypeFunction
*)tfeq
->semantic(0, &sc
);
518 s
= search_function(sd
, Id::tohash
);
519 fdx
= s
? s
->isFuncDeclaration() : NULL
;
521 { fd
= fdx
->overloadExactMatch(tftohash
);
523 dtxoff(pdt
, fd
->toSymbol(), 0, TYnptr
);
525 //fdx->error("must be declared as extern (D) uint toHash()");
531 s
= search_function(sd
, Id::eq
);
532 fdx
= s
? s
->isFuncDeclaration() : NULL
;
533 for (int i
= 0; i
< 2; i
++)
536 { fd
= fdx
->overloadExactMatch(tfeqptr
);
538 dtxoff(pdt
, fd
->toSymbol(), 0, TYnptr
);
540 //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
546 s
= search_function(sd
, Id::cmp
);
547 fdx
= s
? s
->isFuncDeclaration() : NULL
;
550 s
= search_function(sd
, Id::tostring
);
551 fdx
= s
? s
->isFuncDeclaration() : NULL
;
553 { fd
= fdx
->overloadExactMatch(tftostring
);
555 dtxoff(pdt
, fd
->toSymbol(), 0, TYnptr
);
557 //fdx->error("must be declared as extern (D) char[] toString()");
564 dti32(pdt
, tc
->hasPointers(), false);
567 FuncDeclaration
*sgetmembers
= sd
->findGetMembers();
569 dtxoff(pdt
, sgetmembers
->toSymbol(), 0, TYnptr
);
571 dtdword(pdt
, 0); // xgetMembers
574 FuncDeclaration
*sdtor
= sd
->dtor
;
576 dtxoff(pdt
, sdtor
->toSymbol(), 0, TYnptr
);
578 dtdword(pdt
, 0); // xdtor
581 FuncDeclaration
*spostblit
= sd
->postblit
;
583 dtxoff(pdt
, spostblit
->toSymbol(), 0, TYnptr
);
585 dtdword(pdt
, 0); // xpostblit
588 dtnbytes(pdt
, namelen
+ 1, name
);
591 void TypeInfoClassDeclaration::toDt(dt_t
**pdt
)
593 //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
594 dtxoff(pdt
, Type::typeinfoclass
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfoClass
595 dtdword(pdt
, 0); // monitor
597 assert(tinfo
->ty
== Tclass
);
599 TypeClass
*tc
= (TypeClass
*)tinfo
;
602 if (!tc
->sym
->vclassinfo
)
603 tc
->sym
->vclassinfo
= new ClassInfoDeclaration(tc
->sym
);
604 s
= tc
->sym
->vclassinfo
->toSymbol();
605 dtxoff(pdt
, s
, 0, TYnptr
); // ClassInfo for tinfo
608 void TypeInfoInterfaceDeclaration::toDt(dt_t
**pdt
)
610 //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
611 dtxoff(pdt
, Type::typeinfointerface
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfoInterface
612 dtdword(pdt
, 0); // monitor
614 assert(tinfo
->ty
== Tclass
);
616 TypeClass
*tc
= (TypeClass
*)tinfo
;
619 if (!tc
->sym
->vclassinfo
)
620 tc
->sym
->vclassinfo
= new ClassInfoDeclaration(tc
->sym
);
621 s
= tc
->sym
->vclassinfo
->toSymbol();
622 dtxoff(pdt
, s
, 0, TYnptr
); // ClassInfo for tinfo
625 void TypeInfoTupleDeclaration::toDt(dt_t
**pdt
)
627 //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
628 dtxoff(pdt
, Type::typeinfotypelist
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfoInterface
629 dtdword(pdt
, 0); // monitor
631 assert(tinfo
->ty
== Ttuple
);
633 TypeTuple
*tu
= (TypeTuple
*)tinfo
;
635 size_t dim
= tu
->arguments
->dim
;
636 dtdword(pdt
, dim
); // elements.length
639 for (size_t i
= 0; i
< dim
; i
++)
640 { Argument
*arg
= (Argument
*)tu
->arguments
->data
[i
];
641 Expression
*e
= arg
->type
->getTypeInfo(NULL
);
642 e
= e
->optimize(WANTvalue
);
651 dtxoff(pdt
, s
, 0, TYnptr
); // elements.ptr
654 void TypeInfoDeclaration::toObjFile(int multiobj
)
660 //printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection);
671 parent
= this->toParent();
672 s
->Sclass
= SCcomdat
;
679 // See if we can convert a comdat to a comdef,
680 // which saves on exe file space.
681 if (s
->Sclass
== SCcomdat
&&
682 s
->Sdt
->dt
== DT_azeros
&&
683 s
->Sdt
->DTnext
== NULL
)
685 s
->Sclass
= SCglobal
;
686 s
->Sdt
->dt
= DT_common
;
690 if (s
->Sdt
&& s
->Sdt
->dt
== DT_azeros
&& s
->Sdt
->DTnext
== NULL
)
702 /* ========================================================================= */
704 /* These decide if there's an instance for them already in std.typeinfo,
705 * because then the compiler doesn't need to build one.
708 int Type::builtinTypeInfo()
713 int TypeBasic::builtinTypeInfo()
718 int TypeDArray::builtinTypeInfo()
720 return !mod
&& next
->isTypeBasic() != NULL
&& !next
->mod
;
723 /* ========================================================================= */
725 /***************************************
726 * Create a static array of TypeInfo references
727 * corresponding to an array of Expression's.
728 * Used to supply hidden _arguments[] value for variadic D functions.
731 Expression
*createTypeInfoArray(Scope
*sc
, Expression
*exps
[], int dim
)
734 /* Get the corresponding TypeInfo_Tuple and
735 * point at its elements[].
738 /* Create the TypeTuple corresponding to the types of args[]
740 Arguments
*args
= new Arguments
;
742 for (size_t i
= 0; i
< dim
; i
++)
743 { Argument
*arg
= new Argument(STCin
, exps
[i
]->type
, NULL
, NULL
);
744 args
->data
[i
] = (void *)arg
;
746 TypeTuple
*tup
= new TypeTuple(args
);
747 Expression
*e
= tup
->getTypeInfo(sc
);
748 e
= e
->optimize(WANTvalue
);
749 assert(e
->op
== TOKsymoff
); // should be SymOffExp
753 * Should just pass a reference to TypeInfo_Tuple instead,
754 * but that would require existing code to be recompiled.
755 * Source compatibility can be maintained by computing _arguments[]
756 * at the start of the called function by offseting into the
757 * TypeInfo_Tuple reference.
761 // Advance to elements[] member of TypeInfo_Tuple
762 SymOffExp
*se
= (SymOffExp
*)e
;
763 se
->offset
+= PTRSIZE
+ PTRSIZE
;
765 // Set type to TypeInfo[]*
766 se
->type
= Type::typeinfo
->type
->arrayOf()->pointerTo();
768 // Indirect to get the _arguments[] value
769 e
= new PtrExp(0, se
);
770 e
->type
= se
->type
->next
;
775 * 1) create an array literal instead,
776 * as it would eliminate the extra dereference of loading the
780 ArrayInitializer
*ai
= new ArrayInitializer(0);
788 // Generate identifier for _arguments[]
789 buf
.writestring("_arguments_");
790 for (int i
= 0; i
< dim
; i
++)
792 t
->toDecoBuffer(&buf
);
795 id
= Lexer::idPool((char *)buf
.data
);
798 Module
*m
= d_gcc_get_output_module();
800 Module
*m
= sc
->module
;
802 Dsymbol
*s
= m
->symtab
->lookup(id
);
804 if (s
&& s
->parent
== m
)
805 { // Use existing one
806 v
= s
->isVarDeclaration();
810 { // Generate new one
812 for (int i
= 0; i
< dim
; i
++)
814 e
= t
->getTypeInfo(sc
);
815 ai
->addInit(new IntegerExp(i
), new ExpInitializer(0, e
));
818 t
= Type::typeinfo
->type
->arrayOf();
820 v
= new VarDeclaration(0, t
, id
, ai
);
822 m
->symtab
->insert(v
);
825 sc
->stc
= STCstatic
| STCcomdat
;
831 e
= new VarExp(0, v
);