Mercurial > projects > ddmd
diff dmd/TypeQualified.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 69d078c417c6 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/TypeQualified.d Sat Oct 24 08:42:06 2009 +0400 @@ -0,0 +1,271 @@ +module dmd.TypeQualified; + +import dmd.Type; +import dmd.Import; +import dmd.TypeExp; +import dmd.DotIdExp; +import dmd.VarDeclaration; +import dmd.EnumMember; +import dmd.TupleDeclaration; +import dmd.Id; +import dmd.VarExp; +import dmd.TemplateInstance; +import dmd.Loc; +import dmd.Array; +import dmd.TY; +import dmd.Identifier; +import dmd.OutBuffer; +import dmd.HdrGenState; +import dmd.Scope; +import dmd.Dsymbol; +import dmd.DYNCAST; +import dmd.Expression; +import dmd.Util; + +class TypeQualified : Type +{ + Loc loc; + Array idents; // array of Identifier's representing ident.ident.ident etc. + + this(TY ty, Loc loc) + { + super(ty); + this.loc = loc; + + idents = new Array(); + } + +version (DumbClone) { +} else { + Type clone() + { + assert(false); + } +} + void syntaxCopyHelper(TypeQualified t) + { + //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars()); + idents.setDim(t.idents.dim); + for (int i = 0; i < idents.dim; i++) + { + Identifier id = cast(Identifier)t.idents.data[i]; + if (id.dyncast() == DYNCAST.DYNCAST_DSYMBOL) + { + TemplateInstance ti = cast(TemplateInstance)id; + + ti = cast(TemplateInstance)ti.syntaxCopy(null); + id = cast(Identifier)ti; + } + + idents.data[i] = cast(void*)id; + } + } + + void addIdent(Identifier ident) + { + idents.push(cast(void*)ident); + } + + void toCBuffer2Helper(OutBuffer buf, HdrGenState* hgs) + { + int i; + + for (i = 0; i < idents.dim; i++) + { + Identifier id = cast(Identifier)idents.data[i]; + buf.writeByte('.'); + + if (id.dyncast() == DYNCAST.DYNCAST_DSYMBOL) + { + TemplateInstance ti = cast(TemplateInstance)id; + ti.toCBuffer(buf, hgs); + } else { + buf.writestring(id.toChars()); + } + } + } + + ulong size(Loc loc) + { + assert(false); + } + + /************************************* + * Takes an array of Identifiers and figures out if + * it represents a Type or an Expression. + * Output: + * if expression, *pe is set + * if type, *pt is set + */ + void resolveHelper(Loc loc, Scope sc, Dsymbol s, Dsymbol scopesym, Expression* pe, Type* pt, Dsymbol* ps) + { + VarDeclaration v; + EnumMember em; + TupleDeclaration td; + Expression e; + +static if (false) { + printf("TypeQualified.resolveHelper(sc = %p, idents = '%s')\n", sc, toChars()); + if (scopesym) + printf("\tscopesym = '%s'\n", scopesym.toChars()); +} + *pe = null; + *pt = null; + *ps = null; + if (s) + { + //printf("\t1: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind()); + s.checkDeprecated(loc, sc); // check for deprecated aliases + s = s.toAlias(); + //printf("\t2: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind()); + for (int i = 0; i < idents.dim; i++) + { + Identifier id = cast(Identifier)idents.data[i]; + Dsymbol sm = s.searchX(loc, sc, id); + //printf("\t3: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind()); + //printf("\tgetType = '%s'\n", s.getType().toChars()); + if (!sm) + { + Type t; + + v = s.isVarDeclaration(); + if (v && id == Id.length) + { + e = v.getConstInitializer(); + if (!e) + e = new VarExp(loc, v); + t = e.type; + if (!t) + goto Lerror; + goto L3; + } + t = s.getType(); + if (!t && s.isDeclaration()) + t = s.isDeclaration().type; + if (t) + { + sm = t.toDsymbol(sc); + if (sm) + { sm = sm.search(loc, id, 0); + if (sm) + goto L2; + } + //e = t.getProperty(loc, id); + e = new TypeExp(loc, t); + e = t.dotExp(sc, e, id); + i++; + L3: + for (; i < idents.dim; i++) + { + id = cast(Identifier)idents.data[i]; + //printf("e: '%s', id: '%s', type = %p\n", e.toChars(), id.toChars(), e.type); + if (id == Id.offsetof) + { e = new DotIdExp(e.loc, e, id); + e = e.semantic(sc); + } + else + e = e.type.dotExp(sc, e, id); + } + *pe = e; + } + else + Lerror: + error(loc, "identifier '%s' of '%s' is not defined", id.toChars(), toChars()); + return; + } + L2: + s = sm.toAlias(); + } + + v = s.isVarDeclaration(); + if (v) + { +///static if (false) { +/// // It's not a type, it's an expression +/// Expression *e = v.getConstInitializer(); +/// if (e) +/// { +/// *pe = e.copy(); // make copy so we can change loc +/// (*pe).loc = loc; +/// } +/// else +///} + { +///static if (false) { +/// WithScopeSymbol withsym; +/// if (scopesym && (withsym = scopesym.isWithScopeSymbol()) !is null) +/// { +/// // Same as wthis.ident +/// e = new VarExp(loc, withsym.withstate.wthis); +/// e = new DotIdExp(loc, e, ident); +/// //assert(0); // BUG: should handle this +/// } +/// else +///} + *pe = new VarExp(loc, v); + } + return; + } + em = s.isEnumMember(); + if (em) + { + // It's not a type, it's an expression + *pe = em.value.copy(); + return; + } + + L1: + Type t = s.getType(); + if (!t) + { + // If the symbol is an import, try looking inside the import + Import si; + + si = s.isImport(); + if (si) + { + s = si.search(loc, s.ident, 0); + if (s && s != si) + goto L1; + s = si; + } + *ps = s; + return; + } + if (t.ty == TY.Tinstance && t != this && !t.deco) + { + error(loc, "forward reference to '%s'", t.toChars()); + return; + } + + if (t != this) + { + if (t.reliesOnTident()) + { + Scope scx; + + for (scx = sc; 1; scx = scx.enclosing) + { + if (!scx) + { + error(loc, "forward reference to '%s'", t.toChars()); + return; + } + if (scx.scopesym == scopesym) + break; + } + t = t.semantic(loc, scx); + //((TypeIdentifier *)t).resolve(loc, scx, pe, &t, ps); + } + } + if (t.ty == TY.Ttuple) + *pt = t; + else + *pt = t.merge(); + } + if (!s) + { + error(loc, "identifier '%s' is not defined", toChars()); + } + } +} \ No newline at end of file