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