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
*TypeMaybe::getTypeInfoDeclaration()
175 return new TypeInfoMaybeDeclaration(this);
178 TypeInfoDeclaration
*TypeDArray::getTypeInfoDeclaration()
180 return new TypeInfoArrayDeclaration(this);
183 TypeInfoDeclaration
*TypeSArray::getTypeInfoDeclaration()
185 return new TypeInfoStaticArrayDeclaration(this);
188 TypeInfoDeclaration
*TypeAArray::getTypeInfoDeclaration()
190 return new TypeInfoAssociativeArrayDeclaration(this);
193 TypeInfoDeclaration
*TypeStruct::getTypeInfoDeclaration()
195 return new TypeInfoStructDeclaration(this);
198 TypeInfoDeclaration
*TypeClass::getTypeInfoDeclaration()
200 if (sym
->isInterfaceDeclaration())
201 return new TypeInfoInterfaceDeclaration(this);
203 return new TypeInfoClassDeclaration(this);
206 TypeInfoDeclaration
*TypeEnum::getTypeInfoDeclaration()
208 return new TypeInfoEnumDeclaration(this);
211 TypeInfoDeclaration
*TypeFunction::getTypeInfoDeclaration()
213 return new TypeInfoFunctionDeclaration(this);
216 TypeInfoDeclaration
*TypeDelegate::getTypeInfoDeclaration()
218 return new TypeInfoDelegateDeclaration(this);
221 TypeInfoDeclaration
*TypeTuple::getTypeInfoDeclaration()
223 return new TypeInfoTupleDeclaration(this);
227 /****************************************************
232 void TypeInfoDeclaration::toDt(dt_t
**pdt
)
234 //printf("TypeInfoDeclaration::toDt() %s\n", toChars());
235 dtxoff(pdt
, Type::typeinfo
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo
236 dtdword(pdt
, 0); // monitor
239 void TypeInfoConstDeclaration::toDt(dt_t
**pdt
)
241 //printf("TypeInfoConstDeclaration::toDt() %s\n", toChars());
242 dtxoff(pdt
, Type::typeinfoconst
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Const
243 dtdword(pdt
, 0); // monitor
244 Type
*tm
= tinfo
->mutableOf();
246 tm
->getTypeInfo(NULL
);
247 dtxoff(pdt
, tm
->vtinfo
->toSymbol(), 0, TYnptr
);
250 void TypeInfoInvariantDeclaration::toDt(dt_t
**pdt
)
252 //printf("TypeInfoInvariantDeclaration::toDt() %s\n", toChars());
253 dtxoff(pdt
, Type::typeinfoinvariant
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Invariant
254 dtdword(pdt
, 0); // monitor
255 Type
*tm
= tinfo
->mutableOf();
257 tm
->getTypeInfo(NULL
);
258 dtxoff(pdt
, tm
->vtinfo
->toSymbol(), 0, TYnptr
);
261 void TypeInfoTypedefDeclaration::toDt(dt_t
**pdt
)
263 //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars());
265 dtxoff(pdt
, Type::typeinfotypedef
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Typedef
266 dtdword(pdt
, 0); // monitor
268 assert(tinfo
->ty
== Ttypedef
);
270 TypeTypedef
*tc
= (TypeTypedef
*)tinfo
;
271 TypedefDeclaration
*sd
= tc
->sym
;
272 //printf("basetype = %s\n", sd->basetype->toChars());
280 sd
->basetype
= sd
->basetype
->merge();
281 sd
->basetype
->getTypeInfo(NULL
); // generate vtinfo
282 assert(sd
->basetype
->vtinfo
);
283 dtxoff(pdt
, sd
->basetype
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for basetype
285 char *name
= sd
->toPrettyChars();
286 size_t namelen
= strlen(name
);
287 dtdword(pdt
, namelen
);
288 dtabytes(pdt
, TYnptr
, 0, namelen
+ 1, name
);
291 if (tinfo
->isZeroInit() || !sd
->init
)
292 { // 0 initializer, or the same as the base type
293 dtdword(pdt
, 0); // init.length
294 dtdword(pdt
, 0); // init.ptr
298 dtdword(pdt
, sd
->type
->size()); // init.length
299 dtxoff(pdt
, sd
->toInitializer(), 0, TYnptr
); // init.ptr
303 void TypeInfoEnumDeclaration::toDt(dt_t
**pdt
)
305 //printf("TypeInfoEnumDeclaration::toDt()\n");
306 dtxoff(pdt
, Type::typeinfoenum
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Enum
307 dtdword(pdt
, 0); // monitor
309 assert(tinfo
->ty
== Tenum
);
311 TypeEnum
*tc
= (TypeEnum
*)tinfo
;
312 EnumDeclaration
*sd
= tc
->sym
;
321 { sd
->memtype
->getTypeInfo(NULL
);
322 dtxoff(pdt
, sd
->memtype
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for enum members
327 char *name
= sd
->toPrettyChars();
328 size_t namelen
= strlen(name
);
329 dtdword(pdt
, namelen
);
330 dtabytes(pdt
, TYnptr
, 0, namelen
+ 1, name
);
333 if (!sd
->defaultval
|| tinfo
->isZeroInit())
334 { // 0 initializer, or the same as the base type
335 dtdword(pdt
, 0); // init.length
336 dtdword(pdt
, 0); // init.ptr
340 dtdword(pdt
, sd
->type
->size()); // init.length
341 dtxoff(pdt
, sd
->toInitializer(), 0, TYnptr
); // init.ptr
345 void TypeInfoPointerDeclaration::toDt(dt_t
**pdt
)
347 //printf("TypeInfoPointerDeclaration::toDt()\n");
348 dtxoff(pdt
, Type::typeinfopointer
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Pointer
349 dtdword(pdt
, 0); // monitor
351 assert(tinfo
->ty
== Tpointer
);
353 TypePointer
*tc
= (TypePointer
*)tinfo
;
355 tc
->next
->getTypeInfo(NULL
);
356 dtxoff(pdt
, tc
->next
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for type being pointed to
359 void TypeInfoMaybeDeclaration::toDt(dt_t
**pdt
)
361 //printf("TypeInfoMaybeDeclaration::toDt()\n");
362 dtxoff(pdt
, Type::typeinfomaybe
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Maybe
363 dtdword(pdt
, 0); // monitor
365 assert(tinfo
->ty
== Tmaybe
);
367 TypeMaybe
*tc
= (TypeMaybe
*)tinfo
;
369 tc
->next
->getTypeInfo(NULL
);
370 dtxoff(pdt
, tc
->next
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for pointer type
373 void TypeInfoArrayDeclaration::toDt(dt_t
**pdt
)
375 //printf("TypeInfoArrayDeclaration::toDt()\n");
376 dtxoff(pdt
, Type::typeinfoarray
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Array
377 dtdword(pdt
, 0); // monitor
379 assert(tinfo
->ty
== Tarray
);
381 TypeDArray
*tc
= (TypeDArray
*)tinfo
;
383 tc
->next
->getTypeInfo(NULL
);
384 dtxoff(pdt
, tc
->next
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for array of type
387 void TypeInfoStaticArrayDeclaration::toDt(dt_t
**pdt
)
389 //printf("TypeInfoStaticArrayDeclaration::toDt()\n");
390 dtxoff(pdt
, Type::typeinfostaticarray
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_StaticArray
391 dtdword(pdt
, 0); // monitor
393 assert(tinfo
->ty
== Tsarray
);
395 TypeSArray
*tc
= (TypeSArray
*)tinfo
;
397 tc
->next
->getTypeInfo(NULL
);
398 dtxoff(pdt
, tc
->next
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for array of type
400 dtdword(pdt
, tc
->dim
->toInteger()); // length
403 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t
**pdt
)
405 //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
406 dtxoff(pdt
, Type::typeinfoassociativearray
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_AssociativeArray
407 dtdword(pdt
, 0); // monitor
409 assert(tinfo
->ty
== Taarray
);
411 TypeAArray
*tc
= (TypeAArray
*)tinfo
;
413 tc
->next
->getTypeInfo(NULL
);
414 dtxoff(pdt
, tc
->next
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for array of type
416 tc
->index
->getTypeInfo(NULL
);
417 dtxoff(pdt
, tc
->index
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for array of type
420 void TypeInfoFunctionDeclaration::toDt(dt_t
**pdt
)
422 //printf("TypeInfoFunctionDeclaration::toDt()\n");
423 dtxoff(pdt
, Type::typeinfofunction
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Function
424 dtdword(pdt
, 0); // monitor
426 assert(tinfo
->ty
== Tfunction
);
428 TypeFunction
*tc
= (TypeFunction
*)tinfo
;
430 tc
->next
->getTypeInfo(NULL
);
431 dtxoff(pdt
, tc
->next
->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for function return value
434 void TypeInfoDelegateDeclaration::toDt(dt_t
**pdt
)
436 //printf("TypeInfoDelegateDeclaration::toDt()\n");
437 dtxoff(pdt
, Type::typeinfodelegate
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Delegate
438 dtdword(pdt
, 0); // monitor
440 assert(tinfo
->ty
== Tdelegate
);
442 TypeDelegate
*tc
= (TypeDelegate
*)tinfo
;
444 tc
->next
->nextOf()->getTypeInfo(NULL
);
445 dtxoff(pdt
, tc
->next
->nextOf()->vtinfo
->toSymbol(), 0, TYnptr
); // TypeInfo for delegate return value
448 void TypeInfoStructDeclaration::toDt(dt_t
**pdt
)
450 //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
452 unsigned offset
= Type::typeinfostruct
->structsize
;
454 dtxoff(pdt
, Type::typeinfostruct
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfo_Struct
455 dtdword(pdt
, 0); // monitor
457 assert(tinfo
->ty
== Tstruct
);
459 TypeStruct
*tc
= (TypeStruct
*)tinfo
;
460 StructDeclaration
*sd
= tc
->sym
;
465 * hash_t function(in void*) xtoHash;
466 * int function(in void*, in void*) xopEquals;
467 * int function(in void*, in void*) xopCmp;
468 * string function(const(void)*) xtoString;
477 char *name
= sd
->toPrettyChars();
478 size_t namelen
= strlen(name
);
479 dtdword(pdt
, namelen
);
480 //dtabytes(pdt, TYnptr, 0, namelen + 1, name);
481 dtxoff(pdt
, toSymbol(), offset
, TYnptr
);
482 offset
+= namelen
+ 1;
485 dtdword(pdt
, sd
->structsize
); // init.length
487 dtdword(pdt
, 0); // NULL for 0 initialization
489 dtxoff(pdt
, sd
->toInitializer(), 0, TYnptr
); // init.ptr
492 FuncDeclaration
*fdx
;
497 static TypeFunction
*tftohash
;
498 static TypeFunction
*tftostring
;
504 tftohash
= new TypeFunction(NULL
, Type::thash_t
, 0, LINKd
);
505 tftohash
->mod
= MODconst
;
506 tftohash
= (TypeFunction
*)tftohash
->semantic(0, &sc
);
508 tftostring
= new TypeFunction(NULL
, Type::tchar
->invariantOf()->arrayOf(), 0, LINKd
);
509 tftostring
= (TypeFunction
*)tftostring
->semantic(0, &sc
);
512 TypeFunction
*tfeqptr
;
515 Arguments
*arguments
= new Arguments
;
516 Argument
*arg
= new Argument(STCin
, tc
->pointerTo(), NULL
, NULL
);
518 arguments
->push(arg
);
519 tfeqptr
= new TypeFunction(arguments
, Type::tint32
, 0, LINKd
);
520 tfeqptr
->mod
= MODconst
;
521 tfeqptr
= (TypeFunction
*)tfeqptr
->semantic(0, &sc
);
528 Array
*arguments
= new Array
;
529 Argument
*arg
= new Argument(In
, tc
, NULL
, NULL
);
531 arguments
->push(arg
);
532 tfeq
= new TypeFunction(arguments
, Type::tint32
, 0, LINKd
);
533 tfeq
= (TypeFunction
*)tfeq
->semantic(0, &sc
);
537 s
= search_function(sd
, Id::tohash
);
538 fdx
= s
? s
->isFuncDeclaration() : NULL
;
540 { fd
= fdx
->overloadExactMatch(tftohash
);
542 dtxoff(pdt
, fd
->toSymbol(), 0, TYnptr
);
544 //fdx->error("must be declared as extern (D) uint toHash()");
550 s
= search_function(sd
, Id::eq
);
551 fdx
= s
? s
->isFuncDeclaration() : NULL
;
552 for (int i
= 0; i
< 2; i
++)
555 { fd
= fdx
->overloadExactMatch(tfeqptr
);
557 dtxoff(pdt
, fd
->toSymbol(), 0, TYnptr
);
559 //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
565 s
= search_function(sd
, Id::cmp
);
566 fdx
= s
? s
->isFuncDeclaration() : NULL
;
569 s
= search_function(sd
, Id::tostring
);
570 fdx
= s
? s
->isFuncDeclaration() : NULL
;
572 { fd
= fdx
->overloadExactMatch(tftostring
);
574 dtxoff(pdt
, fd
->toSymbol(), 0, TYnptr
);
576 //fdx->error("must be declared as extern (D) char[] toString()");
583 dti32(pdt
, tc
->hasPointers(), false);
586 FuncDeclaration
*sgetmembers
= sd
->findGetMembers();
588 dtxoff(pdt
, sgetmembers
->toSymbol(), 0, TYnptr
);
590 dtdword(pdt
, 0); // xgetMembers
593 FuncDeclaration
*sdtor
= sd
->dtor
;
595 dtxoff(pdt
, sdtor
->toSymbol(), 0, TYnptr
);
597 dtdword(pdt
, 0); // xdtor
600 FuncDeclaration
*spostblit
= sd
->postblit
;
602 dtxoff(pdt
, spostblit
->toSymbol(), 0, TYnptr
);
604 dtdword(pdt
, 0); // xpostblit
607 dtnbytes(pdt
, namelen
+ 1, name
);
610 void TypeInfoClassDeclaration::toDt(dt_t
**pdt
)
612 //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
613 dtxoff(pdt
, Type::typeinfoclass
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfoClass
614 dtdword(pdt
, 0); // monitor
616 assert(tinfo
->ty
== Tclass
);
618 TypeClass
*tc
= (TypeClass
*)tinfo
;
621 if (!tc
->sym
->vclassinfo
)
622 tc
->sym
->vclassinfo
= new ClassInfoDeclaration(tc
->sym
);
623 s
= tc
->sym
->vclassinfo
->toSymbol();
624 dtxoff(pdt
, s
, 0, TYnptr
); // ClassInfo for tinfo
627 void TypeInfoInterfaceDeclaration::toDt(dt_t
**pdt
)
629 //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
630 dtxoff(pdt
, Type::typeinfointerface
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfoInterface
631 dtdword(pdt
, 0); // monitor
633 assert(tinfo
->ty
== Tclass
);
635 TypeClass
*tc
= (TypeClass
*)tinfo
;
638 if (!tc
->sym
->vclassinfo
)
639 tc
->sym
->vclassinfo
= new ClassInfoDeclaration(tc
->sym
);
640 s
= tc
->sym
->vclassinfo
->toSymbol();
641 dtxoff(pdt
, s
, 0, TYnptr
); // ClassInfo for tinfo
644 void TypeInfoTupleDeclaration::toDt(dt_t
**pdt
)
646 //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
647 dtxoff(pdt
, Type::typeinfotypelist
->toVtblSymbol(), 0, TYnptr
); // vtbl for TypeInfoInterface
648 dtdword(pdt
, 0); // monitor
650 assert(tinfo
->ty
== Ttuple
);
652 TypeTuple
*tu
= (TypeTuple
*)tinfo
;
654 size_t dim
= tu
->arguments
->dim
;
655 dtdword(pdt
, dim
); // elements.length
658 for (size_t i
= 0; i
< dim
; i
++)
659 { Argument
*arg
= (Argument
*)tu
->arguments
->data
[i
];
660 Expression
*e
= arg
->type
->getTypeInfo(NULL
);
661 e
= e
->optimize(WANTvalue
);
670 dtxoff(pdt
, s
, 0, TYnptr
); // elements.ptr
673 void TypeInfoDeclaration::toObjFile(int multiobj
)
679 //printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection);
690 parent
= this->toParent();
691 s
->Sclass
= SCcomdat
;
698 // See if we can convert a comdat to a comdef,
699 // which saves on exe file space.
700 if (s
->Sclass
== SCcomdat
&&
701 s
->Sdt
->dt
== DT_azeros
&&
702 s
->Sdt
->DTnext
== NULL
)
704 s
->Sclass
= SCglobal
;
705 s
->Sdt
->dt
= DT_common
;
709 if (s
->Sdt
&& s
->Sdt
->dt
== DT_azeros
&& s
->Sdt
->DTnext
== NULL
)
721 /* ========================================================================= */
723 /* These decide if there's an instance for them already in std.typeinfo,
724 * because then the compiler doesn't need to build one.
727 int Type::builtinTypeInfo()
732 int TypeBasic::builtinTypeInfo()
737 int TypeDArray::builtinTypeInfo()
739 return !mod
&& next
->isTypeBasic() != NULL
&& !next
->mod
;
742 /* ========================================================================= */
744 /***************************************
745 * Create a static array of TypeInfo references
746 * corresponding to an array of Expression's.
747 * Used to supply hidden _arguments[] value for variadic D functions.
750 Expression
*createTypeInfoArray(Scope
*sc
, Expression
*exps
[], int dim
)
753 /* Get the corresponding TypeInfo_Tuple and
754 * point at its elements[].
757 /* Create the TypeTuple corresponding to the types of args[]
759 Arguments
*args
= new Arguments
;
761 for (size_t i
= 0; i
< dim
; i
++)
762 { Argument
*arg
= new Argument(STCin
, exps
[i
]->type
, NULL
, NULL
);
763 args
->data
[i
] = (void *)arg
;
765 TypeTuple
*tup
= new TypeTuple(args
);
766 Expression
*e
= tup
->getTypeInfo(sc
);
767 e
= e
->optimize(WANTvalue
);
768 assert(e
->op
== TOKsymoff
); // should be SymOffExp
772 * Should just pass a reference to TypeInfo_Tuple instead,
773 * but that would require existing code to be recompiled.
774 * Source compatibility can be maintained by computing _arguments[]
775 * at the start of the called function by offseting into the
776 * TypeInfo_Tuple reference.
780 // Advance to elements[] member of TypeInfo_Tuple
781 SymOffExp
*se
= (SymOffExp
*)e
;
782 se
->offset
+= PTRSIZE
+ PTRSIZE
;
784 // Set type to TypeInfo[]*
785 se
->type
= Type::typeinfo
->type
->arrayOf()->pointerTo();
787 // Indirect to get the _arguments[] value
788 e
= new PtrExp(0, se
);
789 e
->type
= se
->type
->next
;
794 * 1) create an array literal instead,
795 * as it would eliminate the extra dereference of loading the
799 ArrayInitializer
*ai
= new ArrayInitializer(0);
807 // Generate identifier for _arguments[]
808 buf
.writestring("_arguments_");
809 for (int i
= 0; i
< dim
; i
++)
811 t
->toDecoBuffer(&buf
);
814 id
= Lexer::idPool((char *)buf
.data
);
817 Module
*m
= d_gcc_get_output_module();
819 Module
*m
= sc
->module
;
821 Dsymbol
*s
= m
->symtab
->lookup(id
);
823 if (s
&& s
->parent
== m
)
824 { // Use existing one
825 v
= s
->isVarDeclaration();
829 { // Generate new one
831 for (int i
= 0; i
< dim
; i
++)
833 e
= t
->getTypeInfo(sc
);
834 ai
->addInit(new IntegerExp(i
), new ExpInitializer(0, e
));
837 t
= Type::typeinfo
->type
->arrayOf();
839 v
= new VarDeclaration(0, t
, id
, ai
);
841 m
->symtab
->insert(v
);
844 sc
->stc
= STCstatic
| STCcomdat
;
850 e
= new VarExp(0, v
);