Mercurial > projects > ddmd
view dmd/StructInitializer.d @ 56:51605de93870
TupleExp.optimize
UnrolledLoopStatement.ctor
UnrolledLoopStatement.semantic
UnrolledLoopStatement.blockExit
OrOrExp.checkSideEffect
FuncExp.syntaxCopy
FuncLiteralDeclaration.syntaxCopy
WhileStatement.hasBreak
StructInitializer.toExpression
StructLiteralExp.ctor
StructLiteralExp.optimize
BinExp.commonSemanticAssign
ModAssignExp.opId
Argument.isLazyArray
CommaExp.implicitConvTo
CommaExp.castTo
TypeClass.isBaseOf
createTypeInfoArray
TypeTuple.getTypeInfoDeclaration
TypeInfoTupleDeclaration.ctor
TypeNext.constConv
XorExp.implicitConvTo
TemplateParameter.isTemplateValueParameter
author | korDen |
---|---|
date | Sat, 21 Aug 2010 14:16:53 +0400 |
parents | b7d29f613539 |
children | f708f0452e81 |
line wrap: on
line source
module dmd.StructInitializer; import dmd.Initializer; import dmd.TOK; import dmd.FuncLiteralDeclaration; import dmd.TypeFunction; import dmd.StructDeclaration; import dmd.StructLiteralExp; import dmd.ArrayTypes; import dmd.Array; import dmd.Loc; import dmd.Type; import dmd.Scope; import dmd.Identifier; import dmd.CompoundStatement; import dmd.AggregateDeclaration; import dmd.OutBuffer; import dmd.HdrGenState; import dmd.Expression; import dmd.TypeStruct; import dmd.TY; import dmd.VarDeclaration; import dmd.Dsymbol; import dmd.Util; import dmd.ExpInitializer; import dmd.FuncExp; import dmd.LINK; import dmd.backend.dt_t; class StructInitializer : Initializer { Identifiers field; // of Identifier *'s Initializers value; // parallel array of Initializer *'s Array vars; // parallel array of VarDeclaration *'s AggregateDeclaration ad; // which aggregate this is for this(Loc loc) { super(loc); ad = null; field = new Identifiers(); value = new Initializers(); vars = new Array(); } Initializer syntaxCopy() { StructInitializer ai = new StructInitializer(loc); assert(field.dim == value.dim); ai.field.setDim(field.dim); ai.value.setDim(value.dim); for (int i = 0; i < field.dim; i++) { ai.field.data[i] = field.data[i]; Initializer init = cast(Initializer)value.data[i]; init = init.syntaxCopy(); ai.value.data[i] = cast(void*)init; } return ai; } void addInit(Identifier field, Initializer value) { //printf("StructInitializer.addInit(field = %p, value = %p)\n", field, value); this.field.push(cast(void*)field); this.value.push(cast(void*)value); } Initializer semantic(Scope sc, Type t) { TypeStruct ts; int errors = 0; //printf("StructInitializer.semantic(t = %s) %s\n", t.toChars(), toChars()); vars.setDim(field.dim); t = t.toBasetype(); if (t.ty == Tstruct) { uint i; uint fieldi = 0; ts = cast(TypeStruct)t; ad = ts.sym; for (i = 0; i < field.dim; i++) { Identifier id = cast(Identifier)field.data[i]; Initializer val = cast(Initializer)value.data[i]; Dsymbol s; VarDeclaration v; if (id is null) { if (fieldi >= ad.fields.dim) { error(loc, "too many initializers for %s", ad.toChars()); field.remove(i); i--; continue; } else { s = cast(Dsymbol)ad.fields.data[fieldi]; } } else { //s = ad.symtab.lookup(id); s = ad.search(loc, id, 0); if (!s) { error(loc, "'%s' is not a member of '%s'", id.toChars(), t.toChars()); continue; } // Find out which field index it is for (fieldi = 0; 1; fieldi++) { if (fieldi >= ad.fields.dim) { s.error("is not a per-instance initializable field"); break; } if (s == cast(Dsymbol)ad.fields.data[fieldi]) break; } } if (s && (v = s.isVarDeclaration()) !is null) { val = val.semantic(sc, v.type); value.data[i] = cast(void*)val; vars.data[i] = cast(void*)v; } else { error(loc, "%s is not a field of %s", id ? id.toChars() : s.toChars(), ad.toChars()); errors = 1; } fieldi++; } } else if (t.ty == Tdelegate && value.dim == 0) { /* Rewrite as empty delegate literal { } */ Arguments arguments = new Arguments; Type tf = new TypeFunction(arguments, null, 0, LINK.LINKd); FuncLiteralDeclaration fd = new FuncLiteralDeclaration(loc, Loc(0), tf, TOK.TOKdelegate, null); fd.fbody = new CompoundStatement(loc, new Statements()); fd.endloc = loc; Expression e = new FuncExp(loc, fd); ExpInitializer ie = new ExpInitializer(loc, e); return ie.semantic(sc, t); } else { error(loc, "a struct is not a valid initializer for a %s", t.toChars()); errors = 1; } if (errors) { field.setDim(0); value.setDim(0); vars.setDim(0); } return this; } /*************************************** * This works by transforming a struct initializer into * a struct literal. In the future, the two should be the * same thing. */ Expression toExpression() { Expression e; //printf("StructInitializer.toExpression() %s\n", toChars()); if (!ad) // if fwd referenced { return null; } StructDeclaration sd = ad.isStructDeclaration(); if (!sd) return null; Expressions elements = new Expressions(); for (size_t i = 0; i < value.dim; i++) { if (field.data[i]) goto Lno; Initializer iz = cast(Initializer)value.data[i]; if (!iz) goto Lno; Expression ex = iz.toExpression(); if (!ex) goto Lno; elements.push(cast(void*)ex); } e = new StructLiteralExp(loc, sd, elements); e.type = sd.type; return e; Lno: delete elements; //error(loc, "struct initializers as expressions are not allowed"); return null; } void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } dt_t* toDt() { assert(false); } StructInitializer isStructInitializer() { return this; } }