Mercurial > projects > ldc
annotate dmd/declaration.c @ 1083:c1e9f612e2e2
Fix for dual operand form of fistp, also make reg ST(0) explicit and fix lindquists
previous code that allowed dual operand form of fstp but dissallowed the single
operand form accidently
author | Kelly Wilson <wilsonk cpsc.ucalgary.ca> |
---|---|
date | Tue, 10 Mar 2009 06:23:26 -0600 |
parents | 545f54041d91 |
children | b30fe7e1dbb9 |
rev | line source |
---|---|
159 | 1 |
2 // Compiler implementation of the D programming language | |
336 | 3 // Copyright (c) 1999-2008 by Digital Mars |
159 | 4 // All Rights Reserved |
5 // written by Walter Bright | |
6 // http://www.digitalmars.com | |
7 // License for redistribution is by either the Artistic License | |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | |
9 // See the included readme.txt for details. | |
10 | |
11 #include <stdio.h> | |
12 #include <assert.h> | |
13 | |
14 #include "init.h" | |
15 #include "declaration.h" | |
16 #include "attrib.h" | |
17 #include "mtype.h" | |
18 #include "template.h" | |
19 #include "scope.h" | |
20 #include "aggregate.h" | |
21 #include "module.h" | |
22 #include "id.h" | |
23 #include "expression.h" | |
24 #include "hdrgen.h" | |
25 | |
26 /********************************* Declaration ****************************/ | |
27 | |
28 Declaration::Declaration(Identifier *id) | |
29 : Dsymbol(id) | |
30 { | |
31 type = NULL; | |
32 originalType = NULL; | |
33 storage_class = STCundefined; | |
34 protection = PROTundefined; | |
35 linkage = LINKdefault; | |
36 } | |
37 | |
38 void Declaration::semantic(Scope *sc) | |
39 { | |
40 } | |
41 | |
336 | 42 const char *Declaration::kind() |
159 | 43 { |
44 return "declaration"; | |
45 } | |
46 | |
47 unsigned Declaration::size(Loc loc) | |
48 { | |
49 assert(type); | |
50 return type->size(); | |
51 } | |
52 | |
53 int Declaration::isStaticConstructor() | |
54 { | |
55 return FALSE; | |
56 } | |
57 | |
58 int Declaration::isStaticDestructor() | |
59 { | |
60 return FALSE; | |
61 } | |
62 | |
63 int Declaration::isDelete() | |
64 { | |
65 return FALSE; | |
66 } | |
67 | |
68 int Declaration::isDataseg() | |
69 { | |
70 return FALSE; | |
71 } | |
72 | |
73 int Declaration::isCodeseg() | |
74 { | |
75 return FALSE; | |
76 } | |
77 | |
78 enum PROT Declaration::prot() | |
79 { | |
80 return protection; | |
81 } | |
82 | |
336 | 83 /************************************* |
84 * Check to see if declaration can be modified in this context (sc). | |
85 * Issue error if not. | |
86 */ | |
87 | |
88 #if DMDV2 | |
89 void Declaration::checkModify(Loc loc, Scope *sc, Type *t) | |
90 { | |
91 if (sc->incontract && isParameter()) | |
92 error(loc, "cannot modify parameter '%s' in contract", toChars()); | |
93 | |
94 if (isCtorinit()) | |
95 { // It's only modifiable if inside the right constructor | |
96 Dsymbol *s = sc->func; | |
97 while (1) | |
98 { | |
99 FuncDeclaration *fd = NULL; | |
100 if (s) | |
101 fd = s->isFuncDeclaration(); | |
102 if (fd && | |
103 ((fd->isCtorDeclaration() && storage_class & STCfield) || | |
104 (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) && | |
105 fd->toParent() == toParent() | |
106 ) | |
107 { | |
108 VarDeclaration *v = isVarDeclaration(); | |
109 assert(v); | |
110 v->ctorinit = 1; | |
111 //printf("setting ctorinit\n"); | |
112 } | |
113 else | |
114 { | |
115 if (s) | |
116 { s = s->toParent2(); | |
117 continue; | |
118 } | |
119 else | |
120 { | |
121 const char *p = isStatic() ? "static " : ""; | |
122 error(loc, "can only initialize %sconst %s inside %sconstructor", | |
123 p, toChars(), p); | |
124 } | |
125 } | |
126 break; | |
127 } | |
128 } | |
129 else | |
130 { | |
131 VarDeclaration *v = isVarDeclaration(); | |
132 if (v && v->canassign == 0) | |
133 { | |
134 char *p = NULL; | |
135 if (isConst()) | |
136 p = "const"; | |
137 else if (isInvariant()) | |
138 p = "invariant"; | |
139 else if (storage_class & STCmanifest) | |
140 p = "manifest constant"; | |
141 else if (!t->isAssignable()) | |
142 p = "struct with immutable members"; | |
143 if (p) | |
144 { error(loc, "cannot modify %s", p); | |
145 halt(); | |
146 } | |
147 } | |
148 } | |
149 } | |
150 #endif | |
151 | |
152 | |
159 | 153 /********************************* TupleDeclaration ****************************/ |
154 | |
155 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects) | |
156 : Declaration(id) | |
157 { | |
158 this->type = NULL; | |
159 this->objects = objects; | |
160 this->isexp = 0; | |
161 this->tupletype = NULL; | |
162 } | |
163 | |
164 Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s) | |
165 { | |
166 assert(0); | |
167 return NULL; | |
168 } | |
169 | |
336 | 170 const char *TupleDeclaration::kind() |
159 | 171 { |
172 return "tuple"; | |
173 } | |
174 | |
175 Type *TupleDeclaration::getType() | |
176 { | |
177 /* If this tuple represents a type, return that type | |
178 */ | |
179 | |
180 //printf("TupleDeclaration::getType() %s\n", toChars()); | |
181 if (isexp) | |
182 return NULL; | |
183 if (!tupletype) | |
184 { | |
185 /* It's only a type tuple if all the Object's are types | |
186 */ | |
187 for (size_t i = 0; i < objects->dim; i++) | |
188 { Object *o = (Object *)objects->data[i]; | |
189 | |
190 if (o->dyncast() != DYNCAST_TYPE) | |
191 { | |
192 //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast()); | |
193 return NULL; | |
194 } | |
195 } | |
196 | |
197 /* We know it's a type tuple, so build the TypeTuple | |
198 */ | |
199 Arguments *args = new Arguments(); | |
200 args->setDim(objects->dim); | |
201 OutBuffer buf; | |
202 for (size_t i = 0; i < objects->dim; i++) | |
203 { Type *t = (Type *)objects->data[i]; | |
204 | |
205 //printf("type = %s\n", t->toChars()); | |
206 #if 0 | |
207 buf.printf("_%s_%d", ident->toChars(), i); | |
208 char *name = (char *)buf.extractData(); | |
209 Identifier *id = new Identifier(name, TOKidentifier); | |
210 Argument *arg = new Argument(STCin, t, id, NULL); | |
211 #else | |
212 Argument *arg = new Argument(STCin, t, NULL, NULL); | |
213 #endif | |
214 args->data[i] = (void *)arg; | |
215 } | |
216 | |
217 tupletype = new TypeTuple(args); | |
218 } | |
219 | |
220 return tupletype; | |
221 } | |
222 | |
223 int TupleDeclaration::needThis() | |
224 { | |
225 //printf("TupleDeclaration::needThis(%s)\n", toChars()); | |
226 for (size_t i = 0; i < objects->dim; i++) | |
227 { Object *o = (Object *)objects->data[i]; | |
228 if (o->dyncast() == DYNCAST_EXPRESSION) | |
229 { Expression *e = (Expression *)o; | |
230 if (e->op == TOKdsymbol) | |
231 { DsymbolExp *ve = (DsymbolExp *)e; | |
232 Declaration *d = ve->s->isDeclaration(); | |
233 if (d && d->needThis()) | |
234 { | |
235 return 1; | |
236 } | |
237 } | |
238 } | |
239 } | |
240 return 0; | |
241 } | |
242 | |
243 /********************************* TypedefDeclaration ****************************/ | |
244 | |
245 TypedefDeclaration::TypedefDeclaration(Loc loc, Identifier *id, Type *basetype, Initializer *init) | |
246 : Declaration(id) | |
247 { | |
248 this->type = new TypeTypedef(this); | |
249 this->basetype = basetype->toBasetype(); | |
250 this->init = init; | |
251 #ifdef _DH | |
252 this->htype = NULL; | |
253 this->hbasetype = NULL; | |
254 #endif | |
255 this->sem = 0; | |
256 this->inuse = 0; | |
257 this->loc = loc; | |
258 this->sinit = NULL; | |
259 } | |
260 | |
261 Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s) | |
262 { | |
263 Type *basetype = this->basetype->syntaxCopy(); | |
264 | |
265 Initializer *init = NULL; | |
266 if (this->init) | |
267 init = this->init->syntaxCopy(); | |
268 | |
269 assert(!s); | |
270 TypedefDeclaration *st; | |
271 st = new TypedefDeclaration(loc, ident, basetype, init); | |
272 #ifdef _DH | |
273 // Syntax copy for header file | |
274 if (!htype) // Don't overwrite original | |
275 { if (type) // Make copy for both old and new instances | |
276 { htype = type->syntaxCopy(); | |
277 st->htype = type->syntaxCopy(); | |
278 } | |
279 } | |
280 else // Make copy of original for new instance | |
281 st->htype = htype->syntaxCopy(); | |
282 if (!hbasetype) | |
283 { if (basetype) | |
284 { hbasetype = basetype->syntaxCopy(); | |
285 st->hbasetype = basetype->syntaxCopy(); | |
286 } | |
287 } | |
288 else | |
289 st->hbasetype = hbasetype->syntaxCopy(); | |
290 #endif | |
291 return st; | |
292 } | |
293 | |
294 void TypedefDeclaration::semantic(Scope *sc) | |
295 { | |
296 //printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem); | |
297 if (sem == 0) | |
298 { sem = 1; | |
299 basetype = basetype->semantic(loc, sc); | |
300 sem = 2; | |
301 type = type->semantic(loc, sc); | |
302 if (sc->parent->isFuncDeclaration() && init) | |
303 semantic2(sc); | |
336 | 304 storage_class |= sc->stc & STCdeprecated; |
159 | 305 } |
306 else if (sem == 1) | |
307 { | |
308 error("circular definition"); | |
309 } | |
310 } | |
311 | |
312 void TypedefDeclaration::semantic2(Scope *sc) | |
313 { | |
314 //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem); | |
315 if (sem == 2) | |
316 { sem = 3; | |
317 if (init) | |
318 { | |
319 init = init->semantic(sc, basetype); | |
320 | |
321 ExpInitializer *ie = init->isExpInitializer(); | |
322 if (ie) | |
323 { | |
324 if (ie->exp->type == basetype) | |
325 ie->exp->type = type; | |
326 } | |
327 } | |
328 } | |
329 } | |
330 | |
336 | 331 const char *TypedefDeclaration::kind() |
159 | 332 { |
333 return "typedef"; | |
334 } | |
335 | |
336 Type *TypedefDeclaration::getType() | |
337 { | |
338 return type; | |
339 } | |
340 | |
341 void TypedefDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
342 { | |
343 buf->writestring("typedef "); | |
344 basetype->toCBuffer(buf, ident, hgs); | |
345 if (init) | |
346 { | |
347 buf->writestring(" = "); | |
348 init->toCBuffer(buf, hgs); | |
349 } | |
350 buf->writeByte(';'); | |
351 buf->writenl(); | |
352 } | |
353 | |
354 /********************************* AliasDeclaration ****************************/ | |
355 | |
356 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type) | |
357 : Declaration(id) | |
358 { | |
359 //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type); | |
360 //printf("type = '%s'\n", type->toChars()); | |
361 this->loc = loc; | |
362 this->type = type; | |
363 this->aliassym = NULL; | |
364 #ifdef _DH | |
365 this->htype = NULL; | |
366 this->haliassym = NULL; | |
367 #endif | |
368 this->overnext = NULL; | |
369 this->inSemantic = 0; | |
370 assert(type); | |
371 } | |
372 | |
373 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s) | |
374 : Declaration(id) | |
375 { | |
376 //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s); | |
377 assert(s != this); | |
378 this->loc = loc; | |
379 this->type = NULL; | |
380 this->aliassym = s; | |
381 #ifdef _DH | |
382 this->htype = NULL; | |
383 this->haliassym = NULL; | |
384 #endif | |
385 this->overnext = NULL; | |
386 this->inSemantic = 0; | |
387 assert(s); | |
388 } | |
389 | |
390 Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s) | |
391 { | |
336 | 392 //printf("AliasDeclaration::syntaxCopy()\n"); |
159 | 393 assert(!s); |
394 AliasDeclaration *sa; | |
395 if (type) | |
396 sa = new AliasDeclaration(loc, ident, type->syntaxCopy()); | |
397 else | |
398 sa = new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL)); | |
399 #ifdef _DH | |
400 // Syntax copy for header file | |
401 if (!htype) // Don't overwrite original | |
402 { if (type) // Make copy for both old and new instances | |
403 { htype = type->syntaxCopy(); | |
404 sa->htype = type->syntaxCopy(); | |
405 } | |
406 } | |
407 else // Make copy of original for new instance | |
408 sa->htype = htype->syntaxCopy(); | |
409 if (!haliassym) | |
410 { if (aliassym) | |
411 { haliassym = aliassym->syntaxCopy(s); | |
412 sa->haliassym = aliassym->syntaxCopy(s); | |
413 } | |
414 } | |
415 else | |
416 sa->haliassym = haliassym->syntaxCopy(s); | |
417 #endif | |
418 return sa; | |
419 } | |
420 | |
421 void AliasDeclaration::semantic(Scope *sc) | |
422 { | |
423 //printf("AliasDeclaration::semantic() %s\n", toChars()); | |
424 if (aliassym) | |
425 { | |
426 if (aliassym->isTemplateInstance()) | |
427 aliassym->semantic(sc); | |
428 return; | |
429 } | |
430 this->inSemantic = 1; | |
431 | |
432 if (storage_class & STCconst) | |
433 error("cannot be const"); | |
434 | |
435 storage_class |= sc->stc & STCdeprecated; | |
436 | |
437 // Given: | |
438 // alias foo.bar.abc def; | |
439 // it is not knowable from the syntax whether this is an alias | |
440 // for a type or an alias for a symbol. It is up to the semantic() | |
441 // pass to distinguish. | |
442 // If it is a type, then type is set and getType() will return that | |
443 // type. If it is a symbol, then aliassym is set and type is NULL - | |
444 // toAlias() will return aliasssym. | |
445 | |
446 Dsymbol *s; | |
447 Type *t; | |
448 Expression *e; | |
449 | |
450 /* This section is needed because resolve() will: | |
451 * const x = 3; | |
452 * alias x y; | |
453 * try to alias y to 3. | |
454 */ | |
455 s = type->toDsymbol(sc); | |
456 if (s) | |
457 goto L2; // it's a symbolic alias | |
458 | |
459 //printf("alias type is %s\n", type->toChars()); | |
460 type->resolve(loc, sc, &e, &t, &s); | |
461 if (s) | |
462 { | |
463 goto L2; | |
464 } | |
465 else if (e) | |
466 { | |
467 // Try to convert Expression to Dsymbol | |
468 if (e->op == TOKvar) | |
469 { s = ((VarExp *)e)->var; | |
470 goto L2; | |
471 } | |
472 else if (e->op == TOKfunction) | |
473 { s = ((FuncExp *)e)->fd; | |
474 goto L2; | |
475 } | |
476 else | |
477 { error("cannot alias an expression %s", e->toChars()); | |
478 t = e->type; | |
479 } | |
480 } | |
481 else if (t) | |
482 type = t; | |
483 if (overnext) | |
484 ScopeDsymbol::multiplyDefined(0, this, overnext); | |
485 this->inSemantic = 0; | |
486 return; | |
487 | |
488 L2: | |
489 //printf("alias is a symbol %s %s\n", s->kind(), s->toChars()); | |
490 type = NULL; | |
491 VarDeclaration *v = s->isVarDeclaration(); | |
492 if (v && v->linkage == LINKdefault) | |
493 { | |
494 error("forward reference of %s", v->toChars()); | |
495 s = NULL; | |
496 } | |
497 else | |
498 { | |
499 FuncDeclaration *f = s->toAlias()->isFuncDeclaration(); | |
500 if (f) | |
501 { | |
502 if (overnext) | |
503 { | |
504 FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); | |
505 if (!fa->overloadInsert(overnext)) | |
506 ScopeDsymbol::multiplyDefined(0, f, overnext); | |
507 overnext = NULL; | |
508 s = fa; | |
509 s->parent = sc->parent; | |
510 } | |
511 } | |
512 if (overnext) | |
513 ScopeDsymbol::multiplyDefined(0, s, overnext); | |
514 if (s == this) | |
515 { | |
516 assert(global.errors); | |
517 s = NULL; | |
518 } | |
519 } | |
520 aliassym = s; | |
521 this->inSemantic = 0; | |
522 } | |
523 | |
524 int AliasDeclaration::overloadInsert(Dsymbol *s) | |
525 { | |
526 /* Don't know yet what the aliased symbol is, so assume it can | |
527 * be overloaded and check later for correctness. | |
528 */ | |
529 | |
530 //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars()); | |
531 if (overnext == NULL) | |
532 { overnext = s; | |
533 return TRUE; | |
534 } | |
535 else | |
536 { | |
537 return overnext->overloadInsert(s); | |
538 } | |
539 } | |
540 | |
336 | 541 const char *AliasDeclaration::kind() |
159 | 542 { |
543 return "alias"; | |
544 } | |
545 | |
546 Type *AliasDeclaration::getType() | |
547 { | |
548 return type; | |
549 } | |
550 | |
551 Dsymbol *AliasDeclaration::toAlias() | |
552 { | |
553 //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); | |
554 assert(this != aliassym); | |
555 //static int count; if (++count == 10) *(char*)0=0; | |
556 if (inSemantic) | |
557 { error("recursive alias declaration"); | |
558 // return this; | |
559 } | |
560 Dsymbol *s = aliassym ? aliassym->toAlias() : this; | |
561 return s; | |
562 } | |
563 | |
564 void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
565 { | |
566 buf->writestring("alias "); | |
567 #if 0 && _DH | |
568 if (hgs->hdrgen) | |
569 { | |
570 if (haliassym) | |
571 { | |
572 haliassym->toCBuffer(buf, hgs); | |
573 buf->writeByte(' '); | |
574 buf->writestring(ident->toChars()); | |
575 } | |
576 else | |
577 htype->toCBuffer(buf, ident, hgs); | |
578 } | |
579 else | |
580 #endif | |
581 { | |
582 if (aliassym) | |
583 { | |
584 aliassym->toCBuffer(buf, hgs); | |
585 buf->writeByte(' '); | |
586 buf->writestring(ident->toChars()); | |
587 } | |
588 else | |
589 type->toCBuffer(buf, ident, hgs); | |
590 } | |
591 buf->writeByte(';'); | |
592 buf->writenl(); | |
593 } | |
594 | |
595 /********************************* VarDeclaration ****************************/ | |
596 | |
597 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) | |
598 : Declaration(id) | |
599 { | |
600 //printf("VarDeclaration('%s')\n", id->toChars()); | |
601 #ifdef DEBUG | |
602 if (!type && !init) | |
603 { printf("VarDeclaration('%s')\n", id->toChars()); | |
604 //*(char*)0=0; | |
605 } | |
606 #endif | |
607 assert(type || init); | |
608 this->type = type; | |
609 this->init = init; | |
610 #ifdef _DH | |
611 this->htype = NULL; | |
612 this->hinit = NULL; | |
613 #endif | |
614 this->loc = loc; | |
615 offset = 0; | |
616 noauto = 0; | |
617 nestedref = 0; | |
618 inuse = 0; | |
619 ctorinit = 0; | |
620 aliassym = NULL; | |
621 onstack = 0; | |
622 canassign = 0; | |
623 value = NULL; | |
737
041c1596d217
Removed warnings on ignored aligns. Only do aligment on packed structs, align(1) struct Packed { ... }
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
624 |
041c1596d217
Removed warnings on ignored aligns. Only do aligment on packed structs, align(1) struct Packed { ... }
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
625 // LDC |
041c1596d217
Removed warnings on ignored aligns. Only do aligment on packed structs, align(1) struct Packed { ... }
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
658
diff
changeset
|
626 anonDecl = NULL; |
797
340acf1535d0
Removed KDevelop3 project files, CMake can generate them just fine!
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
737
diff
changeset
|
627 offset2 = 0; |
920
545f54041d91
Implemented proper support for naked asm using llvm module level asm. Still not 100% complete, but already 1000 times better that what we had before. Don's BignumX86 implementation from Tango (when turned into a standalone unittest) seems to fully work with no changes, and great performance :)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
913
diff
changeset
|
628 nakedUse = false; |
159 | 629 } |
630 | |
631 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) | |
632 { | |
633 //printf("VarDeclaration::syntaxCopy(%s)\n", toChars()); | |
634 | |
635 VarDeclaration *sv; | |
636 if (s) | |
637 { sv = (VarDeclaration *)s; | |
638 } | |
639 else | |
640 { | |
641 Initializer *init = NULL; | |
642 if (this->init) | |
643 { init = this->init->syntaxCopy(); | |
644 //init->isExpInitializer()->exp->print(); | |
645 //init->isExpInitializer()->exp->dump(0); | |
646 } | |
647 | |
648 sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init); | |
649 sv->storage_class = storage_class; | |
650 } | |
651 #ifdef _DH | |
652 // Syntax copy for header file | |
653 if (!htype) // Don't overwrite original | |
654 { if (type) // Make copy for both old and new instances | |
655 { htype = type->syntaxCopy(); | |
656 sv->htype = type->syntaxCopy(); | |
657 } | |
658 } | |
659 else // Make copy of original for new instance | |
660 sv->htype = htype->syntaxCopy(); | |
661 if (!hinit) | |
662 { if (init) | |
663 { hinit = init->syntaxCopy(); | |
664 sv->hinit = init->syntaxCopy(); | |
665 } | |
666 } | |
667 else | |
668 sv->hinit = hinit->syntaxCopy(); | |
669 #endif | |
670 return sv; | |
671 } | |
672 | |
673 void VarDeclaration::semantic(Scope *sc) | |
674 { | |
675 //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); | |
336 | 676 //printf(" type = %s\n", type ? type->toChars() : "null"); |
677 //printf(" stc = x%x\n", sc->stc); | |
678 //printf(" storage_class = x%x\n", storage_class); | |
159 | 679 //printf("linkage = %d\n", sc->linkage); |
680 //if (strcmp(toChars(), "mul") == 0) halt(); | |
681 | |
682 storage_class |= sc->stc; | |
683 if (storage_class & STCextern && init) | |
684 error("extern symbols cannot have initializers"); | |
685 | |
686 /* If auto type inference, do the inference | |
687 */ | |
688 int inferred = 0; | |
689 if (!type) | |
690 { inuse++; | |
691 type = init->inferType(sc); | |
692 inuse--; | |
693 inferred = 1; | |
694 | |
695 /* This is a kludge to support the existing syntax for RAII | |
696 * declarations. | |
697 */ | |
698 storage_class &= ~STCauto; | |
699 originalType = type; | |
700 } | |
701 else | |
702 { if (!originalType) | |
703 originalType = type; | |
704 type = type->semantic(loc, sc); | |
705 } | |
336 | 706 //printf(" semantic type = %s\n", type ? type->toChars() : "null"); |
159 | 707 |
708 type->checkDeprecated(loc, sc); | |
709 linkage = sc->linkage; | |
710 this->parent = sc->parent; | |
711 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); | |
712 protection = sc->protection; | |
713 //printf("sc->stc = %x\n", sc->stc); | |
336 | 714 //printf("storage_class = x%x\n", storage_class); |
159 | 715 |
716 Dsymbol *parent = toParent(); | |
717 FuncDeclaration *fd = parent->isFuncDeclaration(); | |
718 | |
719 Type *tb = type->toBasetype(); | |
720 if (tb->ty == Tvoid && !(storage_class & STClazy)) | |
721 { error("voids have no value"); | |
722 type = Type::terror; | |
723 tb = type; | |
724 } | |
725 if (tb->ty == Tfunction) | |
726 { error("cannot be declared to be a function"); | |
727 type = Type::terror; | |
728 tb = type; | |
729 } | |
730 if (tb->ty == Tstruct) | |
731 { TypeStruct *ts = (TypeStruct *)tb; | |
732 | |
733 if (!ts->sym->members) | |
734 { | |
735 error("no definition of struct %s", ts->toChars()); | |
736 } | |
737 } | |
738 | |
739 if (tb->ty == Ttuple) | |
740 { /* Instead, declare variables for each of the tuple elements | |
741 * and add those. | |
742 */ | |
743 TypeTuple *tt = (TypeTuple *)tb; | |
744 size_t nelems = Argument::dim(tt->arguments); | |
745 Objects *exps = new Objects(); | |
746 exps->setDim(nelems); | |
747 Expression *ie = init ? init->toExpression() : NULL; | |
748 | |
749 for (size_t i = 0; i < nelems; i++) | |
750 { Argument *arg = Argument::getNth(tt->arguments, i); | |
751 | |
752 OutBuffer buf; | |
305
2b72433d5c8c
[svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.
lindquist
parents:
245
diff
changeset
|
753 buf.printf("_%s_field_%"PRIuSIZE, ident->toChars(), i); |
159 | 754 buf.writeByte(0); |
755 char *name = (char *)buf.extractData(); | |
756 Identifier *id = new Identifier(name, TOKidentifier); | |
757 | |
758 Expression *einit = ie; | |
759 if (ie && ie->op == TOKtuple) | |
760 { einit = (Expression *)((TupleExp *)ie)->exps->data[i]; | |
761 } | |
762 Initializer *ti = init; | |
763 if (einit) | |
764 { ti = new ExpInitializer(einit->loc, einit); | |
765 } | |
766 | |
767 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); | |
768 //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); | |
769 v->semantic(sc); | |
770 | |
771 if (sc->scopesym) | |
772 { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars()); | |
773 if (sc->scopesym->members) | |
774 sc->scopesym->members->push(v); | |
775 } | |
776 | |
777 Expression *e = new DsymbolExp(loc, v); | |
778 exps->data[i] = e; | |
779 } | |
780 TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps); | |
781 v2->isexp = 1; | |
782 aliassym = v2; | |
783 return; | |
784 } | |
785 | |
786 if (storage_class & STCconst && !init && !fd) | |
787 // Initialize by constructor only | |
788 storage_class = (storage_class & ~STCconst) | STCctorinit; | |
789 | |
790 if (isConst()) | |
791 { | |
792 } | |
793 else if (isStatic()) | |
794 { | |
795 } | |
796 else if (isSynchronized()) | |
797 { | |
798 error("variable %s cannot be synchronized", toChars()); | |
799 } | |
800 else if (isOverride()) | |
801 { | |
802 error("override cannot be applied to variable"); | |
803 } | |
804 else if (isAbstract()) | |
805 { | |
806 error("abstract cannot be applied to variable"); | |
807 } | |
808 else if (storage_class & STCtemplateparameter) | |
809 { | |
810 } | |
811 else | |
812 { | |
813 AggregateDeclaration *aad = sc->anonAgg; | |
814 if (!aad) | |
815 aad = parent->isAggregateDeclaration(); | |
816 if (aad) | |
817 { | |
818 aad->addField(sc, this); | |
819 } | |
820 | |
821 InterfaceDeclaration *id = parent->isInterfaceDeclaration(); | |
822 if (id) | |
823 { | |
824 error("field not allowed in interface"); | |
825 } | |
826 | |
336 | 827 /* Templates cannot add fields to aggregates |
828 */ | |
159 | 829 TemplateInstance *ti = parent->isTemplateInstance(); |
830 if (ti) | |
831 { | |
832 // Take care of nested templates | |
833 while (1) | |
834 { | |
835 TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance(); | |
836 if (!ti2) | |
837 break; | |
838 ti = ti2; | |
839 } | |
840 | |
841 // If it's a member template | |
842 AggregateDeclaration *ad = ti->tempdecl->isMember(); | |
843 if (ad && storage_class != STCundefined) | |
844 { | |
845 error("cannot use template to add field to aggregate '%s'", ad->toChars()); | |
846 } | |
847 } | |
848 } | |
849 | |
850 if (type->isauto() && !noauto) | |
851 { | |
852 if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) | |
853 { | |
854 error("globals, statics, fields, ref and out parameters cannot be auto"); | |
855 } | |
856 | |
857 if (!(storage_class & (STCauto | STCscope))) | |
858 { | |
859 if (!(storage_class & STCparameter) && ident != Id::withSym) | |
860 error("reference to scope class must be scope"); | |
861 } | |
862 } | |
863 | |
864 if (!init && !sc->inunion && !isStatic() && !isConst() && fd && | |
865 !(storage_class & (STCfield | STCin | STCforeach)) && | |
866 type->size() != 0) | |
867 { | |
868 // Provide a default initializer | |
869 //printf("Providing default initializer for '%s'\n", toChars()); | |
870 if (type->ty == Tstruct && | |
871 ((TypeStruct *)type)->sym->zeroInit == 1) | |
872 { /* If a struct is all zeros, as a special case | |
873 * set it's initializer to the integer 0. | |
874 * In AssignExp::toElem(), we check for this and issue | |
875 * a memset() to initialize the struct. | |
876 * Must do same check in interpreter. | |
877 */ | |
878 Expression *e = new IntegerExp(loc, 0, Type::tint32); | |
879 Expression *e1; | |
880 e1 = new VarExp(loc, this); | |
881 e = new AssignExp(loc, e1, e); | |
882 e->type = e1->type; | |
883 init = new ExpInitializer(loc, e/*->type->defaultInit()*/); | |
884 return; | |
885 } | |
886 else if (type->ty == Ttypedef) | |
887 { TypeTypedef *td = (TypeTypedef *)type; | |
888 if (td->sym->init) | |
889 { init = td->sym->init; | |
890 ExpInitializer *ie = init->isExpInitializer(); | |
891 if (ie) | |
892 // Make copy so we can modify it | |
893 init = new ExpInitializer(ie->loc, ie->exp); | |
894 } | |
895 else | |
896 init = getExpInitializer(); | |
897 } | |
898 else | |
899 { | |
900 init = getExpInitializer(); | |
901 } | |
902 } | |
903 | |
904 if (init) | |
905 { | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
906 sc = sc->push(); |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
907 sc->stc &= ~(STCconst | STCinvariant | STCpure); |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
908 |
159 | 909 ArrayInitializer *ai = init->isArrayInitializer(); |
910 if (ai && tb->ty == Taarray) | |
911 { | |
912 init = ai->toAssocArrayInitializer(); | |
913 } | |
914 | |
915 StructInitializer *si = init->isStructInitializer(); | |
916 ExpInitializer *ei = init->isExpInitializer(); | |
917 | |
918 // See if we can allocate on the stack | |
919 if (ei && isScope() && ei->exp->op == TOKnew) | |
920 { NewExp *ne = (NewExp *)ei->exp; | |
921 if (!(ne->newargs && ne->newargs->dim)) | |
922 { ne->onstack = 1; | |
923 onstack = 1; | |
924 if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL)) | |
925 onstack = 2; | |
926 } | |
927 } | |
928 | |
929 // If inside function, there is no semantic3() call | |
930 if (sc->func) | |
931 { | |
932 // If local variable, use AssignExp to handle all the various | |
933 // possibilities. | |
934 if (fd && !isStatic() && !isConst() && !init->isVoidInitializer()) | |
935 { | |
936 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); | |
937 if (!ei) | |
938 { | |
939 Expression *e = init->toExpression(); | |
940 if (!e) | |
941 { | |
942 init = init->semantic(sc, type); | |
943 e = init->toExpression(); | |
944 if (!e) | |
945 { error("is not a static and cannot have static initializer"); | |
946 return; | |
947 } | |
948 } | |
949 ei = new ExpInitializer(init->loc, e); | |
950 init = ei; | |
951 } | |
952 | |
336 | 953 Expression *e1 = new VarExp(loc, this); |
159 | 954 |
336 | 955 Type *t = type->toBasetype(); |
159 | 956 if (t->ty == Tsarray) |
957 { | |
958 ei->exp = ei->exp->semantic(sc); | |
959 if (!ei->exp->implicitConvTo(type)) | |
960 { | |
336 | 961 int dim = ((TypeSArray *)t)->dim->toInteger(); |
159 | 962 // If multidimensional static array, treat as one large array |
963 while (1) | |
964 { | |
965 t = t->nextOf()->toBasetype(); | |
966 if (t->ty != Tsarray) | |
967 break; | |
968 dim *= ((TypeSArray *)t)->dim->toInteger(); | |
969 e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex)); | |
970 } | |
971 } | |
972 e1 = new SliceExp(loc, e1, NULL, NULL); | |
973 } | |
974 else if (t->ty == Tstruct) | |
975 { | |
976 ei->exp = ei->exp->semantic(sc); | |
977 if (!ei->exp->implicitConvTo(type)) | |
978 ei->exp = new CastExp(loc, ei->exp, type); | |
979 } | |
980 ei->exp = new AssignExp(loc, e1, ei->exp); | |
981 ei->exp->op = TOKconstruct; | |
982 canassign++; | |
983 ei->exp = ei->exp->semantic(sc); | |
984 canassign--; | |
985 ei->exp->optimize(WANTvalue); | |
986 } | |
987 else | |
988 { | |
989 init = init->semantic(sc, type); | |
990 if (fd && isConst() && !isStatic()) | |
991 { // Make it static | |
992 storage_class |= STCstatic; | |
993 } | |
994 } | |
995 } | |
996 else if (isConst() || isFinal()) | |
997 { | |
998 /* Because we may need the results of a const declaration in a | |
999 * subsequent type, such as an array dimension, before semantic2() | |
1000 * gets ordinarily run, try to run semantic2() now. | |
1001 * Ignore failure. | |
1002 */ | |
1003 | |
1004 if (!global.errors && !inferred) | |
1005 { | |
1006 unsigned errors = global.errors; | |
1007 global.gag++; | |
1008 //printf("+gag\n"); | |
1009 Expression *e; | |
1010 Initializer *i2 = init; | |
1011 inuse++; | |
1012 if (ei) | |
1013 { | |
1014 e = ei->exp->syntaxCopy(); | |
1015 e = e->semantic(sc); | |
1016 e = e->implicitCastTo(sc, type); | |
1017 } | |
1018 else if (si || ai) | |
1019 { i2 = init->syntaxCopy(); | |
1020 i2 = i2->semantic(sc, type); | |
1021 } | |
1022 inuse--; | |
1023 global.gag--; | |
1024 //printf("-gag\n"); | |
1025 if (errors != global.errors) // if errors happened | |
1026 { | |
1027 if (global.gag == 0) | |
1028 global.errors = errors; // act as if nothing happened | |
1029 } | |
1030 else if (ei) | |
1031 { | |
1032 e = e->optimize(WANTvalue | WANTinterpret); | |
1033 if (e->op == TOKint64 || e->op == TOKstring) | |
1034 { | |
1035 ei->exp = e; // no errors, keep result | |
1036 } | |
1037 } | |
1038 else | |
1039 init = i2; // no errors, keep result | |
1040 } | |
1041 } | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
1042 sc = sc->pop(); |
159 | 1043 } |
1044 } | |
1045 | |
1046 ExpInitializer *VarDeclaration::getExpInitializer() | |
1047 { | |
1048 ExpInitializer *ei; | |
1049 | |
1050 if (init) | |
1051 ei = init->isExpInitializer(); | |
1052 else | |
1053 { | |
336 | 1054 Expression *e = type->defaultInit(loc); |
159 | 1055 if (e) |
1056 ei = new ExpInitializer(loc, e); | |
1057 else | |
1058 ei = NULL; | |
1059 } | |
1060 return ei; | |
1061 } | |
1062 | |
1063 void VarDeclaration::semantic2(Scope *sc) | |
1064 { | |
1065 //printf("VarDeclaration::semantic2('%s')\n", toChars()); | |
1066 if (init && !toParent()->isFuncDeclaration()) | |
1067 { inuse++; | |
1068 #if 0 | |
1069 ExpInitializer *ei = init->isExpInitializer(); | |
1070 if (ei) | |
1071 { | |
1072 ei->exp->dump(0); | |
1073 printf("type = %p\n", ei->exp->type); | |
1074 } | |
1075 #endif | |
1076 init = init->semantic(sc, type); | |
1077 inuse--; | |
1078 } | |
1079 } | |
1080 | |
336 | 1081 const char *VarDeclaration::kind() |
159 | 1082 { |
1083 return "variable"; | |
1084 } | |
1085 | |
1086 Dsymbol *VarDeclaration::toAlias() | |
1087 { | |
1088 //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym); | |
1089 assert(this != aliassym); | |
1090 Dsymbol *s = aliassym ? aliassym->toAlias() : this; | |
1091 return s; | |
1092 } | |
1093 | |
1094 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
1095 { | |
1096 if (storage_class & STCconst) | |
1097 buf->writestring("const "); | |
1098 if (storage_class & STCstatic) | |
1099 buf->writestring("static "); | |
336 | 1100 if (storage_class & STCauto) |
1101 buf->writestring("auto "); | |
1102 #if DMDV2 | |
1103 if (storage_class & STCmanifest) | |
1104 buf->writestring("manifest "); | |
1105 if (storage_class & STCinvariant) | |
1106 buf->writestring("invariant "); | |
1107 if (storage_class & STCtls) | |
1108 buf->writestring("__thread "); | |
1109 #endif | |
1110 | |
159 | 1111 if (type) |
1112 type->toCBuffer(buf, ident, hgs); | |
1113 else | |
1114 buf->writestring(ident->toChars()); | |
1115 if (init) | |
1116 { buf->writestring(" = "); | |
1117 init->toCBuffer(buf, hgs); | |
1118 } | |
1119 buf->writeByte(';'); | |
1120 buf->writenl(); | |
1121 } | |
1122 | |
1123 int VarDeclaration::needThis() | |
1124 { | |
1125 //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class); | |
1126 return storage_class & STCfield; | |
1127 } | |
1128 | |
1129 int VarDeclaration::isImportedSymbol() | |
1130 { | |
1131 if (protection == PROTexport && !init && (isStatic() || isConst() || parent->isModule())) | |
1132 return TRUE; | |
1133 return FALSE; | |
1134 } | |
1135 | |
1136 void VarDeclaration::checkCtorConstInit() | |
1137 { | |
1138 if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield)) | |
1139 error("missing initializer in static constructor for const variable"); | |
1140 } | |
1141 | |
1142 /************************************ | |
336 | 1143 * Check to see if this variable is actually in an enclosing function |
1144 * rather than the current one. | |
159 | 1145 */ |
1146 | |
1147 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) | |
1148 { | |
336 | 1149 //printf("VarDeclaration::checkNestedReference() %s\n", toChars()); |
159 | 1150 if (parent && !isDataseg() && parent != sc->parent) |
1151 { | |
336 | 1152 // The function that this variable is in |
159 | 1153 FuncDeclaration *fdv = toParent()->isFuncDeclaration(); |
336 | 1154 // The current function |
159 | 1155 FuncDeclaration *fdthis = sc->parent->isFuncDeclaration(); |
1156 | |
1157 if (fdv && fdthis) | |
1158 { | |
1159 if (loc.filename) | |
1160 fdthis->getLevel(loc, fdv); | |
1161 nestedref = 1; | |
1162 fdv->nestedFrameRef = 1; | |
1163 fdv->nestedVars.insert(this); | |
1164 //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars()); | |
1165 } | |
1166 } | |
1167 } | |
1168 | |
1169 /******************************* | |
1170 * Does symbol go into data segment? | |
336 | 1171 * Includes extern variables. |
159 | 1172 */ |
1173 | |
1174 int VarDeclaration::isDataseg() | |
1175 { | |
1176 #if 0 | |
1177 printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars()); | |
1178 printf("%x, %p, %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance()); | |
1179 printf("parent = '%s'\n", parent->toChars()); | |
1180 #endif | |
1181 Dsymbol *parent = this->toParent(); | |
1182 if (!parent && !(storage_class & (STCstatic | STCconst))) | |
1183 { error("forward referenced"); | |
1184 type = Type::terror; | |
1185 return 0; | |
1186 } | |
1187 return (storage_class & (STCstatic | STCconst) || | |
1188 parent->isModule() || | |
1189 parent->isTemplateInstance()); | |
1190 } | |
1191 | |
1192 int VarDeclaration::hasPointers() | |
1193 { | |
1194 return (!isDataseg() && type->hasPointers()); | |
1195 } | |
1196 | |
1197 /****************************************** | |
1198 * If a variable has an auto destructor call, return call for it. | |
1199 * Otherwise, return NULL. | |
1200 */ | |
1201 | |
1202 Expression *VarDeclaration::callAutoDtor() | |
1203 { Expression *e = NULL; | |
1204 | |
1205 //printf("VarDeclaration::callAutoDtor() %s\n", toChars()); | |
1206 if (storage_class & (STCauto | STCscope) && !noauto) | |
1207 { | |
1208 for (ClassDeclaration *cd = type->isClassHandle(); | |
1209 cd; | |
1210 cd = cd->baseClass) | |
1211 { | |
1212 /* We can do better if there's a way with onstack | |
1213 * classes to determine if there's no way the monitor | |
1214 * could be set. | |
1215 */ | |
1216 //if (cd->isInterfaceDeclaration()) | |
1217 //error("interface %s cannot be scope", cd->toChars()); | |
1218 if (1 || onstack || cd->dtors.dim) // if any destructors | |
1219 { | |
1220 // delete this; | |
1221 Expression *ec; | |
1222 | |
1223 ec = new VarExp(loc, this); | |
1224 e = new DeleteExp(loc, ec); | |
1225 e->type = Type::tvoid; | |
1226 break; | |
1227 } | |
1228 } | |
1229 } | |
1230 return e; | |
1231 } | |
1232 | |
1233 | |
1234 /********************************* ClassInfoDeclaration ****************************/ | |
1235 | |
1236 ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd) | |
1237 : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL) | |
1238 { | |
1239 this->cd = cd; | |
1240 storage_class = STCstatic; | |
1241 } | |
1242 | |
1243 Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s) | |
1244 { | |
1245 assert(0); // should never be produced by syntax | |
1246 return NULL; | |
1247 } | |
1248 | |
1249 void ClassInfoDeclaration::semantic(Scope *sc) | |
1250 { | |
1251 } | |
1252 | |
1253 /********************************* ModuleInfoDeclaration ****************************/ | |
1254 | |
1255 ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod) | |
1256 : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL) | |
1257 { | |
1258 this->mod = mod; | |
1259 storage_class = STCstatic; | |
1260 } | |
1261 | |
1262 Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s) | |
1263 { | |
1264 assert(0); // should never be produced by syntax | |
1265 return NULL; | |
1266 } | |
1267 | |
1268 void ModuleInfoDeclaration::semantic(Scope *sc) | |
1269 { | |
1270 } | |
1271 | |
1272 /********************************* TypeInfoDeclaration ****************************/ | |
1273 | |
1274 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal) | |
1275 : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL) | |
1276 { | |
1277 this->tinfo = tinfo; | |
1278 storage_class = STCstatic; | |
1279 protection = PROTpublic; | |
1280 linkage = LINKc; | |
1281 } | |
1282 | |
1283 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s) | |
1284 { | |
1285 assert(0); // should never be produced by syntax | |
1286 return NULL; | |
1287 } | |
1288 | |
1289 void TypeInfoDeclaration::semantic(Scope *sc) | |
1290 { | |
1291 assert(linkage == LINKc); | |
1292 } | |
1293 | |
1294 /***************************** TypeInfoConstDeclaration **********************/ | |
1295 | |
336 | 1296 #if DMDV2 |
159 | 1297 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo) |
1298 : TypeInfoDeclaration(tinfo, 0) | |
1299 { | |
1300 } | |
1301 #endif | |
1302 | |
1303 /***************************** TypeInfoInvariantDeclaration **********************/ | |
1304 | |
336 | 1305 #if DMDV2 |
159 | 1306 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo) |
1307 : TypeInfoDeclaration(tinfo, 0) | |
1308 { | |
1309 } | |
1310 #endif | |
1311 | |
1312 /***************************** TypeInfoStructDeclaration **********************/ | |
1313 | |
1314 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) | |
1315 : TypeInfoDeclaration(tinfo, 0) | |
1316 { | |
1317 } | |
1318 | |
1319 /***************************** TypeInfoClassDeclaration ***********************/ | |
1320 | |
1321 TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo) | |
1322 : TypeInfoDeclaration(tinfo, 0) | |
1323 { | |
1324 } | |
1325 | |
1326 /***************************** TypeInfoInterfaceDeclaration *******************/ | |
1327 | |
1328 TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo) | |
1329 : TypeInfoDeclaration(tinfo, 0) | |
1330 { | |
1331 } | |
1332 | |
1333 /***************************** TypeInfoTypedefDeclaration *********************/ | |
1334 | |
1335 TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo) | |
1336 : TypeInfoDeclaration(tinfo, 0) | |
1337 { | |
1338 } | |
1339 | |
1340 /***************************** TypeInfoPointerDeclaration *********************/ | |
1341 | |
1342 TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo) | |
1343 : TypeInfoDeclaration(tinfo, 0) | |
1344 { | |
1345 } | |
1346 | |
1347 /***************************** TypeInfoArrayDeclaration ***********************/ | |
1348 | |
1349 TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo) | |
1350 : TypeInfoDeclaration(tinfo, 0) | |
1351 { | |
1352 } | |
1353 | |
1354 /***************************** TypeInfoStaticArrayDeclaration *****************/ | |
1355 | |
1356 TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo) | |
1357 : TypeInfoDeclaration(tinfo, 0) | |
1358 { | |
1359 } | |
1360 | |
1361 /***************************** TypeInfoAssociativeArrayDeclaration ************/ | |
1362 | |
1363 TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo) | |
1364 : TypeInfoDeclaration(tinfo, 0) | |
1365 { | |
1366 } | |
1367 | |
1368 /***************************** TypeInfoEnumDeclaration ***********************/ | |
1369 | |
1370 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo) | |
1371 : TypeInfoDeclaration(tinfo, 0) | |
1372 { | |
1373 } | |
1374 | |
1375 /***************************** TypeInfoFunctionDeclaration ********************/ | |
1376 | |
1377 TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo) | |
1378 : TypeInfoDeclaration(tinfo, 0) | |
1379 { | |
1380 } | |
1381 | |
1382 /***************************** TypeInfoDelegateDeclaration ********************/ | |
1383 | |
1384 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo) | |
1385 : TypeInfoDeclaration(tinfo, 0) | |
1386 { | |
1387 } | |
1388 | |
1389 /***************************** TypeInfoTupleDeclaration **********************/ | |
1390 | |
1391 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo) | |
1392 : TypeInfoDeclaration(tinfo, 0) | |
1393 { | |
1394 } | |
1395 | |
1396 /********************************* ThisDeclaration ****************************/ | |
1397 | |
1398 // For the "this" parameter to member functions | |
1399 | |
1400 ThisDeclaration::ThisDeclaration(Type *t) | |
1401 : VarDeclaration(0, t, Id::This, NULL) | |
1402 { | |
1403 noauto = 1; | |
1404 } | |
1405 | |
1406 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) | |
1407 { | |
1408 assert(0); // should never be produced by syntax | |
1409 return NULL; | |
1410 } | |
1411 | |
913
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1412 /********************** StaticStructInitDeclaration ***************************/ |
159 | 1413 |
913
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1414 StaticStructInitDeclaration::StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym) |
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1415 : Declaration(new Identifier("", TOKidentifier)) |
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1416 { |
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1417 this->loc = loc; |
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1418 this->dsym = dsym; |
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1419 storage_class |= STCconst; |
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1420 } |
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1421 |