Mercurial > projects > ddmd
annotate dmd/PragmaDeclaration.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | 438eaa11eed4 |
children | 0622fff7810a |
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 | |
4 | 24 import core.memory; |
2 | 25 |
0 | 26 class PragmaDeclaration : AttribDeclaration |
27 { | |
28 Expressions args; // array of Expression's | |
29 | |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
30 this(Loc loc, Identifier ident, Expressions args, Dsymbols decl) |
0 | 31 { |
178 | 32 register(); |
0 | 33 super(decl); |
34 this.loc = loc; | |
35 this.ident = ident; | |
36 this.args = args; | |
37 } | |
38 | |
72 | 39 override Dsymbol syntaxCopy(Dsymbol s) |
0 | 40 { |
41 //printf("PragmaDeclaration.syntaxCopy(%s)\n", toChars()); | |
42 PragmaDeclaration pd; | |
43 | |
44 assert(!s); | |
45 pd = new PragmaDeclaration(loc, ident, Expression.arraySyntaxCopy(args), Dsymbol.arraySyntaxCopy(decl)); | |
46 return pd; | |
47 } | |
48 | |
72 | 49 override void semantic(Scope sc) |
0 | 50 { |
51 // Should be merged with PragmaStatement | |
52 | |
53 //printf("\tPragmaDeclaration.semantic '%s'\n",toChars()); | |
54 if (ident == Id.msg) | |
55 { | |
56 if (args) | |
57 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
58 foreach (e; args) |
0 | 59 { |
60 e = e.semantic(sc); | |
61 e = e.optimize(WANTvalue | WANTinterpret); | |
62 if (e.op == TOKstring) | |
63 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
64 auto se = cast(StringExp)e; |
136 | 65 writef("%s", se.toChars()[1..$-2]); // strip the '"'s, TODO: change to original?: /*se.len, cast(char*)se.string_*/ |
0 | 66 } |
67 else | |
95 | 68 writef(e.toChars()); |
0 | 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 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
77
diff
changeset
|
80 auto e = args[0]; |
0 | 81 |
82 e = e.semantic(sc); | |
83 e = e.optimize(WANTvalue | WANTinterpret); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
77
diff
changeset
|
84 args[0] = e; |
0 | 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 /// } | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
116
diff
changeset
|
131 ///version(DMDV2) { |
0 | 132 else if (ident == Id.startaddress) |
133 { | |
134 if (!args || args.dim != 1) | |
135 error("function name expected for start address"); | |
136 else | |
137 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
77
diff
changeset
|
138 auto e = args[0]; |
0 | 139 e = e.semantic(sc); |
140 e = e.optimize(WANTvalue | WANTinterpret); | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
77
diff
changeset
|
141 args[0] = e; |
0 | 142 Dsymbol sa = getDsymbol(e); |
143 if (!sa || !sa.isFuncDeclaration()) | |
144 error("function name expected for start address, not '%s'", e.toChars()); | |
145 } | |
146 goto Lnodecl; | |
147 } | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
116
diff
changeset
|
148 ///} |
0 | 149 /// version (TARGET_NET) { |
150 /// else if (ident == Lexer.idPool("assembly")) | |
151 /// { | |
152 /// } | |
153 /// } // TARGET_NET | |
154 else if (global.params.ignoreUnsupportedPragmas) | |
155 { | |
156 if (global.params.verbose) | |
157 { | |
158 /* Print unrecognized pragmas | |
159 */ | |
160 writef("pragma %s", ident.toChars()); | |
161 if (args) | |
162 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
163 foreach (size_t i, Expression e; args) |
0 | 164 { |
165 e = e.semantic(sc); | |
166 e = e.optimize(WANTvalue | WANTinterpret); | |
167 if (i == 0) | |
168 writef(" ("); | |
169 else | |
170 writef(","); | |
171 writef("%s", e.toChars()); | |
172 } | |
173 if (args.dim) | |
174 writef(")"); | |
175 } | |
176 writef("\n"); | |
177 } | |
178 goto Lnodecl; | |
179 } | |
180 else | |
181 error("unrecognized pragma(%s)", ident.toChars()); | |
182 | |
183 if (decl) | |
184 { | |
77
ad4792a1cfd6
more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
74
diff
changeset
|
185 foreach(Dsymbol s; decl) |
0 | 186 s.semantic(sc); |
187 } | |
188 return; | |
189 | |
190 Lnodecl: | |
191 if (decl) | |
192 error("pragma is missing closing ';'"); | |
193 } | |
194 | |
72 | 195 override void setScope(Scope sc) |
0 | 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 | |
72 | 228 override bool oneMember(Dsymbol* ps) |
0 | 229 { |
162 | 230 *ps = null; |
231 return true; | |
0 | 232 } |
233 | |
72 | 234 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 235 { |
236 assert(false); | |
237 } | |
238 | |
72 | 239 override string kind() |
0 | 240 { |
241 assert(false); | |
242 } | |
243 | |
72 | 244 override void toObjFile(int multiobj) // compile to .obj file |
0 | 245 { |
246 if (ident == Id.lib) | |
247 { | |
248 assert(args && args.dim == 1); | |
249 | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
250 auto e = args[0]; |
0 | 251 |
252 assert(e.op == TOKstring); | |
253 | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
254 auto se = cast(StringExp)e; |
2 | 255 char* name = cast(char*)GC.malloc(se.len + 1); |
0 | 256 memcpy(name, se.string_, se.len); |
257 name[se.len] = 0; | |
258 version (OMFOBJ) { | |
259 /* The OMF format allows library names to be inserted | |
260 * into the object file. The linker will then automatically | |
261 * search that library, too. | |
262 */ | |
263 obj_includelib(name); | |
264 } else version (ELFOBJ_OR_MACHOBJ) { | |
265 /* The format does not allow embedded library names, | |
266 * so instead append the library name to the list to be passed | |
267 * to the linker. | |
268 */ | |
269 global.params.libfiles.push(cast(void*) name); | |
270 } else { | |
271 error("pragma lib not supported"); | |
272 } | |
273 } | |
274 /// version (DMDV2) { | |
275 else if (ident == Id.startaddress) | |
276 { | |
277 assert(args && args.dim == 1); | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
278 auto e = args[0]; |
0 | 279 Dsymbol sa = getDsymbol(e); |
280 FuncDeclaration f = sa.isFuncDeclaration(); | |
281 assert(f); | |
282 Symbol* s = f.toSymbol(); | |
283 obj_startaddress(s); | |
284 } | |
285 /// } | |
286 AttribDeclaration.toObjFile(multiobj); | |
287 } | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
4
diff
changeset
|
288 } |