Mercurial > projects > ddmd
diff dmd/DsymbolExp.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 2e2a5c3f943a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/DsymbolExp.d Sat Oct 24 08:42:06 2009 +0400 @@ -0,0 +1,251 @@ +module dmd.DsymbolExp; + +import dmd.Expression; +import dmd.OutBuffer; +import dmd.EnumMember; +import dmd.VarDeclaration; +import dmd.FuncDeclaration; +import dmd.FuncLiteralDeclaration; +import dmd.OverloadSet; +import dmd.Declaration; +import dmd.ClassDeclaration; +import dmd.Import; +import dmd.Package; +import dmd.Type; +import dmd.DotVarExp; +import dmd.ThisExp; +import dmd.VarExp; +import dmd.FuncExp; +import dmd.OverExp; +import dmd.DotTypeExp; +import dmd.ScopeExp; +import dmd.Module; +import dmd.TypeExp; +import dmd.TupleDeclaration; +import dmd.TupleExp; +import dmd.TemplateInstance; +import dmd.Global; +import dmd.TemplateDeclaration; +import dmd.TemplateExp; +import dmd.Loc; +import dmd.Scope; +import dmd.HdrGenState; +import dmd.Dsymbol; +import dmd.TOK; + +class DsymbolExp : Expression +{ + Dsymbol s; + int hasOverloads; + + this(Loc loc, Dsymbol s, int hasOverloads = 0) + { + super(loc, TOK.TOKdsymbol, DsymbolExp.sizeof); + this.s = s; + this.hasOverloads = hasOverloads; + } + + Expression semantic(Scope sc) + { +version (LOGSEMANTIC) { + printf("DsymbolExp.semantic('%s')\n", s.toChars()); +} + + Lagain: + EnumMember em; + Expression e; + VarDeclaration v; + FuncDeclaration f; + FuncLiteralDeclaration fld; + OverloadSet o; + Declaration d; + ClassDeclaration cd; + ClassDeclaration thiscd = null; + Import imp; + Package pkg; + Type t; + + //printf("DsymbolExp. %p '%s' is a symbol\n", this, toChars()); + //printf("s = '%s', s.kind = '%s'\n", s.toChars(), s.kind()); + if (type) + return this; + + if (!s.isFuncDeclaration()) // functions are checked after overloading + checkDeprecated(sc, s); + + s = s.toAlias(); + //printf("s = '%s', s.kind = '%s', s.needThis() = %p\n", s.toChars(), s.kind(), s.needThis()); + if (!s.isFuncDeclaration()) + checkDeprecated(sc, s); + + if (sc.func) + thiscd = sc.func.parent.isClassDeclaration(); + + // BUG: This should happen after overload resolution for functions, not before + if (s.needThis()) + { +version (DMDV2) { + bool cond = !s.isFuncDeclaration(); +} else { + bool cond = true; +} + if (hasThis(sc) && cond) + { + // Supply an implicit 'this', as in + // this.ident + DotVarExp de = new DotVarExp(loc, new ThisExp(loc), s.isDeclaration()); + return de.semantic(sc); + } + } + + em = s.isEnumMember(); + if (em) + { + e = em.value; + e = e.semantic(sc); + return e; + } + v = s.isVarDeclaration(); + if (v) + { + //printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v.type.toChars()); + if (!type) + { + type = v.type; + if (!v.type) + { + error("forward reference of %s %s", v.kind(), v.toChars()); + type = Type.terror; + } + } + + e = new VarExp(loc, v); + e.type = type; + e = e.semantic(sc); + return e.deref(); + } + + fld = s.isFuncLiteralDeclaration(); + if (fld) + { + //printf("'%s' is a function literal\n", fld.toChars()); + e = new FuncExp(loc, fld); + return e.semantic(sc); + } + f = s.isFuncDeclaration(); + if (f) + { + //printf("'%s' is a function\n", f.toChars()); + + if (!f.type.deco) + { + error("forward reference to %s", toChars()); + } + return new VarExp(loc, f, hasOverloads); + } + o = s.isOverloadSet(); + if (o) + { + //printf("'%s' is an overload set\n", o.toChars()); + return new OverExp(o); + } + cd = s.isClassDeclaration(); + if (cd && thiscd && cd.isBaseOf(thiscd, null) && sc.func.needThis()) + { + // We need to add an implicit 'this' if cd is this class or a base class. + DotTypeExp dte = new DotTypeExp(loc, new ThisExp(loc), s); + return dte.semantic(sc); + } + imp = s.isImport(); + if (imp) + { + if (!imp.pkg) + { + error("forward reference of import %s", imp.toChars()); + return this; + } + ScopeExp ie = new ScopeExp(loc, imp.pkg); + return ie.semantic(sc); + } + pkg = s.isPackage(); + if (pkg) + { + ScopeExp ie = new ScopeExp(loc, pkg); + return ie.semantic(sc); + } + Module mod = s.isModule(); + if (mod) + { + ScopeExp ie = new ScopeExp(loc, mod); + return ie.semantic(sc); + } + + t = s.getType(); + if (t) + { + return new TypeExp(loc, t); + } + + TupleDeclaration tup = s.isTupleDeclaration(); + if (tup) + { + e = new TupleExp(loc, tup); + e = e.semantic(sc); + return e; + } + + TemplateInstance ti = s.isTemplateInstance(); + if (ti && !global.errors) + { + if (!ti.semanticRun) + ti.semantic(sc); + + s = ti.inst.toAlias(); + if (!s.isTemplateInstance()) + goto Lagain; + + e = new ScopeExp(loc, ti); + e = e.semantic(sc); + return e; + } + + TemplateDeclaration td = s.isTemplateDeclaration(); + if (td) + { + e = new TemplateExp(loc, td); + e = e.semantic(sc); + return e; + } + + Lerr: + error("%s '%s' is not a variable", s.kind(), s.toChars()); + type = Type.terror; + return this; + } + + string toChars() + { + assert(false); + } + + void dump(int indent) + { + assert(false); + } + + void toCBuffer(OutBuffer buf, HdrGenState* hgs) + { + assert(false); + } + + int isLvalue() + { + assert(false); + } + + Expression toLvalue(Scope sc, Expression e) + { + assert(false); + } +} +