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, December 2006
22 #include "expression.h"
23 #include "statement.h"
24 #include "identifier.h"
25 #include "declaration.h"
26 #include "aggregate.h"
31 /********************************** Initializer *******************************/
33 Initializer::Initializer(Loc loc
)
38 Initializer
*Initializer::syntaxCopy()
43 Initializer
*Initializer::semantic(Scope
*sc
, Type
*t
)
48 Type
*Initializer::inferType(Scope
*sc
)
50 error(loc
, "cannot infer type from initializer");
54 Initializers
*Initializer::arraySyntaxCopy(Initializers
*ai
)
55 { Initializers
*a
= NULL
;
59 a
= new Initializers();
61 for (int i
= 0; i
< a
->dim
; i
++)
62 { Initializer
*e
= (Initializer
*)ai
->data
[i
];
71 char *Initializer::toChars()
75 memset(&hgs
, 0, sizeof(hgs
));
76 buf
= new OutBuffer();
78 return buf
->toChars();
81 /********************************** VoidInitializer ***************************/
83 VoidInitializer::VoidInitializer(Loc loc
)
90 Initializer
*VoidInitializer::syntaxCopy()
92 return new VoidInitializer(loc
);
96 Initializer
*VoidInitializer::semantic(Scope
*sc
, Type
*t
)
98 //printf("VoidInitializer::semantic(t = %p)\n", t);
104 Expression
*VoidInitializer::toExpression()
106 error(loc
, "void initializer has no value");
107 return new IntegerExp(0);
111 void VoidInitializer::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
113 buf
->writestring("void");
117 /********************************** StructInitializer *************************/
119 StructInitializer::StructInitializer(Loc loc
)
125 Initializer
*StructInitializer::syntaxCopy()
127 StructInitializer
*ai
= new StructInitializer(loc
);
129 assert(field
.dim
== value
.dim
);
130 ai
->field
.setDim(field
.dim
);
131 ai
->value
.setDim(value
.dim
);
132 for (int i
= 0; i
< field
.dim
; i
++)
134 ai
->field
.data
[i
] = field
.data
[i
];
136 Initializer
*init
= (Initializer
*)value
.data
[i
];
137 init
= init
->syntaxCopy();
138 ai
->value
.data
[i
] = init
;
143 void StructInitializer::addInit(Identifier
*field
, Initializer
*value
)
145 //printf("StructInitializer::addInit(field = %p, value = %p)\n", field, value);
146 this->field
.push(field
);
147 this->value
.push(value
);
150 Initializer
*StructInitializer::semantic(Scope
*sc
, Type
*t
)
155 //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars());
156 vars
.setDim(field
.dim
);
158 if (t
->ty
== Tstruct
)
162 ts
= (TypeStruct
*)t
;
164 for (i
= 0; i
< field
.dim
; i
++)
166 Identifier
*id
= (Identifier
*)field
.data
[i
];
167 Initializer
*val
= (Initializer
*)value
.data
[i
];
173 if (fieldi
>= ad
->fields
.dim
)
174 { error(loc
, "too many initializers for %s", ad
->toChars());
181 s
= (Dsymbol
*)ad
->fields
.data
[fieldi
];
186 //s = ad->symtab->lookup(id);
187 s
= ad
->search(loc
, id
, 0);
190 error(loc
, "'%s' is not a member of '%s'", id
->toChars(), t
->toChars());
194 // Find out which field index it is
195 for (fieldi
= 0; 1; fieldi
++)
197 if (fieldi
>= ad
->fields
.dim
)
199 s
->error("is not a per-instance initializable field");
202 if (s
== (Dsymbol
*)ad
->fields
.data
[fieldi
])
206 if (s
&& (v
= s
->isVarDeclaration()) != NULL
)
208 val
= val
->semantic(sc
, v
->type
);
209 value
.data
[i
] = (void *)val
;
210 vars
.data
[i
] = (void *)v
;
213 { error(loc
, "%s is not a field of %s", id
? id
->toChars() : s
->toChars(), ad
->toChars());
219 else if (t
->ty
== Tdelegate
&& value
.dim
== 0)
220 { /* Rewrite as empty delegate literal { }
222 Arguments
*arguments
= new Arguments
;
223 Type
*tf
= new TypeFunction(arguments
, NULL
, 0, LINKd
);
224 FuncLiteralDeclaration
*fd
= new FuncLiteralDeclaration(loc
, 0, tf
, TOKdelegate
, NULL
);
225 fd
->fbody
= new CompoundStatement(loc
, new Statements());
227 Expression
*e
= new FuncExp(loc
, fd
);
228 ExpInitializer
*ie
= new ExpInitializer(loc
, e
);
229 return ie
->semantic(sc
, t
);
233 error(loc
, "a struct is not a valid initializer for a %s", t
->toChars());
246 /***************************************
247 * This works by transforming a struct initializer into
248 * a struct literal. In the future, the two should be the
251 Expression
*StructInitializer::toExpression()
254 //printf("StructInitializer::toExpression() %s\n", toChars());
255 if (!ad
) // if fwd referenced
259 StructDeclaration
*sd
= ad
->isStructDeclaration();
262 Expressions
*elements
= new Expressions();
263 for (size_t i
= 0; i
< value
.dim
; i
++)
267 Initializer
*iz
= (Initializer
*)value
.data
[i
];
270 Expression
*ex
= iz
->toExpression();
275 e
= new StructLiteralExp(loc
, sd
, elements
);
281 //error(loc, "struct initializers as expressions are not allowed");
286 void StructInitializer::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
288 //printf("StructInitializer::toCBuffer()\n");
290 for (int i
= 0; i
< field
.dim
; i
++)
294 Identifier
*id
= (Identifier
*)field
.data
[i
];
297 buf
->writestring(id
->toChars());
300 Initializer
*iz
= (Initializer
*)value
.data
[i
];
302 iz
->toCBuffer(buf
, hgs
);
307 /********************************** ArrayInitializer ************************************/
309 ArrayInitializer::ArrayInitializer(Loc loc
)
317 Initializer
*ArrayInitializer::syntaxCopy()
319 //printf("ArrayInitializer::syntaxCopy()\n");
321 ArrayInitializer
*ai
= new ArrayInitializer(loc
);
323 assert(index
.dim
== value
.dim
);
324 ai
->index
.setDim(index
.dim
);
325 ai
->value
.setDim(value
.dim
);
326 for (int i
= 0; i
< ai
->value
.dim
; i
++)
327 { Expression
*e
= (Expression
*)index
.data
[i
];
330 ai
->index
.data
[i
] = e
;
332 Initializer
*init
= (Initializer
*)value
.data
[i
];
333 init
= init
->syntaxCopy();
334 ai
->value
.data
[i
] = init
;
339 void ArrayInitializer::addInit(Expression
*index
, Initializer
*value
)
341 this->index
.push(index
);
342 this->value
.push(value
);
347 Initializer
*ArrayInitializer::semantic(Scope
*sc
, Type
*t
)
351 //printf("ArrayInitializer::semantic(%s)\n", t->toChars());
352 if (sem
) // if semantic() already run
365 error(loc
, "cannot use array to initialize %s", type
->toChars());
370 for (i
= 0; i
< index
.dim
; i
++)
374 idx
= (Expression
*)index
.data
[i
];
376 { idx
= idx
->semantic(sc
);
377 idx
= idx
->optimize(WANTvalue
| WANTinterpret
);
378 index
.data
[i
] = (void *)idx
;
379 length
= idx
->toInteger();
382 val
= (Initializer
*)value
.data
[i
];
383 val
= val
->semantic(sc
, t
->nextOf());
384 value
.data
[i
] = (void *)val
;
387 error("array dimension overflow");
391 uintmax_t amax
= 0x80000000;
392 if ((uintmax_t) dim
* t
->nextOf()->size() >= amax
)
393 error(loc
, "array dimension %"PRIuTSIZE
" exceeds max of %"PRIuMAX
, dim
, amax
/ t
->nextOf()->size());
397 /********************************
398 * If possible, convert array initializer to array literal.
401 Expression
*ArrayInitializer::toExpression()
402 { Expressions
*elements
;
405 //printf("ArrayInitializer::toExpression()\n");
406 //static int i; if (++i == 2) halt();
407 elements
= new Expressions();
408 for (size_t i
= 0; i
< value
.dim
; i
++)
412 Initializer
*iz
= (Initializer
*)value
.data
[i
];
415 Expression
*ex
= iz
->toExpression();
420 e
= new ArrayLiteralExp(loc
, elements
);
426 error(loc
, "array initializers as expressions are not allowed");
431 /********************************
432 * If possible, convert array initializer to associative array initializer.
435 Initializer
*ArrayInitializer::toAssocArrayInitializer()
440 //printf("ArrayInitializer::toAssocArrayInitializer()\n");
441 //static int i; if (++i == 2) halt();
442 keys
= new Expressions();
443 keys
->setDim(value
.dim
);
444 values
= new Expressions();
445 values
->setDim(value
.dim
);
447 for (size_t i
= 0; i
< value
.dim
; i
++)
449 e
= (Expression
*)index
.data
[i
];
452 keys
->data
[i
] = (void *)e
;
454 Initializer
*iz
= (Initializer
*)value
.data
[i
];
457 e
= iz
->toExpression();
460 values
->data
[i
] = (void *)e
;
462 e
= new AssocArrayLiteralExp(loc
, keys
, values
);
463 return new ExpInitializer(loc
, e
);
468 error(loc
, "not an associative array initializer");
473 Type
*ArrayInitializer::inferType(Scope
*sc
)
475 for (size_t i
= 0; i
< value
.dim
; i
++)
482 Initializer
*iz
= (Initializer
*)value
.data
[0];
484 { Type
*t
= iz
->inferType(sc
);
485 t
= new TypeSArray(t
, new IntegerExp(value
.dim
));
486 t
= t
->semantic(loc
, sc
);
492 error(loc
, "cannot infer type from this array initializer");
497 void ArrayInitializer::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
500 for (int i
= 0; i
< index
.dim
; i
++)
504 Expression
*ex
= (Expression
*)index
.data
[i
];
507 ex
->toCBuffer(buf
, hgs
);
510 Initializer
*iz
= (Initializer
*)value
.data
[i
];
512 iz
->toCBuffer(buf
, hgs
);
518 /********************************** ExpInitializer ************************************/
520 ExpInitializer::ExpInitializer(Loc loc
, Expression
*exp
)
526 Initializer
*ExpInitializer::syntaxCopy()
528 return new ExpInitializer(loc
, exp
->syntaxCopy());
531 Initializer
*ExpInitializer::semantic(Scope
*sc
, Type
*t
)
533 //printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
534 exp
= exp
->semantic(sc
);
535 exp
= exp
->optimize(WANTvalue
| WANTinterpret
);
536 Type
*tb
= t
->toBasetype();
538 /* Look for case of initializing a static array with a too-short
539 * string literal, such as:
540 * char[5] foo = "abc";
541 * Allow this by doing an explicit cast, which will lengthen the string
544 if (exp
->op
== TOKstring
&& tb
->ty
== Tsarray
&& exp
->type
->ty
== Tsarray
)
545 { StringExp
*se
= (StringExp
*)exp
;
547 if (!se
->committed
&& se
->type
->ty
== Tsarray
&&
548 ((TypeSArray
*)se
->type
)->dim
->toInteger() <
549 ((TypeSArray
*)t
)->dim
->toInteger())
551 exp
= se
->castTo(sc
, t
);
556 // Look for the case of statically initializing an array
557 // with a single member.
558 if (tb
->ty
== Tsarray
&&
559 !tb
->nextOf()->equals(exp
->type
->toBasetype()->nextOf()) &&
560 exp
->implicitConvTo(tb
->nextOf())
566 exp
= exp
->implicitCastTo(sc
, t
);
568 exp
= exp
->optimize(WANTvalue
| WANTinterpret
);
569 //printf("-ExpInitializer::semantic(): "); exp->print();
573 Type
*ExpInitializer::inferType(Scope
*sc
)
575 //printf("ExpInitializer::inferType() %s\n", toChars());
576 exp
= exp
->semantic(sc
);
577 exp
= resolveProperties(sc
, exp
);
579 // Give error for overloaded function addresses
580 if (exp
->op
== TOKsymoff
)
581 { SymOffExp
*se
= (SymOffExp
*)exp
;
582 if (se
->hasOverloads
&& !se
->var
->isFuncDeclaration()->isUnique())
583 exp
->error("cannot infer type from overloaded function symbol %s", exp
->toChars());
588 //return t->ty == Tsarray ? t : t->toHeadMutable();
591 Expression
*ExpInitializer::toExpression()
597 void ExpInitializer::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
599 exp
->toCBuffer(buf
, hgs
);