diff dmd/IdentifierExp.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children ee3a9f34dc48
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/IdentifierExp.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,171 @@
+module dmd.IdentifierExp;
+
+import dmd.Expression;
+import dmd.Declaration;
+import dmd.TY;
+import dmd.TypePointer;
+import dmd.FuncDeclaration;
+import dmd.TemplateInstance;
+import dmd.TemplateDeclaration;
+import dmd.TemplateExp;
+import dmd.DsymbolExp;
+import dmd.Identifier;
+import dmd.OutBuffer;
+import dmd.Loc;
+import dmd.Scope;
+import dmd.Dsymbol;
+import dmd.WithScopeSymbol;
+import dmd.VarExp;
+import dmd.DotIdExp;
+import dmd.Type;
+import dmd.HdrGenState;
+import dmd.TOK;
+
+class IdentifierExp : Expression
+{
+	Identifier ident;
+
+	Declaration var;
+
+	this(Loc loc, Identifier ident)
+	{
+		super(loc, TOK.TOKidentifier, IdentifierExp.sizeof);
+		this.ident = ident;
+	}
+
+	this(Loc loc, Declaration var)
+	{
+		assert(false);
+		super(loc, TOK.init, 0);
+	}
+
+	Expression semantic(Scope sc)
+	{
+		Dsymbol s;
+		Dsymbol scopesym;
+
+version (LOGSEMANTIC) {
+		printf("IdentifierExp.semantic('%s')\n", ident.toChars());
+}
+		s = sc.search(loc, ident, &scopesym);
+		if (s)
+		{	
+			Expression e;
+			WithScopeSymbol withsym;
+
+			/* See if the symbol was a member of an enclosing 'with'
+			 */
+			withsym = scopesym.isWithScopeSymbol();
+			if (withsym)
+			{
+version (DMDV2) {
+				/* Disallow shadowing
+				 */
+				// First find the scope of the with
+				Scope scwith = sc;
+				while (scwith.scopesym !is scopesym)
+				{	
+					scwith = scwith.enclosing;
+					assert(scwith);
+				}
+
+				// Look at enclosing scopes for symbols with the same name,
+				// in the same function
+				for (Scope scx = scwith; scx && scx.func == scwith.func; scx = scx.enclosing)
+				{   
+					Dsymbol s2;
+
+					if (scx.scopesym && scx.scopesym.symtab && (s2 = scx.scopesym.symtab.lookup(s.ident)) !is null && s !is s2)
+					{
+						error("with symbol %s is shadowing local symbol %s", s.toPrettyChars(), s2.toPrettyChars());
+					}
+				}
+}
+				s = s.toAlias();
+
+				// Same as wthis.ident
+				if (s.needThis() || s.isTemplateDeclaration())
+				{
+					e = new VarExp(loc, withsym.withstate.wthis);
+					e = new DotIdExp(loc, e, ident);
+				}
+				else
+				{	
+					Type t = withsym.withstate.wthis.type;
+					if (t.ty == TY.Tpointer)
+						t = (cast(TypePointer)t).next;
+					e = typeDotIdExp(loc, t, ident);
+				}
+			}
+			else
+			{
+				/* If f is really a function template,
+				 * then replace f with the function template declaration.
+				 */
+				FuncDeclaration f = s.isFuncDeclaration();
+				if (f && f.parent)
+				{   
+					TemplateInstance ti = f.parent.isTemplateInstance();
+
+					if (ti && !ti.isTemplateMixin() &&
+						(ti.name == f.ident || ti.toAlias().ident == f.ident) &&
+						ti.tempdecl && ti.tempdecl.onemember)
+					{
+						TemplateDeclaration tempdecl = ti.tempdecl;
+
+						if (tempdecl.overroot)         // if not start of overloaded list of TemplateDeclaration's
+							tempdecl = tempdecl.overroot; // then get the start
+
+						e = new TemplateExp(loc, tempdecl);
+						e = e.semantic(sc);
+
+						return e;
+					}
+				}
+
+				// Haven't done overload resolution yet, so pass 1
+				e = new DsymbolExp(loc, s, 1);
+			}
+
+			return e.semantic(sc);
+		}
+
+		error("undefined identifier %s", ident.toChars());
+		type = Type.terror;
+		return this;
+	}
+
+	string toChars()
+	{
+		return ident.toChars();
+	}
+
+	void dump(int indent)
+	{
+		assert(false);
+	}
+
+	void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	{
+		if (hgs.hdrgen)
+			buf.writestring(ident.toHChars2());
+		else
+			buf.writestring(ident.toChars());
+	}
+
+	int isLvalue()
+	{
+		assert(false);
+	}
+
+	Expression toLvalue(Scope sc, Expression e)
+	{
+static if (false) {
+		tym = tybasic(e1.ET.Tty);
+		if (!(tyscalar(tym) || tym == TYM.TYstruct || tym == TYM.TYarray && e.Eoper == TOK.TOKaddr))
+			synerr(EM_lvalue);	// lvalue expected
+}
+		return this;
+	}
+}
+