0
|
1 module dmd.PragmaDeclaration;
|
|
2
|
|
3 import dmd.ArrayTypes;
|
|
4 import dmd.AttribDeclaration;
|
|
5 import dmd.Loc;
|
|
6 import dmd.Identifier;
|
|
7 import dmd.StringExp;
|
|
8 import dmd.TOK;
|
|
9 import dmd.WANT;
|
|
10 import dmd.Global;
|
|
11 import dmd.Id;
|
|
12 import dmd.Array;
|
|
13 import dmd.Dsymbol;
|
|
14 import dmd.Scope;
|
|
15 import dmd.OutBuffer;
|
|
16 import dmd.HdrGenState;
|
|
17 import dmd.Expression;
|
|
18 import dmd.FuncDeclaration;
|
|
19
|
|
20 import dmd.backend.Util;
|
|
21 import dmd.backend.Symbol;
|
|
22
|
2
|
23 import dmd.Memory;
|
|
24
|
0
|
25 class PragmaDeclaration : AttribDeclaration
|
|
26 {
|
|
27 Expressions args; // array of Expression's
|
|
28
|
|
29 this(Loc loc, Identifier ident, Expressions args, Array decl)
|
|
30 {
|
|
31 super(decl);
|
|
32 this.loc = loc;
|
|
33 this.ident = ident;
|
|
34 this.args = args;
|
|
35 }
|
|
36
|
|
37 Dsymbol syntaxCopy(Dsymbol s)
|
|
38 {
|
|
39 //printf("PragmaDeclaration.syntaxCopy(%s)\n", toChars());
|
|
40 PragmaDeclaration pd;
|
|
41
|
|
42 assert(!s);
|
|
43 pd = new PragmaDeclaration(loc, ident, Expression.arraySyntaxCopy(args), Dsymbol.arraySyntaxCopy(decl));
|
|
44 return pd;
|
|
45 }
|
|
46
|
|
47 void semantic(Scope sc)
|
|
48 {
|
|
49 // Should be merged with PragmaStatement
|
|
50
|
|
51 //printf("\tPragmaDeclaration.semantic '%s'\n",toChars());
|
|
52 if (ident == Id.msg)
|
|
53 {
|
|
54 if (args)
|
|
55 {
|
|
56 for (size_t i = 0; i < args.dim; i++)
|
|
57 {
|
|
58 Expression e = cast(Expression)args.data[i];
|
|
59
|
|
60 e = e.semantic(sc);
|
|
61 e = e.optimize(WANTvalue | WANTinterpret);
|
|
62 if (e.op == TOKstring)
|
|
63 {
|
|
64 StringExp se = cast(StringExp)e;
|
|
65 writef("%.*s", cast(int)se.len, cast(char*)se.string_);
|
|
66 }
|
|
67 else
|
|
68 error("string expected for message, not '%s'", e.toChars());
|
|
69 }
|
|
70 writef("\n");
|
|
71 }
|
|
72 goto Lnodecl;
|
|
73 }
|
|
74 else if (ident == Id.lib)
|
|
75 {
|
|
76 if (!args || args.dim != 1)
|
|
77 error("string expected for library name");
|
|
78 else
|
|
79 {
|
|
80 Expression e = cast(Expression)args.data[0];
|
|
81
|
|
82 e = e.semantic(sc);
|
|
83 e = e.optimize(WANTvalue | WANTinterpret);
|
|
84 args.data[0] = cast(void*)e;
|
|
85 if (e.op != TOKstring)
|
|
86 error("string expected for library name, not '%s'", e.toChars());
|
|
87 else if (global.params.verbose)
|
|
88 {
|
|
89 StringExp se = cast(StringExp)e;
|
|
90 writef("library %.*s\n", cast(int)se.len, cast(char*)se.string_);
|
|
91 }
|
|
92 }
|
|
93 goto Lnodecl;
|
|
94 }
|
|
95 /// version (IN_GCC) {
|
|
96 /// else if (ident == Id.GNU_asm)
|
|
97 /// {
|
|
98 /// if (! args || args.dim != 2)
|
|
99 /// error("identifier and string expected for asm name");
|
|
100 /// else
|
|
101 /// {
|
|
102 /// Expression *e;
|
|
103 /// Declaration *d = null;
|
|
104 /// StringExp *s = null;
|
|
105 ///
|
|
106 /// e = (Expression *)args.data[0];
|
|
107 /// e = e.semantic(sc);
|
|
108 /// if (e.op == TOKvar)
|
|
109 /// {
|
|
110 /// d = ((VarExp *)e).var;
|
|
111 /// if (! d.isFuncDeclaration() && ! d.isVarDeclaration())
|
|
112 /// d = null;
|
|
113 /// }
|
|
114 /// if (!d)
|
|
115 /// error("first argument of GNU_asm must be a function or variable declaration");
|
|
116 ///
|
|
117 /// e = (Expression *)args.data[1];
|
|
118 /// e = e.semantic(sc);
|
|
119 /// e = e.optimize(WANTvalue);
|
|
120 /// if (e.op == TOKstring && ((StringExp *)e).sz == 1)
|
|
121 /// s = ((StringExp *)e);
|
|
122 /// else
|
|
123 /// error("second argument of GNU_asm must be a char string");
|
|
124 ///
|
|
125 /// if (d && s)
|
|
126 /// d.c_ident = Lexer.idPool((char*) s.string);
|
|
127 /// }
|
|
128 /// goto Lnodecl;
|
|
129 /// }
|
|
130 /// }
|
|
131 else if (ident == Id.startaddress)
|
|
132 {
|
|
133 if (!args || args.dim != 1)
|
|
134 error("function name expected for start address");
|
|
135 else
|
|
136 {
|
|
137 Expression e = cast(Expression)args.data[0];
|
|
138 e = e.semantic(sc);
|
|
139 e = e.optimize(WANTvalue | WANTinterpret);
|
|
140 args.data[0] = cast(void*)e;
|
|
141 Dsymbol sa = getDsymbol(e);
|
|
142 if (!sa || !sa.isFuncDeclaration())
|
|
143 error("function name expected for start address, not '%s'", e.toChars());
|
|
144 }
|
|
145 goto Lnodecl;
|
|
146 }
|
|
147 /// version (TARGET_NET) {
|
|
148 /// else if (ident == Lexer.idPool("assembly"))
|
|
149 /// {
|
|
150 /// }
|
|
151 /// } // TARGET_NET
|
|
152 else if (global.params.ignoreUnsupportedPragmas)
|
|
153 {
|
|
154 if (global.params.verbose)
|
|
155 {
|
|
156 /* Print unrecognized pragmas
|
|
157 */
|
|
158 writef("pragma %s", ident.toChars());
|
|
159 if (args)
|
|
160 {
|
|
161 for (size_t i = 0; i < args.dim; i++)
|
|
162 {
|
|
163 Expression e = cast(Expression)args.data[i];
|
|
164 e = e.semantic(sc);
|
|
165 e = e.optimize(WANTvalue | WANTinterpret);
|
|
166 if (i == 0)
|
|
167 writef(" (");
|
|
168 else
|
|
169 writef(",");
|
|
170 writef("%s", e.toChars());
|
|
171 }
|
|
172 if (args.dim)
|
|
173 writef(")");
|
|
174 }
|
|
175 writef("\n");
|
|
176 }
|
|
177 goto Lnodecl;
|
|
178 }
|
|
179 else
|
|
180 error("unrecognized pragma(%s)", ident.toChars());
|
|
181
|
|
182 if (decl)
|
|
183 {
|
|
184 for (uint i = 0; i < decl.dim; i++)
|
|
185 {
|
|
186 Dsymbol s = cast(Dsymbol)decl.data[i];
|
|
187 s.semantic(sc);
|
|
188 }
|
|
189 }
|
|
190 return;
|
|
191
|
|
192 Lnodecl:
|
|
193 if (decl)
|
|
194 error("pragma is missing closing ';'");
|
|
195 }
|
|
196
|
|
197 void setScope(Scope sc)
|
|
198 {
|
|
199 version (TARGET_NET) {
|
|
200 if (ident == Lexer.idPool("assembly"))
|
|
201 {
|
|
202 if (!args || args.dim != 1)
|
|
203 {
|
|
204 error("pragma has invalid number of arguments");
|
|
205 }
|
|
206 else
|
|
207 {
|
|
208 Expression e = cast(Expression)args.data[0];
|
|
209 e = e.semantic(sc);
|
|
210 e = e.optimize(WANTvalue | WANTinterpret);
|
|
211 args.data[0] = cast(void*)e;
|
|
212 if (e.op != TOKstring)
|
|
213 {
|
|
214 error("string expected, not '%s'", e.toChars());
|
|
215 }
|
|
216 PragmaScope pragma_ = new PragmaScope(this, sc.parent, cast(StringExp)e);
|
|
217
|
|
218 assert(sc);
|
|
219 pragma_.setScope(sc);
|
|
220
|
|
221 //add to module members
|
|
222 assert(sc.module_);
|
|
223 assert(sc.module_.members);
|
|
224 sc.module_.members.push(cast(void*)pragma_);
|
|
225 }
|
|
226 }
|
|
227 }
|
|
228 }
|
|
229
|
|
230 bool oneMember(Dsymbol* ps)
|
|
231 {
|
|
232 assert(false);
|
|
233 }
|
|
234
|
|
235 void toCBuffer(OutBuffer buf, HdrGenState* hgs)
|
|
236 {
|
|
237 assert(false);
|
|
238 }
|
|
239
|
|
240 string kind()
|
|
241 {
|
|
242 assert(false);
|
|
243 }
|
|
244
|
|
245 void toObjFile(int multiobj) // compile to .obj file
|
|
246 {
|
|
247 if (ident == Id.lib)
|
|
248 {
|
|
249 assert(args && args.dim == 1);
|
|
250
|
|
251 Expression e = cast(Expression)args.data[0];
|
|
252
|
|
253 assert(e.op == TOKstring);
|
|
254
|
|
255 StringExp se = cast(StringExp)e;
|
2
|
256 char* name = cast(char*)GC.malloc(se.len + 1);
|
0
|
257 memcpy(name, se.string_, se.len);
|
|
258 name[se.len] = 0;
|
|
259 version (OMFOBJ) {
|
|
260 /* The OMF format allows library names to be inserted
|
|
261 * into the object file. The linker will then automatically
|
|
262 * search that library, too.
|
|
263 */
|
|
264 obj_includelib(name);
|
|
265 } else version (ELFOBJ_OR_MACHOBJ) {
|
|
266 /* The format does not allow embedded library names,
|
|
267 * so instead append the library name to the list to be passed
|
|
268 * to the linker.
|
|
269 */
|
|
270 global.params.libfiles.push(cast(void*) name);
|
|
271 } else {
|
|
272 error("pragma lib not supported");
|
|
273 }
|
|
274 }
|
|
275 /// version (DMDV2) {
|
|
276 else if (ident == Id.startaddress)
|
|
277 {
|
|
278 assert(args && args.dim == 1);
|
|
279 Expression e = cast(Expression)args.data[0];
|
|
280 Dsymbol sa = getDsymbol(e);
|
|
281 FuncDeclaration f = sa.isFuncDeclaration();
|
|
282 assert(f);
|
|
283 Symbol* s = f.toSymbol();
|
|
284 obj_startaddress(s);
|
|
285 }
|
|
286 /// }
|
|
287 AttribDeclaration.toObjFile(multiobj);
|
|
288 }
|
|
289 } |