diff dmd/SuperExp.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children ecf732dfe11e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/SuperExp.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,125 @@
+module dmd.SuperExp;
+
+import dmd.Expression;
+import dmd.OutBuffer;
+import dmd.Loc;
+import dmd.Scope;
+import dmd.InlineCostState;
+import dmd.InlineDoState;
+import dmd.FuncDeclaration;
+import dmd.ClassDeclaration;
+import dmd.Dsymbol;
+import dmd.HdrGenState;
+import dmd.ThisExp;
+import dmd.TOK;
+import dmd.CSX;
+import dmd.Type;
+
+class SuperExp : ThisExp
+{
+	this(Loc loc)
+	{
+		super(loc);
+		op = TOK.TOKsuper;
+	}
+
+	Expression semantic(Scope sc)
+	{
+		FuncDeclaration fd;
+		FuncDeclaration fdthis;
+
+	version (LOGSEMANTIC) {
+		printf("SuperExp.semantic('%s')\n", toChars());
+	}
+		if (type)
+			return this;
+
+		/* Special case for typeof(this) and typeof(super) since both
+		 * should work even if they are not inside a non-static member function
+		 */
+		if (sc.intypeof)
+		{
+			// Find enclosing class
+			for (Dsymbol s = sc.parent; 1; s = s.parent)
+			{
+				ClassDeclaration cd;
+
+				if (!s)
+				{
+					error("%s is not in a class scope", toChars());
+					goto Lerr;
+				}
+				cd = s.isClassDeclaration();
+				if (cd)
+				{
+					cd = cd.baseClass;
+					if (!cd)
+					{   
+						error("class %s has no 'super'", s.toChars());
+						goto Lerr;
+					}
+					type = cd.type;
+					return this;
+				}
+			}
+		}
+
+		fdthis = sc.parent.isFuncDeclaration();
+		fd = hasThis(sc);
+		if (!fd)
+			goto Lerr;
+		assert(fd.vthis);
+		var = fd.vthis;
+		assert(var.parent);
+
+		Dsymbol s = fd.toParent();
+		while (s && s.isTemplateInstance())
+			s = s.toParent();
+		assert(s);
+		ClassDeclaration cd = s.isClassDeclaration();
+	//printf("parent is %s %s\n", fd.toParent().kind(), fd.toParent().toChars());
+		if (!cd)
+			goto Lerr;
+		if (!cd.baseClass)
+		{
+			error("no base class for %s", cd.toChars());
+			type = fd.vthis.type;
+		}
+		else
+		{
+			type = cd.baseClass.type;
+		}
+
+		var.isVarDeclaration().checkNestedReference(sc, loc);
+
+		if (!sc.intypeof)
+			sc.callSuper |= CSXsuper;
+		return this;
+
+	Lerr:
+		error("'super' is only allowed in non-static class member functions");
+		type = Type.tint32;
+		return this;
+	}
+
+	void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	{
+		assert(false);
+	}
+
+	void scanForNestedRef(Scope sc)
+	{
+		assert(false);
+	}
+
+	int inlineCost(InlineCostState* ics)
+	{
+		assert(false);
+	}
+
+	Expression doInline(InlineDoState ids)
+	{
+		assert(false);
+	}
+}
+