diff dmd/StaticCtorDeclaration.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/StaticCtorDeclaration.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,129 @@
+module dmd.StaticCtorDeclaration;
+
+import dmd.FuncDeclaration;
+import dmd.Loc;
+import dmd.Dsymbol;
+import dmd.AggregateDeclaration;
+import dmd.Scope;
+import dmd.OutBuffer;
+import dmd.HdrGenState;
+import dmd.STC;
+import dmd.Identifier;
+import dmd.TypeFunction;
+import dmd.Type;
+import dmd.LINK;
+import dmd.Lexer;
+import dmd.VarDeclaration;
+import dmd.ArrayTypes;
+import dmd.Expression;
+import dmd.Statement;
+import dmd.DeclarationStatement;
+import dmd.AddAssignExp;
+import dmd.EqualExp;
+import dmd.TOK;
+import dmd.IfStatement;
+import dmd.CompoundStatement;
+import dmd.Module;
+import dmd.IntegerExp;
+import dmd.ReturnStatement;
+import dmd.IdentifierExp;
+
+class StaticCtorDeclaration : FuncDeclaration
+{
+    this(Loc loc, Loc endloc)
+	{
+		super(loc, endloc, Identifier.generateId("_staticCtor"), STCstatic, null);
+	}
+	
+    Dsymbol syntaxCopy(Dsymbol)
+	{
+		assert(false);
+	}
+	
+    void semantic(Scope sc)
+	{
+		//printf("StaticCtorDeclaration.semantic()\n");
+
+		type = new TypeFunction(null, Type.tvoid, false, LINK.LINKd);
+
+		/* If the static ctor appears within a template instantiation,
+		 * it could get called multiple times by the module constructors
+		 * for different modules. Thus, protect it with a gate.
+		 */
+		if (inTemplateInstance())
+		{
+			/* Add this prefix to the function:
+			 *	static int gate;
+			 *	if (++gate != 1) return;
+			 * Note that this is not thread safe; should not have threads
+			 * during static construction.
+			 */
+			Identifier id = Lexer.idPool("__gate");
+			VarDeclaration v = new VarDeclaration(Loc(0), Type.tint32, id, null);
+			v.storage_class = STCstatic;
+			Statements sa = new Statements();
+			Statement s = new DeclarationStatement(Loc(0), v);
+			sa.push(cast(void*)s);
+			Expression e = new IdentifierExp(Loc(0), id);
+			e = new AddAssignExp(Loc(0), e, new IntegerExp(1));
+			e = new EqualExp(TOKnotequal, Loc(0), e, new IntegerExp(1));
+			s = new IfStatement(Loc(0), null, e, new ReturnStatement(Loc(0), null), null);
+			sa.push(cast(void*)s);
+			if (fbody)
+				sa.push(cast(void*)fbody);
+			fbody = new CompoundStatement(Loc(0), sa);
+		}
+
+		FuncDeclaration.semantic(sc);
+
+		// We're going to need ModuleInfo
+		Module m = getModule();
+		if (!m)
+			m = sc.module_;
+
+		if (m)
+		{	
+			m.needmoduleinfo = 1;
+	version (IN_GCC) {
+			m.strictlyneedmoduleinfo = 1;
+	}
+		}
+	}
+	
+    AggregateDeclaration isThis()
+	{
+		return null;
+	}
+	
+    bool isStaticConstructor()
+	{
+		return true;
+	}
+	
+    bool isVirtual()
+	{
+		return false;
+	}
+	
+    bool addPreInvariant()
+	{
+		return false;
+	}
+	
+    bool addPostInvariant()
+	{
+		return false;
+	}
+	
+    void emitComment(Scope sc)
+	{
+		assert(false);
+	}
+	
+    void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	{
+		assert(false);
+	}
+
+    StaticCtorDeclaration isStaticCtorDeclaration() { return this; }
+}
\ No newline at end of file