Mercurial > projects > ldc
annotate dmd/declaration.c @ 1138:4c8bb03e4fbc
Update DtoConstFP() to be correct after LLVM r67562, which changed the way the
APFloat constructor expects its i80 APInts to be formatted. (They're now
actually consistent with the x87 format)
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Tue, 24 Mar 2009 15:24:59 +0100 |
parents | 76e72fdef04d |
children | 1860414bf3b7 |
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; | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
920
diff
changeset
|
753 buf.printf("_%s_field_%zu", 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); | |
1132
76e72fdef04d
Fix tuple declarations in aggregates.
Christian Kamm <kamm incasoftware de>
parents:
1103
diff
changeset
|
770 |
76e72fdef04d
Fix tuple declarations in aggregates.
Christian Kamm <kamm incasoftware de>
parents:
1103
diff
changeset
|
771 /* |
76e72fdef04d
Fix tuple declarations in aggregates.
Christian Kamm <kamm incasoftware de>
parents:
1103
diff
changeset
|
772 // removed for LDC since TupleDeclaration::toObj already creates the fields; |
76e72fdef04d
Fix tuple declarations in aggregates.
Christian Kamm <kamm incasoftware de>
parents:
1103
diff
changeset
|
773 // adding them to the scope again leads to duplicates |
159 | 774 if (sc->scopesym) |
775 { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars()); | |
776 if (sc->scopesym->members) | |
777 sc->scopesym->members->push(v); | |
778 } | |
1132
76e72fdef04d
Fix tuple declarations in aggregates.
Christian Kamm <kamm incasoftware de>
parents:
1103
diff
changeset
|
779 */ |
159 | 780 Expression *e = new DsymbolExp(loc, v); |
781 exps->data[i] = e; | |
782 } | |
783 TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps); | |
784 v2->isexp = 1; | |
785 aliassym = v2; | |
786 return; | |
787 } | |
788 | |
789 if (storage_class & STCconst && !init && !fd) | |
790 // Initialize by constructor only | |
791 storage_class = (storage_class & ~STCconst) | STCctorinit; | |
792 | |
793 if (isConst()) | |
794 { | |
795 } | |
796 else if (isStatic()) | |
797 { | |
798 } | |
799 else if (isSynchronized()) | |
800 { | |
801 error("variable %s cannot be synchronized", toChars()); | |
802 } | |
803 else if (isOverride()) | |
804 { | |
805 error("override cannot be applied to variable"); | |
806 } | |
807 else if (isAbstract()) | |
808 { | |
809 error("abstract cannot be applied to variable"); | |
810 } | |
811 else if (storage_class & STCtemplateparameter) | |
812 { | |
813 } | |
814 else | |
815 { | |
816 AggregateDeclaration *aad = sc->anonAgg; | |
817 if (!aad) | |
818 aad = parent->isAggregateDeclaration(); | |
819 if (aad) | |
820 { | |
821 aad->addField(sc, this); | |
822 } | |
823 | |
824 InterfaceDeclaration *id = parent->isInterfaceDeclaration(); | |
825 if (id) | |
826 { | |
827 error("field not allowed in interface"); | |
828 } | |
829 | |
336 | 830 /* Templates cannot add fields to aggregates |
831 */ | |
159 | 832 TemplateInstance *ti = parent->isTemplateInstance(); |
833 if (ti) | |
834 { | |
835 // Take care of nested templates | |
836 while (1) | |
837 { | |
838 TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance(); | |
839 if (!ti2) | |
840 break; | |
841 ti = ti2; | |
842 } | |
843 | |
844 // If it's a member template | |
845 AggregateDeclaration *ad = ti->tempdecl->isMember(); | |
846 if (ad && storage_class != STCundefined) | |
847 { | |
848 error("cannot use template to add field to aggregate '%s'", ad->toChars()); | |
849 } | |
850 } | |
851 } | |
852 | |
853 if (type->isauto() && !noauto) | |
854 { | |
855 if (storage_class & (STCfield | STCout | STCref | STCstatic) || !fd) | |
856 { | |
857 error("globals, statics, fields, ref and out parameters cannot be auto"); | |
858 } | |
859 | |
860 if (!(storage_class & (STCauto | STCscope))) | |
861 { | |
862 if (!(storage_class & STCparameter) && ident != Id::withSym) | |
863 error("reference to scope class must be scope"); | |
864 } | |
865 } | |
866 | |
867 if (!init && !sc->inunion && !isStatic() && !isConst() && fd && | |
868 !(storage_class & (STCfield | STCin | STCforeach)) && | |
869 type->size() != 0) | |
870 { | |
871 // Provide a default initializer | |
872 //printf("Providing default initializer for '%s'\n", toChars()); | |
873 if (type->ty == Tstruct && | |
874 ((TypeStruct *)type)->sym->zeroInit == 1) | |
875 { /* If a struct is all zeros, as a special case | |
876 * set it's initializer to the integer 0. | |
877 * In AssignExp::toElem(), we check for this and issue | |
878 * a memset() to initialize the struct. | |
879 * Must do same check in interpreter. | |
880 */ | |
881 Expression *e = new IntegerExp(loc, 0, Type::tint32); | |
882 Expression *e1; | |
883 e1 = new VarExp(loc, this); | |
884 e = new AssignExp(loc, e1, e); | |
885 e->type = e1->type; | |
886 init = new ExpInitializer(loc, e/*->type->defaultInit()*/); | |
887 return; | |
888 } | |
889 else if (type->ty == Ttypedef) | |
890 { TypeTypedef *td = (TypeTypedef *)type; | |
891 if (td->sym->init) | |
892 { init = td->sym->init; | |
893 ExpInitializer *ie = init->isExpInitializer(); | |
894 if (ie) | |
895 // Make copy so we can modify it | |
896 init = new ExpInitializer(ie->loc, ie->exp); | |
897 } | |
898 else | |
899 init = getExpInitializer(); | |
900 } | |
901 else | |
902 { | |
903 init = getExpInitializer(); | |
904 } | |
905 } | |
906 | |
907 if (init) | |
908 { | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
909 sc = sc->push(); |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
910 sc->stc &= ~(STCconst | STCinvariant | STCpure); |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
911 |
159 | 912 ArrayInitializer *ai = init->isArrayInitializer(); |
913 if (ai && tb->ty == Taarray) | |
914 { | |
915 init = ai->toAssocArrayInitializer(); | |
916 } | |
917 | |
918 StructInitializer *si = init->isStructInitializer(); | |
919 ExpInitializer *ei = init->isExpInitializer(); | |
920 | |
921 // See if we can allocate on the stack | |
922 if (ei && isScope() && ei->exp->op == TOKnew) | |
923 { NewExp *ne = (NewExp *)ei->exp; | |
924 if (!(ne->newargs && ne->newargs->dim)) | |
925 { ne->onstack = 1; | |
926 onstack = 1; | |
927 if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL)) | |
928 onstack = 2; | |
929 } | |
930 } | |
931 | |
932 // If inside function, there is no semantic3() call | |
933 if (sc->func) | |
934 { | |
935 // If local variable, use AssignExp to handle all the various | |
936 // possibilities. | |
937 if (fd && !isStatic() && !isConst() && !init->isVoidInitializer()) | |
938 { | |
939 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); | |
940 if (!ei) | |
941 { | |
942 Expression *e = init->toExpression(); | |
943 if (!e) | |
944 { | |
945 init = init->semantic(sc, type); | |
946 e = init->toExpression(); | |
947 if (!e) | |
948 { error("is not a static and cannot have static initializer"); | |
949 return; | |
950 } | |
951 } | |
952 ei = new ExpInitializer(init->loc, e); | |
953 init = ei; | |
954 } | |
955 | |
336 | 956 Expression *e1 = new VarExp(loc, this); |
159 | 957 |
336 | 958 Type *t = type->toBasetype(); |
159 | 959 if (t->ty == Tsarray) |
960 { | |
961 ei->exp = ei->exp->semantic(sc); | |
962 if (!ei->exp->implicitConvTo(type)) | |
963 { | |
336 | 964 int dim = ((TypeSArray *)t)->dim->toInteger(); |
159 | 965 // If multidimensional static array, treat as one large array |
966 while (1) | |
967 { | |
968 t = t->nextOf()->toBasetype(); | |
969 if (t->ty != Tsarray) | |
970 break; | |
971 dim *= ((TypeSArray *)t)->dim->toInteger(); | |
972 e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex)); | |
973 } | |
974 } | |
975 e1 = new SliceExp(loc, e1, NULL, NULL); | |
976 } | |
977 else if (t->ty == Tstruct) | |
978 { | |
979 ei->exp = ei->exp->semantic(sc); | |
980 if (!ei->exp->implicitConvTo(type)) | |
981 ei->exp = new CastExp(loc, ei->exp, type); | |
982 } | |
983 ei->exp = new AssignExp(loc, e1, ei->exp); | |
984 ei->exp->op = TOKconstruct; | |
985 canassign++; | |
986 ei->exp = ei->exp->semantic(sc); | |
987 canassign--; | |
988 ei->exp->optimize(WANTvalue); | |
989 } | |
990 else | |
991 { | |
992 init = init->semantic(sc, type); | |
993 if (fd && isConst() && !isStatic()) | |
994 { // Make it static | |
995 storage_class |= STCstatic; | |
996 } | |
997 } | |
998 } | |
999 else if (isConst() || isFinal()) | |
1000 { | |
1001 /* Because we may need the results of a const declaration in a | |
1002 * subsequent type, such as an array dimension, before semantic2() | |
1003 * gets ordinarily run, try to run semantic2() now. | |
1004 * Ignore failure. | |
1005 */ | |
1006 | |
1007 if (!global.errors && !inferred) | |
1008 { | |
1009 unsigned errors = global.errors; | |
1010 global.gag++; | |
1011 //printf("+gag\n"); | |
1012 Expression *e; | |
1013 Initializer *i2 = init; | |
1014 inuse++; | |
1015 if (ei) | |
1016 { | |
1017 e = ei->exp->syntaxCopy(); | |
1018 e = e->semantic(sc); | |
1019 e = e->implicitCastTo(sc, type); | |
1020 } | |
1021 else if (si || ai) | |
1022 { i2 = init->syntaxCopy(); | |
1023 i2 = i2->semantic(sc, type); | |
1024 } | |
1025 inuse--; | |
1026 global.gag--; | |
1027 //printf("-gag\n"); | |
1028 if (errors != global.errors) // if errors happened | |
1029 { | |
1030 if (global.gag == 0) | |
1031 global.errors = errors; // act as if nothing happened | |
1032 } | |
1033 else if (ei) | |
1034 { | |
1035 e = e->optimize(WANTvalue | WANTinterpret); | |
1036 if (e->op == TOKint64 || e->op == TOKstring) | |
1037 { | |
1038 ei->exp = e; // no errors, keep result | |
1039 } | |
1040 } | |
1041 else | |
1042 init = i2; // no errors, keep result | |
1043 } | |
1044 } | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
468
diff
changeset
|
1045 sc = sc->pop(); |
159 | 1046 } |
1047 } | |
1048 | |
1049 ExpInitializer *VarDeclaration::getExpInitializer() | |
1050 { | |
1051 ExpInitializer *ei; | |
1052 | |
1053 if (init) | |
1054 ei = init->isExpInitializer(); | |
1055 else | |
1056 { | |
336 | 1057 Expression *e = type->defaultInit(loc); |
159 | 1058 if (e) |
1059 ei = new ExpInitializer(loc, e); | |
1060 else | |
1061 ei = NULL; | |
1062 } | |
1063 return ei; | |
1064 } | |
1065 | |
1066 void VarDeclaration::semantic2(Scope *sc) | |
1067 { | |
1068 //printf("VarDeclaration::semantic2('%s')\n", toChars()); | |
1069 if (init && !toParent()->isFuncDeclaration()) | |
1070 { inuse++; | |
1071 #if 0 | |
1072 ExpInitializer *ei = init->isExpInitializer(); | |
1073 if (ei) | |
1074 { | |
1075 ei->exp->dump(0); | |
1076 printf("type = %p\n", ei->exp->type); | |
1077 } | |
1078 #endif | |
1079 init = init->semantic(sc, type); | |
1080 inuse--; | |
1081 } | |
1082 } | |
1083 | |
336 | 1084 const char *VarDeclaration::kind() |
159 | 1085 { |
1086 return "variable"; | |
1087 } | |
1088 | |
1089 Dsymbol *VarDeclaration::toAlias() | |
1090 { | |
1091 //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym); | |
1092 assert(this != aliassym); | |
1093 Dsymbol *s = aliassym ? aliassym->toAlias() : this; | |
1094 return s; | |
1095 } | |
1096 | |
1097 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
1098 { | |
1099 if (storage_class & STCconst) | |
1100 buf->writestring("const "); | |
1101 if (storage_class & STCstatic) | |
1102 buf->writestring("static "); | |
336 | 1103 if (storage_class & STCauto) |
1104 buf->writestring("auto "); | |
1105 #if DMDV2 | |
1106 if (storage_class & STCmanifest) | |
1107 buf->writestring("manifest "); | |
1108 if (storage_class & STCinvariant) | |
1109 buf->writestring("invariant "); | |
1110 if (storage_class & STCtls) | |
1111 buf->writestring("__thread "); | |
1112 #endif | |
1113 | |
159 | 1114 if (type) |
1115 type->toCBuffer(buf, ident, hgs); | |
1116 else | |
1117 buf->writestring(ident->toChars()); | |
1118 if (init) | |
1119 { buf->writestring(" = "); | |
1120 init->toCBuffer(buf, hgs); | |
1121 } | |
1122 buf->writeByte(';'); | |
1123 buf->writenl(); | |
1124 } | |
1125 | |
1126 int VarDeclaration::needThis() | |
1127 { | |
1128 //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class); | |
1129 return storage_class & STCfield; | |
1130 } | |
1131 | |
1132 int VarDeclaration::isImportedSymbol() | |
1133 { | |
1134 if (protection == PROTexport && !init && (isStatic() || isConst() || parent->isModule())) | |
1135 return TRUE; | |
1136 return FALSE; | |
1137 } | |
1138 | |
1139 void VarDeclaration::checkCtorConstInit() | |
1140 { | |
1141 if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield)) | |
1142 error("missing initializer in static constructor for const variable"); | |
1143 } | |
1144 | |
1145 /************************************ | |
336 | 1146 * Check to see if this variable is actually in an enclosing function |
1147 * rather than the current one. | |
159 | 1148 */ |
1149 | |
1150 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) | |
1151 { | |
336 | 1152 //printf("VarDeclaration::checkNestedReference() %s\n", toChars()); |
159 | 1153 if (parent && !isDataseg() && parent != sc->parent) |
1154 { | |
336 | 1155 // The function that this variable is in |
159 | 1156 FuncDeclaration *fdv = toParent()->isFuncDeclaration(); |
336 | 1157 // The current function |
159 | 1158 FuncDeclaration *fdthis = sc->parent->isFuncDeclaration(); |
1159 | |
1160 if (fdv && fdthis) | |
1161 { | |
1162 if (loc.filename) | |
1163 fdthis->getLevel(loc, fdv); | |
1164 nestedref = 1; | |
1165 fdv->nestedFrameRef = 1; | |
1166 fdv->nestedVars.insert(this); | |
1167 //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars()); | |
1168 } | |
1169 } | |
1170 } | |
1171 | |
1172 /******************************* | |
1173 * Does symbol go into data segment? | |
336 | 1174 * Includes extern variables. |
159 | 1175 */ |
1176 | |
1177 int VarDeclaration::isDataseg() | |
1178 { | |
1179 #if 0 | |
1180 printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars()); | |
1181 printf("%x, %p, %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance()); | |
1182 printf("parent = '%s'\n", parent->toChars()); | |
1183 #endif | |
1184 Dsymbol *parent = this->toParent(); | |
1185 if (!parent && !(storage_class & (STCstatic | STCconst))) | |
1186 { error("forward referenced"); | |
1187 type = Type::terror; | |
1188 return 0; | |
1189 } | |
1190 return (storage_class & (STCstatic | STCconst) || | |
1191 parent->isModule() || | |
1192 parent->isTemplateInstance()); | |
1193 } | |
1194 | |
1195 int VarDeclaration::hasPointers() | |
1196 { | |
1197 return (!isDataseg() && type->hasPointers()); | |
1198 } | |
1199 | |
1200 /****************************************** | |
1201 * If a variable has an auto destructor call, return call for it. | |
1202 * Otherwise, return NULL. | |
1203 */ | |
1204 | |
1205 Expression *VarDeclaration::callAutoDtor() | |
1206 { Expression *e = NULL; | |
1207 | |
1208 //printf("VarDeclaration::callAutoDtor() %s\n", toChars()); | |
1209 if (storage_class & (STCauto | STCscope) && !noauto) | |
1210 { | |
1211 for (ClassDeclaration *cd = type->isClassHandle(); | |
1212 cd; | |
1213 cd = cd->baseClass) | |
1214 { | |
1215 /* We can do better if there's a way with onstack | |
1216 * classes to determine if there's no way the monitor | |
1217 * could be set. | |
1218 */ | |
1219 //if (cd->isInterfaceDeclaration()) | |
1220 //error("interface %s cannot be scope", cd->toChars()); | |
1221 if (1 || onstack || cd->dtors.dim) // if any destructors | |
1222 { | |
1223 // delete this; | |
1224 Expression *ec; | |
1225 | |
1226 ec = new VarExp(loc, this); | |
1227 e = new DeleteExp(loc, ec); | |
1228 e->type = Type::tvoid; | |
1229 break; | |
1230 } | |
1231 } | |
1232 } | |
1233 return e; | |
1234 } | |
1235 | |
1236 | |
1237 /********************************* ClassInfoDeclaration ****************************/ | |
1238 | |
1239 ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd) | |
1240 : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL) | |
1241 { | |
1242 this->cd = cd; | |
1243 storage_class = STCstatic; | |
1244 } | |
1245 | |
1246 Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s) | |
1247 { | |
1248 assert(0); // should never be produced by syntax | |
1249 return NULL; | |
1250 } | |
1251 | |
1252 void ClassInfoDeclaration::semantic(Scope *sc) | |
1253 { | |
1254 } | |
1255 | |
1256 /********************************* ModuleInfoDeclaration ****************************/ | |
1257 | |
1258 ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod) | |
1259 : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL) | |
1260 { | |
1261 this->mod = mod; | |
1262 storage_class = STCstatic; | |
1263 } | |
1264 | |
1265 Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s) | |
1266 { | |
1267 assert(0); // should never be produced by syntax | |
1268 return NULL; | |
1269 } | |
1270 | |
1271 void ModuleInfoDeclaration::semantic(Scope *sc) | |
1272 { | |
1273 } | |
1274 | |
1275 /********************************* TypeInfoDeclaration ****************************/ | |
1276 | |
1277 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal) | |
1278 : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL) | |
1279 { | |
1280 this->tinfo = tinfo; | |
1281 storage_class = STCstatic; | |
1282 protection = PROTpublic; | |
1283 linkage = LINKc; | |
1284 } | |
1285 | |
1286 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s) | |
1287 { | |
1288 assert(0); // should never be produced by syntax | |
1289 return NULL; | |
1290 } | |
1291 | |
1292 void TypeInfoDeclaration::semantic(Scope *sc) | |
1293 { | |
1294 assert(linkage == LINKc); | |
1295 } | |
1296 | |
1297 /***************************** TypeInfoConstDeclaration **********************/ | |
1298 | |
336 | 1299 #if DMDV2 |
159 | 1300 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo) |
1301 : TypeInfoDeclaration(tinfo, 0) | |
1302 { | |
1303 } | |
1304 #endif | |
1305 | |
1306 /***************************** TypeInfoInvariantDeclaration **********************/ | |
1307 | |
336 | 1308 #if DMDV2 |
159 | 1309 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo) |
1310 : TypeInfoDeclaration(tinfo, 0) | |
1311 { | |
1312 } | |
1313 #endif | |
1314 | |
1315 /***************************** TypeInfoStructDeclaration **********************/ | |
1316 | |
1317 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) | |
1318 : TypeInfoDeclaration(tinfo, 0) | |
1319 { | |
1320 } | |
1321 | |
1322 /***************************** TypeInfoClassDeclaration ***********************/ | |
1323 | |
1324 TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo) | |
1325 : TypeInfoDeclaration(tinfo, 0) | |
1326 { | |
1327 } | |
1328 | |
1329 /***************************** TypeInfoInterfaceDeclaration *******************/ | |
1330 | |
1331 TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo) | |
1332 : TypeInfoDeclaration(tinfo, 0) | |
1333 { | |
1334 } | |
1335 | |
1336 /***************************** TypeInfoTypedefDeclaration *********************/ | |
1337 | |
1338 TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo) | |
1339 : TypeInfoDeclaration(tinfo, 0) | |
1340 { | |
1341 } | |
1342 | |
1343 /***************************** TypeInfoPointerDeclaration *********************/ | |
1344 | |
1345 TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo) | |
1346 : TypeInfoDeclaration(tinfo, 0) | |
1347 { | |
1348 } | |
1349 | |
1350 /***************************** TypeInfoArrayDeclaration ***********************/ | |
1351 | |
1352 TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo) | |
1353 : TypeInfoDeclaration(tinfo, 0) | |
1354 { | |
1355 } | |
1356 | |
1357 /***************************** TypeInfoStaticArrayDeclaration *****************/ | |
1358 | |
1359 TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo) | |
1360 : TypeInfoDeclaration(tinfo, 0) | |
1361 { | |
1362 } | |
1363 | |
1364 /***************************** TypeInfoAssociativeArrayDeclaration ************/ | |
1365 | |
1366 TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo) | |
1367 : TypeInfoDeclaration(tinfo, 0) | |
1368 { | |
1369 } | |
1370 | |
1371 /***************************** TypeInfoEnumDeclaration ***********************/ | |
1372 | |
1373 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo) | |
1374 : TypeInfoDeclaration(tinfo, 0) | |
1375 { | |
1376 } | |
1377 | |
1378 /***************************** TypeInfoFunctionDeclaration ********************/ | |
1379 | |
1380 TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo) | |
1381 : TypeInfoDeclaration(tinfo, 0) | |
1382 { | |
1383 } | |
1384 | |
1385 /***************************** TypeInfoDelegateDeclaration ********************/ | |
1386 | |
1387 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo) | |
1388 : TypeInfoDeclaration(tinfo, 0) | |
1389 { | |
1390 } | |
1391 | |
1392 /***************************** TypeInfoTupleDeclaration **********************/ | |
1393 | |
1394 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo) | |
1395 : TypeInfoDeclaration(tinfo, 0) | |
1396 { | |
1397 } | |
1398 | |
1399 /********************************* ThisDeclaration ****************************/ | |
1400 | |
1401 // For the "this" parameter to member functions | |
1402 | |
1403 ThisDeclaration::ThisDeclaration(Type *t) | |
1404 : VarDeclaration(0, t, Id::This, NULL) | |
1405 { | |
1406 noauto = 1; | |
1407 } | |
1408 | |
1409 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) | |
1410 { | |
1411 assert(0); // should never be produced by syntax | |
1412 return NULL; | |
1413 } | |
1414 | |
913
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1415 /********************** StaticStructInitDeclaration ***************************/ |
159 | 1416 |
913
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1417 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
|
1418 : 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
|
1419 { |
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1420 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
|
1421 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
|
1422 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
|
1423 } |
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
797
diff
changeset
|
1424 |