Mercurial > projects > ddmd
comparison dmd/PragmaDeclaration.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 7427ded8caf7 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:10317f0c89a5 |
---|---|
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 } |