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