Mercurial > projects > ddmd
view dmd/DotTemplateInstanceExp.d @ 91:21a53563c840
merge
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Mon, 30 Aug 2010 20:30:04 +0100 |
parents | 2e2a5c3f943a |
children | e28b18c23469 |
line wrap: on
line source
module dmd.DotTemplateInstanceExp; import dmd.Expression; import dmd.UnaExp; import dmd.OutBuffer; import dmd.Loc; import dmd.Scope; import dmd.TemplateInstance; import dmd.HdrGenState; import dmd.TOK; import dmd.PREC; import dmd.Declaration; import dmd.Global; import dmd.TypePointer; import dmd.TypeStruct; import dmd.TY; import dmd.ScopeExp; import dmd.DotExp; import dmd.Type; import dmd.Identifier; import dmd.ErrorExp; import dmd.DotVarExp; import dmd.TemplateDeclaration; import dmd.Dsymbol; import dmd.expression.Util; /* Things like: * foo.bar!(args) */ class DotTemplateInstanceExp : UnaExp { TemplateInstance ti; this(Loc loc, Expression e, TemplateInstance ti) { super(loc, TOK.TOKdotti, DotTemplateInstanceExp.sizeof, e); //printf("DotTemplateInstanceExp()\n"); this.ti = ti; } override Expression syntaxCopy() { DotTemplateInstanceExp de = new DotTemplateInstanceExp(loc, e1.syntaxCopy(), cast(TemplateInstance)ti.syntaxCopy(null)); return de; } override Expression semantic(Scope sc) { Dsymbol s; Dsymbol s2; TemplateDeclaration td; Expression e; Identifier id; Type t1; Expression eleft = null; Expression eright; version (LOGSEMANTIC) { printf("DotTemplateInstanceExp.semantic('%s')\n", toChars()); } //e1.print(); //print(); e1 = e1.semantic(sc); t1 = e1.type; if (t1) t1 = t1.toBasetype(); //t1.print(); /* Extract the following from e1: * s: the symbol which ti should be a member of * eleft: if not null, it is the 'this' pointer for ti */ if (e1.op == TOKdotexp) { DotExp de = cast(DotExp)e1; eleft = de.e1; eright = de.e2; } else { eleft = null; eright = e1; } if (eright.op == TOKimport) { s = (cast(ScopeExp)eright).sds; } else if (e1.op == TOKtype) { s = t1.isClassHandle(); if (!s) { if (t1.ty == Tstruct) s = (cast(TypeStruct)t1).sym; else goto L1; } } else if (t1 && (t1.ty == Tstruct || t1.ty == Tclass)) { s = t1.toDsymbol(sc); eleft = e1; } else if (t1 && t1.ty == Tpointer) { t1 = (cast(TypePointer)t1).next.toBasetype(); if (t1.ty != Tstruct) goto L1; s = t1.toDsymbol(sc); eleft = e1; } else { L1: error("template %s is not a member of %s", ti.toChars(), e1.toChars()); goto Lerr; } assert(s); id = ti.name; s2 = s.search(loc, id, 0); if (!s2) { if (!s.ident) error("template identifier %s is not a member of undefined %s", id.toChars(), s.kind()); else error("template identifier %s is not a member of %s %s", id.toChars(), s.kind(), s.ident.toChars()); goto Lerr; } s = s2; s.semantic(sc); s = s.toAlias(); td = s.isTemplateDeclaration(); if (!td) { error("%s is not a template", id.toChars()); goto Lerr; } if (global.errors) goto Lerr; ti.tempdecl = td; if (eleft) { Declaration v; ti.semantic(sc); s = ti.inst.toAlias(); v = s.isDeclaration(); if (v) { e = new DotVarExp(loc, eleft, v); e = e.semantic(sc); return e; } } e = new ScopeExp(loc, ti); if (eleft) { e = new DotExp(loc, eleft, e); } e = e.semantic(sc); return e; Lerr: return new ErrorExp(); } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { expToCBuffer(buf, hgs, e1, PREC.PREC_primary); buf.writeByte('.'); ti.toCBuffer(buf, hgs); } override void dump(int indent) { assert(false); } }