summaryrefslogtreecommitdiff
path: root/gcc/d/dmd/initsem.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/d/dmd/initsem.c')
-rw-r--r--gcc/d/dmd/initsem.c914
1 files changed, 0 insertions, 914 deletions
diff --git a/gcc/d/dmd/initsem.c b/gcc/d/dmd/initsem.c
deleted file mode 100644
index c7d1dfe0deb..00000000000
--- a/gcc/d/dmd/initsem.c
+++ /dev/null
@@ -1,914 +0,0 @@
-
-/* Compiler implementation of the D programming language
- * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
- * written by Walter Bright
- * http://www.digitalmars.com
- * Distributed under the Boost Software License, Version 1.0.
- * http://www.boost.org/LICENSE_1_0.txt
- */
-
-#include "root/checkedint.h"
-#include "mars.h"
-#include "init.h"
-#include "expression.h"
-#include "statement.h"
-#include "declaration.h"
-#include "aggregate.h"
-#include "scope.h"
-#include "mtype.h"
-#include "template.h"
-#include "id.h"
-
-FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL);
-Initializer *inferType(Initializer *init, Scope *sc);
-bool hasNonConstPointers(Expression *e);
-
-class InitializerSemanticVisitor : public Visitor
-{
-public:
- Initializer *result;
- Scope *sc;
- Type *t;
- NeedInterpret needInterpret;
-
- InitializerSemanticVisitor(Scope *sc, Type *t, NeedInterpret needInterpret)
- {
- this->result = NULL;
- this->sc = sc;
- this->t = t;
- this->needInterpret = needInterpret;
- }
-
- void visit(ErrorInitializer *i)
- {
- //printf("ErrorInitializer::semantic(t = %p)\n", t);
- result = i;
- }
-
- void visit(VoidInitializer *i)
- {
- //printf("VoidInitializer::semantic(t = %p)\n", t);
- i->type = t;
- result = i;
- }
-
- void visit(StructInitializer *i)
- {
- //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars());
- t = t->toBasetype();
- if (t->ty == Tsarray && t->nextOf()->toBasetype()->ty == Tstruct)
- t = t->nextOf()->toBasetype();
- if (t->ty == Tstruct)
- {
- StructDeclaration *sd = ((TypeStruct *)t)->sym;
- if (sd->ctor)
- {
- error(i->loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead",
- sd->kind(), sd->toChars(), sd->toChars());
- result = new ErrorInitializer();
- return;
- }
- sd->size(i->loc);
- if (sd->sizeok != SIZEOKdone)
- {
- result = new ErrorInitializer();
- return;
- }
- size_t nfields = sd->fields.length - sd->isNested();
-
- //expandTuples for non-identity arguments?
-
- Expressions *elements = new Expressions();
- elements->setDim(nfields);
- for (size_t j = 0; j < elements->length; j++)
- (*elements)[j] = NULL;
-
- // Run semantic for explicitly given initializers
- // TODO: this part is slightly different from StructLiteralExp::semantic.
- bool errors = false;
- for (size_t fieldi = 0, j = 0; j < i->field.length; j++)
- {
- if (Identifier *id = i->field[j])
- {
- Dsymbol *s = sd->search(i->loc, id);
- if (!s)
- {
- s = sd->search_correct(id);
- if (s)
- error(i->loc, "`%s` is not a member of `%s`, did you mean %s `%s`?",
- id->toChars(), sd->toChars(), s->kind(), s->toChars());
- else
- error(i->loc, "`%s` is not a member of `%s`", id->toChars(), sd->toChars());
- result = new ErrorInitializer();
- return;
- }
- s = s->toAlias();
-
- // Find out which field index it is
- for (fieldi = 0; 1; fieldi++)
- {
- if (fieldi >= nfields)
- {
- error(i->loc, "%s.%s is not a per-instance initializable field",
- sd->toChars(), s->toChars());
- result = new ErrorInitializer();
- return;
- }
- if (s == sd->fields[fieldi])
- break;
- }
- }
- else if (fieldi >= nfields)
- {
- error(i->loc, "too many initializers for %s", sd->toChars());
- result = new ErrorInitializer();
- return;
- }
-
- VarDeclaration *vd = sd->fields[fieldi];
- if ((*elements)[fieldi])
- {
- error(i->loc, "duplicate initializer for field `%s`", vd->toChars());
- errors = true;
- continue;
- }
- for (size_t k = 0; k < nfields; k++)
- {
- VarDeclaration *v2 = sd->fields[k];
- if (vd->isOverlappedWith(v2) && (*elements)[k])
- {
- error(i->loc, "overlapping initialization for field %s and %s",
- v2->toChars(), vd->toChars());
- errors = true;
- continue;
- }
- }
-
- assert(sc);
- Initializer *iz = i->value[j];
- iz = initializerSemantic(iz, sc, vd->type->addMod(t->mod), needInterpret);
- Expression *ex = initializerToExpression(iz);
- if (ex->op == TOKerror)
- {
- errors = true;
- continue;
- }
- i->value[j] = iz;
- (*elements)[fieldi] = doCopyOrMove(sc, ex);
- ++fieldi;
- }
- if (errors)
- {
- result = new ErrorInitializer();
- return;
- }
-
- StructLiteralExp *sle = new StructLiteralExp(i->loc, sd, elements, t);
- if (!sd->fill(i->loc, elements, false))
- {
- result = new ErrorInitializer();
- return;
- }
- sle->type = t;
-
- ExpInitializer *ie = new ExpInitializer(i->loc, sle);
- result = initializerSemantic(ie, sc, t, needInterpret);
- return;
- }
- else if ((t->ty == Tdelegate || (t->ty == Tpointer && t->nextOf()->ty == Tfunction)) && i->value.length == 0)
- {
- TOK tok = (t->ty == Tdelegate) ? TOKdelegate : TOKfunction;
- /* Rewrite as empty delegate literal { }
- */
- Type *tf = new TypeFunction(ParameterList(), NULL, LINKd);
- FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(i->loc, Loc(), tf, tok, NULL);
- fd->fbody = new CompoundStatement(i->loc, new Statements());
- fd->endloc = i->loc;
- Expression *e = new FuncExp(i->loc, fd);
- ExpInitializer *ie = new ExpInitializer(i->loc, e);
- result = initializerSemantic(ie, sc, t, needInterpret);
- return;
- }
-
- error(i->loc, "a struct is not a valid initializer for a %s", t->toChars());
- result = new ErrorInitializer();
- }
-
- void visit(ArrayInitializer *i)
- {
- unsigned length;
- const unsigned amax = 0x80000000;
- bool errors = false;
-
- //printf("ArrayInitializer::semantic(%s)\n", t->toChars());
- if (i->sem) // if semantic() already run
- {
- result = i;
- return;
- }
- i->sem = true;
- t = t->toBasetype();
- switch (t->ty)
- {
- case Tsarray:
- case Tarray:
- break;
-
- case Tvector:
- t = ((TypeVector *)t)->basetype;
- break;
-
- case Taarray:
- case Tstruct: // consider implicit constructor call
- {
- Expression *e;
- // note: MyStruct foo = [1:2, 3:4] is correct code if MyStruct has a this(int[int])
- if (t->ty == Taarray || i->isAssociativeArray())
- e = i->toAssocArrayLiteral();
- else
- e = initializerToExpression(i);
- if (!e) // Bugzilla 13987
- {
- error(i->loc, "cannot use array to initialize %s", t->toChars());
- goto Lerr;
- }
- ExpInitializer *ei = new ExpInitializer(e->loc, e);
- result = initializerSemantic(ei, sc, t, needInterpret);
- return;
- }
- case Tpointer:
- if (t->nextOf()->ty != Tfunction)
- break;
- /* fall through */
-
- default:
- error(i->loc, "cannot use array to initialize %s", t->toChars());
- goto Lerr;
- }
-
- i->type = t;
-
- length = 0;
- for (size_t j = 0; j < i->index.length; j++)
- {
- Expression *idx = i->index[j];
- if (idx)
- {
- sc = sc->startCTFE();
- idx = expressionSemantic(idx, sc);
- sc = sc->endCTFE();
- idx = idx->ctfeInterpret();
- i->index[j] = idx;
- const uinteger_t idxvalue = idx->toInteger();
- if (idxvalue >= amax)
- {
- error(i->loc, "array index %llu overflow", (ulonglong)idxvalue);
- errors = true;
- }
- length = (unsigned)idx->toInteger();
- if (idx->op == TOKerror)
- errors = true;
- }
-
- Initializer *val = i->value[j];
- ExpInitializer *ei = val->isExpInitializer();
- if (ei && !idx)
- ei->expandTuples = true;
- val = initializerSemantic(val, sc, t->nextOf(), needInterpret);
- if (val->isErrorInitializer())
- errors = true;
-
- ei = val->isExpInitializer();
- // found a tuple, expand it
- if (ei && ei->exp->op == TOKtuple)
- {
- TupleExp *te = (TupleExp *)ei->exp;
- i->index.remove(j);
- i->value.remove(j);
-
- for (size_t k = 0; k < te->exps->length; ++k)
- {
- Expression *e = (*te->exps)[k];
- i->index.insert(j + k, (Expression *)NULL);
- i->value.insert(j + k, new ExpInitializer(e->loc, e));
- }
- j--;
- continue;
- }
- else
- {
- i->value[j] = val;
- }
-
- length++;
- if (length == 0)
- {
- error(i->loc, "array dimension overflow");
- goto Lerr;
- }
- if (length > i->dim)
- i->dim = length;
- }
- if (t->ty == Tsarray)
- {
- uinteger_t edim = ((TypeSArray *)t)->dim->toInteger();
- if (i->dim > edim)
- {
- error(i->loc, "array initializer has %u elements, but array length is %llu", i->dim, (ulonglong)edim);
- goto Lerr;
- }
- }
- if (errors)
- goto Lerr;
- else
- {
- d_uns64 sz = t->nextOf()->size();
- bool overflow = false;
- const d_uns64 max = mulu((d_uns64)i->dim, sz, overflow);
- if (overflow || max > amax)
- {
- error(i->loc, "array dimension %llu exceeds max of %llu", (ulonglong)i->dim, (ulonglong)(amax / sz));
- goto Lerr;
- }
- result = i;
- return;
- }
-
- Lerr:
- result = new ErrorInitializer();
- }
-
- void visit(ExpInitializer *i)
- {
- //printf("ExpInitializer::semantic(%s), type = %s\n", i->exp->toChars(), t->toChars());
- if (needInterpret) sc = sc->startCTFE();
- i->exp = expressionSemantic(i->exp, sc);
- i->exp = resolveProperties(sc, i->exp);
- if (needInterpret) sc = sc->endCTFE();
- if (i->exp->op == TOKerror)
- {
- result = new ErrorInitializer();
- return;
- }
-
- unsigned int olderrors = global.errors;
- if (needInterpret)
- {
- // If the result will be implicitly cast, move the cast into CTFE
- // to avoid premature truncation of polysemous types.
- // eg real [] x = [1.1, 2.2]; should use real precision.
- if (i->exp->implicitConvTo(t))
- {
- i->exp = i->exp->implicitCastTo(sc, t);
- }
- if (!global.gag && olderrors != global.errors)
- {
- result = i;
- return;
- }
- i->exp = i->exp->ctfeInterpret();
- }
- else
- {
- i->exp = i->exp->optimize(WANTvalue);
- }
- if (!global.gag && olderrors != global.errors)
- {
- result = i; // Failed, suppress duplicate error messages
- return;
- }
-
- if (i->exp->type->ty == Ttuple && ((TypeTuple *)i->exp->type)->arguments->length == 0)
- {
- Type *et = i->exp->type;
- i->exp = new TupleExp(i->exp->loc, new Expressions());
- i->exp->type = et;
- }
- if (i->exp->op == TOKtype)
- {
- i->exp->error("initializer must be an expression, not `%s`", i->exp->toChars());
- result = new ErrorInitializer();
- return;
- }
-
- // Make sure all pointers are constants
- if (needInterpret && hasNonConstPointers(i->exp))
- {
- i->exp->error("cannot use non-constant CTFE pointer in an initializer `%s`", i->exp->toChars());
- result = new ErrorInitializer();
- return;
- }
-
- Type *tb = t->toBasetype();
- Type *ti = i->exp->type->toBasetype();
-
- if (i->exp->op == TOKtuple && i->expandTuples && !i->exp->implicitConvTo(t))
- {
- result = new ExpInitializer(i->loc, i->exp);
- return;
- }
-
- /* Look for case of initializing a static array with a too-short
- * string literal, such as:
- * char[5] foo = "abc";
- * Allow this by doing an explicit cast, which will lengthen the string
- * literal.
- */
- if (i->exp->op == TOKstring && tb->ty == Tsarray)
- {
- StringExp *se = (StringExp *)i->exp;
- Type *typeb = se->type->toBasetype();
- TY tynto = tb->nextOf()->ty;
- if (!se->committed &&
- (typeb->ty == Tarray || typeb->ty == Tsarray) &&
- (tynto == Tchar || tynto == Twchar || tynto == Tdchar) &&
- se->numberOfCodeUnits(tynto) < ((TypeSArray *)tb)->dim->toInteger())
- {
- i->exp = se->castTo(sc, t);
- goto L1;
- }
- }
-
- // Look for implicit constructor call
- if (tb->ty == Tstruct &&
- !(ti->ty == Tstruct && tb->toDsymbol(sc) == ti->toDsymbol(sc)) &&
- !i->exp->implicitConvTo(t))
- {
- StructDeclaration *sd = ((TypeStruct *)tb)->sym;
- if (sd->ctor)
- {
- // Rewrite as S().ctor(exp)
- Expression *e;
- e = new StructLiteralExp(i->loc, sd, NULL);
- e = new DotIdExp(i->loc, e, Id::ctor);
- e = new CallExp(i->loc, e, i->exp);
- e = expressionSemantic(e, sc);
- if (needInterpret)
- i->exp = e->ctfeInterpret();
- else
- i->exp = e->optimize(WANTvalue);
- }
- }
-
- // Look for the case of statically initializing an array
- // with a single member.
- if (tb->ty == Tsarray &&
- !tb->nextOf()->equals(ti->toBasetype()->nextOf()) &&
- i->exp->implicitConvTo(tb->nextOf())
- )
- {
- /* If the variable is not actually used in compile time, array creation is
- * redundant. So delay it until invocation of toExpression() or toDt().
- */
- t = tb->nextOf();
- }
-
- if (i->exp->implicitConvTo(t))
- {
- i->exp = i->exp->implicitCastTo(sc, t);
- }
- else
- {
- // Look for mismatch of compile-time known length to emit
- // better diagnostic message, as same as AssignExp::semantic.
- if (tb->ty == Tsarray &&
- i->exp->implicitConvTo(tb->nextOf()->arrayOf()) > MATCHnomatch)
- {
- uinteger_t dim1 = ((TypeSArray *)tb)->dim->toInteger();
- uinteger_t dim2 = dim1;
- if (i->exp->op == TOKarrayliteral)
- {
- ArrayLiteralExp *ale = (ArrayLiteralExp *)i->exp;
- dim2 = ale->elements ? ale->elements->length : 0;
- }
- else if (i->exp->op == TOKslice)
- {
- Type *tx = toStaticArrayType((SliceExp *)i->exp);
- if (tx)
- dim2 = ((TypeSArray *)tx)->dim->toInteger();
- }
- if (dim1 != dim2)
- {
- i->exp->error("mismatched array lengths, %d and %d", (int)dim1, (int)dim2);
- i->exp = new ErrorExp();
- }
- }
- i->exp = i->exp->implicitCastTo(sc, t);
- }
- L1:
- if (i->exp->op == TOKerror)
- {
- result = i;
- return;
- }
- if (needInterpret)
- i->exp = i->exp->ctfeInterpret();
- else
- i->exp = i->exp->optimize(WANTvalue);
- //printf("-ExpInitializer::semantic(): "); i->exp->print();
- result = i;
- }
-};
-
-// Performs semantic analisys on Initializer AST nodes
-Initializer *initializerSemantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret)
-{
- InitializerSemanticVisitor v = InitializerSemanticVisitor(sc, t, needInterpret);
- init->accept(&v);
- return v.result;
-}
-
-class InferTypeVisitor : public Visitor
-{
-public:
- Initializer *result;
- Scope *sc;
-
- InferTypeVisitor(Scope *sc)
- {
- this->result = NULL;
- this->sc = sc;
- }
-
- void visit(ErrorInitializer *i)
- {
- result = i;
- }
-
- void visit(VoidInitializer *i)
- {
- error(i->loc, "cannot infer type from void initializer");
- result = new ErrorInitializer();
- }
-
- void visit(StructInitializer *i)
- {
- error(i->loc, "cannot infer type from struct initializer");
- result = new ErrorInitializer();
- }
-
- void visit(ArrayInitializer *init)
- {
- //printf("ArrayInitializer::inferType() %s\n", init->toChars());
- Expressions *keys = NULL;
- Expressions *values;
- if (init->isAssociativeArray())
- {
- keys = new Expressions();
- keys->setDim(init->value.length);
- values = new Expressions();
- values->setDim(init->value.length);
-
- for (size_t i = 0; i < init->value.length; i++)
- {
- Expression *e = init->index[i];
- if (!e)
- goto Lno;
- (*keys)[i] = e;
-
- Initializer *iz = init->value[i];
- if (!iz)
- goto Lno;
- iz = inferType(iz, sc);
- if (iz->isErrorInitializer())
- {
- result = iz;
- return;
- }
- assert(iz->isExpInitializer());
- (*values)[i] = ((ExpInitializer *)iz)->exp;
- assert((*values)[i]->op != TOKerror);
- }
-
- Expression *e = new AssocArrayLiteralExp(init->loc, keys, values);
- ExpInitializer *ei = new ExpInitializer(init->loc, e);
- result = inferType(ei, sc);
- return;
- }
- else
- {
- Expressions *elements = new Expressions();
- elements->setDim(init->value.length);
- elements->zero();
-
- for (size_t i = 0; i < init->value.length; i++)
- {
- assert(!init->index[i]); // already asserted by isAssociativeArray()
-
- Initializer *iz = init->value[i];
- if (!iz)
- goto Lno;
- iz = inferType(iz, sc);
- if (iz->isErrorInitializer())
- {
- result = iz;
- return;
- }
- assert(iz->isExpInitializer());
- (*elements)[i] = ((ExpInitializer *)iz)->exp;
- assert((*elements)[i]->op != TOKerror);
- }
-
- Expression *e = new ArrayLiteralExp(init->loc, NULL, elements);
- ExpInitializer *ei = new ExpInitializer(init->loc, e);
- result = inferType(ei, sc);
- return;
- }
- Lno:
- if (keys)
- {
- delete keys;
- delete values;
- error(init->loc, "not an associative array initializer");
- }
- else
- {
- error(init->loc, "cannot infer type from array initializer");
- }
- result = new ErrorInitializer();
- }
-
- void visit(ExpInitializer *init)
- {
- //printf("ExpInitializer::inferType() %s\n", init->toChars());
- init->exp = expressionSemantic(init->exp, sc);
- init->exp = resolveProperties(sc, init->exp);
-
- if (init->exp->op == TOKscope)
- {
- ScopeExp *se = (ScopeExp *)init->exp;
- TemplateInstance *ti = se->sds->isTemplateInstance();
- if (ti && ti->semanticRun == PASSsemantic && !ti->aliasdecl)
- se->error("cannot infer type from %s %s, possible circular dependency", se->sds->kind(), se->toChars());
- else
- se->error("cannot infer type from %s %s", se->sds->kind(), se->toChars());
- result = new ErrorInitializer();
- return;
- }
-
- // Give error for overloaded function addresses
- bool hasOverloads = false;
- if (FuncDeclaration *f = isFuncAddress(init->exp, &hasOverloads))
- {
- if (f->checkForwardRef(init->loc))
- {
- result = new ErrorInitializer();
- return;
- }
-
- if (hasOverloads && !f->isUnique())
- {
- init->exp->error("cannot infer type from overloaded function symbol %s", init->exp->toChars());
- result = new ErrorInitializer();
- return;
- }
- }
- if (init->exp->op == TOKaddress)
- {
- AddrExp *ae = (AddrExp *)init->exp;
- if (ae->e1->op == TOKoverloadset)
- {
- init->exp->error("cannot infer type from overloaded function symbol %s", init->exp->toChars());
- result = new ErrorInitializer();
- return;
- }
- }
-
- if (init->exp->op == TOKerror)
- {
- result = new ErrorInitializer();
- return;
- }
- if (!init->exp->type)
- {
- result = new ErrorInitializer();
- return;
- }
- result = init;
- }
-};
-
-/* Translates to an expression to infer type.
- * Returns ExpInitializer or ErrorInitializer.
- */
-Initializer *inferType(Initializer *init, Scope *sc)
-{
- InferTypeVisitor v = InferTypeVisitor(sc);
- init->accept(&v);
- return v.result;
-}
-
-class InitToExpressionVisitor : public Visitor
-{
-public:
- Expression *result;
- Type *itype;
-
- InitToExpressionVisitor(Type *itype)
- {
- this->result = NULL;
- this->itype = itype;
- }
-
- void visit(ErrorInitializer *)
- {
- result = new ErrorExp();
- }
-
- void visit(VoidInitializer *)
- {
- result = NULL;
- }
-
- /***************************************
- * This works by transforming a struct initializer into
- * a struct literal. In the future, the two should be the
- * same thing.
- */
- void visit(StructInitializer *)
- {
- // cannot convert to an expression without target 'ad'
- result = NULL;
- }
-
- /********************************
- * If possible, convert array initializer to array literal.
- * Otherwise return NULL.
- */
-
- void visit(ArrayInitializer *init)
- {
- //printf("ArrayInitializer::toExpression(), dim = %d\n", init->length);
- //static int i; if (++i == 2) halt();
-
- Expressions *elements;
- unsigned edim;
- const unsigned amax = 0x80000000;
- Type *t = NULL;
- if (init->type)
- {
- if (init->type == Type::terror)
- {
- result = new ErrorExp();
- return;
- }
-
- t = init->type->toBasetype();
- switch (t->ty)
- {
- case Tvector:
- t = ((TypeVector *)t)->basetype;
- /* fall through */
-
- case Tsarray:
- {
- uinteger_t adim = ((TypeSArray *)t)->dim->toInteger();
- if (adim >= amax)
- goto Lno;
- edim = (unsigned)adim;
- break;
- }
-
- case Tpointer:
- case Tarray:
- edim = init->dim;
- break;
-
- default:
- assert(0);
- }
- }
- else
- {
- edim = (unsigned)init->value.length;
- for (size_t i = 0, j = 0; i < init->value.length; i++, j++)
- {
- if (init->index[i])
- {
- if (init->index[i]->op == TOKint64)
- {
- const uinteger_t idxval = init->index[i]->toInteger();
- if (idxval >= amax)
- goto Lno;
- j = (size_t)idxval;
- }
- else
- goto Lno;
- }
- if (j >= edim)
- edim = (unsigned)(j + 1);
- }
- }
-
- elements = new Expressions();
- elements->setDim(edim);
- elements->zero();
- for (size_t i = 0, j = 0; i < init->value.length; i++, j++)
- {
- if (init->index[i])
- j = (size_t)(init->index[i])->toInteger();
- assert(j < edim);
- Initializer *iz = init->value[i];
- if (!iz)
- goto Lno;
- Expression *ex = initializerToExpression(iz);
- if (!ex)
- {
- goto Lno;
- }
- (*elements)[j] = ex;
- }
-
- /* Fill in any missing elements with the default initializer
- */
- {
- Expression *_init = NULL;
- for (size_t i = 0; i < edim; i++)
- {
- if (!(*elements)[i])
- {
- if (!init->type)
- goto Lno;
- if (!_init)
- _init = ((TypeNext *)t)->next->defaultInit();
- (*elements)[i] = _init;
- }
- }
-
- /* Expand any static array initializers that are a single expression
- * into an array of them
- */
- if (t)
- {
- Type *tn = t->nextOf()->toBasetype();
- if (tn->ty == Tsarray)
- {
- size_t dim = ((TypeSArray *)tn)->dim->toInteger();
- Type *te = tn->nextOf()->toBasetype();
- for (size_t i = 0; i < elements->length; i++)
- {
- Expression *e = (*elements)[i];
- if (te->equals(e->type))
- {
- Expressions *elements2 = new Expressions();
- elements2->setDim(dim);
- for (size_t j = 0; j < dim; j++)
- (*elements2)[j] = e;
- e = new ArrayLiteralExp(e->loc, tn, elements2);
- (*elements)[i] = e;
- }
- }
- }
- }
-
- /* If any elements are errors, then the whole thing is an error
- */
- for (size_t i = 0; i < edim; i++)
- {
- Expression *e = (*elements)[i];
- if (e->op == TOKerror)
- {
- result = e;
- return;
- }
- }
-
- Expression *e = new ArrayLiteralExp(init->loc, init->type, elements);
- result = e;
- return;
- }
-
- Lno:
- result = NULL;
- }
-
- void visit(ExpInitializer *i)
- {
- if (itype)
- {
- //printf("ExpInitializer::toExpression(t = %s) exp = %s\n", itype->toChars(), i->exp->toChars());
- Type *tb = itype->toBasetype();
- Expression *e = (i->exp->op == TOKconstruct || i->exp->op == TOKblit) ? ((AssignExp *)i->exp)->e2 : i->exp;
- if (tb->ty == Tsarray && e->implicitConvTo(tb->nextOf()))
- {
- TypeSArray *tsa = (TypeSArray *)tb;
- size_t d = (size_t)tsa->dim->toInteger();
- Expressions *elements = new Expressions();
- elements->setDim(d);
- for (size_t j = 0; j < d; j++)
- (*elements)[j] = e;
- ArrayLiteralExp *ae = new ArrayLiteralExp(e->loc, itype, elements);
- result = ae;
- return;
- }
- }
- result = i->exp;
- }
-};
-
-Expression *initializerToExpression(Initializer *i, Type *t)
-{
- InitToExpressionVisitor v = InitToExpressionVisitor(t);
- i->accept(&v);
- return v.result;
-}