Mercurial > projects > ddmd
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