diff dmd/PragmaDeclaration.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 7427ded8caf7
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/PragmaDeclaration.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,287 @@
+module dmd.PragmaDeclaration;
+
+import dmd.ArrayTypes;
+import dmd.AttribDeclaration;
+import dmd.Loc;
+import dmd.Identifier;
+import dmd.StringExp;
+import dmd.TOK;
+import dmd.WANT;
+import dmd.Global;
+import dmd.Id;
+import dmd.Array;
+import dmd.Dsymbol;
+import dmd.Scope;
+import dmd.OutBuffer;
+import dmd.HdrGenState;
+import dmd.Expression;
+import dmd.FuncDeclaration;
+
+import dmd.backend.Util;
+import dmd.backend.Symbol;
+
+class PragmaDeclaration : AttribDeclaration
+{
+    Expressions args;		// array of Expression's
+
+    this(Loc loc, Identifier ident, Expressions args, Array decl)
+	{
+		super(decl);
+		this.loc = loc;
+		this.ident = ident;
+		this.args = args;
+	}
+
+    Dsymbol syntaxCopy(Dsymbol s)
+	{
+		//printf("PragmaDeclaration.syntaxCopy(%s)\n", toChars());
+		PragmaDeclaration pd;
+
+		assert(!s);
+		pd = new PragmaDeclaration(loc, ident, Expression.arraySyntaxCopy(args), Dsymbol.arraySyntaxCopy(decl));
+		return pd;
+	}
+	
+    void semantic(Scope sc)
+	{
+		// Should be merged with PragmaStatement
+
+		//printf("\tPragmaDeclaration.semantic '%s'\n",toChars());
+		if (ident == Id.msg)
+		{
+			if (args)
+			{
+				for (size_t i = 0; i < args.dim; i++)
+				{
+					Expression e = cast(Expression)args.data[i];
+
+					e = e.semantic(sc);
+					e = e.optimize(WANTvalue | WANTinterpret);
+					if (e.op == TOKstring)
+					{
+						StringExp se = cast(StringExp)e;
+						writef("%.*s", cast(int)se.len, cast(char*)se.string_);
+					}
+					else
+						error("string expected for message, not '%s'", e.toChars());
+				}
+				writef("\n");
+			}
+			goto Lnodecl;
+		}
+		else if (ident == Id.lib)
+		{
+			if (!args || args.dim != 1)
+				error("string expected for library name");
+			else
+			{
+				Expression e = cast(Expression)args.data[0];
+
+				e = e.semantic(sc);
+				e = e.optimize(WANTvalue | WANTinterpret);
+				args.data[0] = cast(void*)e;
+				if (e.op != TOKstring)
+					error("string expected for library name, not '%s'", e.toChars());
+				else if (global.params.verbose)
+				{
+					StringExp se = cast(StringExp)e;
+					writef("library   %.*s\n", cast(int)se.len, cast(char*)se.string_);
+				}
+			}
+			goto Lnodecl;
+		}
+///	version (IN_GCC) {
+///		else if (ident == Id.GNU_asm)
+///		{
+///		if (! args || args.dim != 2)
+///			error("identifier and string expected for asm name");
+///		else
+///		{
+///			Expression *e;
+///			Declaration *d = null;
+///			StringExp *s = null;
+///
+///			e = (Expression *)args.data[0];
+///			e = e.semantic(sc);
+///			if (e.op == TOKvar)
+///			{
+///			d = ((VarExp *)e).var;
+///			if (! d.isFuncDeclaration() && ! d.isVarDeclaration())
+///				d = null;
+///			}
+///			if (!d)
+///			error("first argument of GNU_asm must be a function or variable declaration");
+///
+///			e = (Expression *)args.data[1];
+///			e = e.semantic(sc);
+///			e = e.optimize(WANTvalue);
+///			if (e.op == TOKstring && ((StringExp *)e).sz == 1)
+///			s = ((StringExp *)e);
+///			else
+///			error("second argument of GNU_asm must be a char string");
+///
+///			if (d && s)
+///			d.c_ident = Lexer.idPool((char*) s.string);
+///		}
+///		goto Lnodecl;
+///		}
+///	}
+		else if (ident == Id.startaddress)
+		{
+			if (!args || args.dim != 1)
+				error("function name expected for start address");
+			else
+			{
+				Expression e = cast(Expression)args.data[0];
+				e = e.semantic(sc);
+				e = e.optimize(WANTvalue | WANTinterpret);
+				args.data[0] = cast(void*)e;
+				Dsymbol sa = getDsymbol(e);
+				if (!sa || !sa.isFuncDeclaration())
+					error("function name expected for start address, not '%s'", e.toChars());
+			}
+			goto Lnodecl;
+		}
+///	version (TARGET_NET) {
+///		else if (ident == Lexer.idPool("assembly"))
+///		{
+///		}
+///	} // TARGET_NET
+		else if (global.params.ignoreUnsupportedPragmas)
+		{
+			if (global.params.verbose)
+			{
+				/* Print unrecognized pragmas
+				 */
+				writef("pragma    %s", ident.toChars());
+				if (args)
+				{
+					for (size_t i = 0; i < args.dim; i++)
+					{
+						Expression e = cast(Expression)args.data[i];
+						e = e.semantic(sc);
+						e = e.optimize(WANTvalue | WANTinterpret);
+						if (i == 0)
+							writef(" (");
+						else
+							writef(",");
+						writef("%s", e.toChars());
+					}
+					if (args.dim)
+						writef(")");
+				}
+				writef("\n");
+			}
+			goto Lnodecl;
+		}
+		else
+			error("unrecognized pragma(%s)", ident.toChars());
+
+		if (decl)
+		{
+			for (uint i = 0; i < decl.dim; i++)
+			{
+				Dsymbol s = cast(Dsymbol)decl.data[i];
+				s.semantic(sc);
+			}
+		}
+		return;
+
+	Lnodecl:
+		if (decl)
+			error("pragma is missing closing ';'");
+	}
+	
+    void setScope(Scope sc)
+	{
+version (TARGET_NET) {
+    if (ident == Lexer.idPool("assembly"))
+    {
+        if (!args || args.dim != 1)
+        {
+            error("pragma has invalid number of arguments");
+        }
+        else
+        {
+            Expression e = cast(Expression)args.data[0];
+            e = e.semantic(sc);
+            e = e.optimize(WANTvalue | WANTinterpret);
+            args.data[0] = cast(void*)e;
+            if (e.op != TOKstring)
+            {
+                error("string expected, not '%s'", e.toChars());
+            }
+            PragmaScope pragma_ = new PragmaScope(this, sc.parent, cast(StringExp)e);
+
+            assert(sc);
+            pragma_.setScope(sc);
+
+            //add to module members
+            assert(sc.module_);
+            assert(sc.module_.members);
+            sc.module_.members.push(cast(void*)pragma_);
+        }
+    }
+}
+	}
+	
+    bool oneMember(Dsymbol* ps)
+	{
+		assert(false);
+	}
+	
+    void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	{
+		assert(false);
+	}
+	
+    string kind()
+	{
+		assert(false);
+	}
+	
+    void toObjFile(int multiobj)			// compile to .obj file
+	{
+		if (ident == Id.lib)
+		{
+			assert(args && args.dim == 1);
+
+			Expression e = cast(Expression)args.data[0];
+
+			assert(e.op == TOKstring);
+
+			StringExp se = cast(StringExp)e;
+			char* name = cast(char*)malloc(se.len + 1);
+			memcpy(name, se.string_, se.len);
+			name[se.len] = 0;
+		version (OMFOBJ) {
+			/* The OMF format allows library names to be inserted
+			 * into the object file. The linker will then automatically
+			 * search that library, too.
+			 */
+			obj_includelib(name);
+		} else version (ELFOBJ_OR_MACHOBJ) {
+			/* The format does not allow embedded library names,
+			 * so instead append the library name to the list to be passed
+			 * to the linker.
+			 */
+			global.params.libfiles.push(cast(void*) name);
+		} else {
+			error("pragma lib not supported");
+		}
+		}
+///	version (DMDV2) {
+		else if (ident == Id.startaddress)
+		{
+			assert(args && args.dim == 1);
+			Expression e = cast(Expression)args.data[0];
+			Dsymbol sa = getDsymbol(e);
+			FuncDeclaration f = sa.isFuncDeclaration();
+			assert(f);
+			Symbol* s = f.toSymbol();
+			obj_startaddress(s);
+		}
+///	}
+		AttribDeclaration.toObjFile(multiobj);
+	}
+}
\ No newline at end of file