Mercurial > projects > ldc
comparison dmd2/mtype.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | 442ab244c455 |
children | a5526b7a5ae6 |
comparison
equal
deleted
inserted
replaced
1423:42bd767ec5a4 | 1452:638d16625da2 |
---|---|
1 | 1 |
2 // Compiler implementation of the D programming language | 2 // Compiler implementation of the D programming language |
3 // Copyright (c) 1999-2008 by Digital Mars | 3 // Copyright (c) 1999-2009 by Digital Mars |
4 // All Rights Reserved | 4 // All Rights Reserved |
5 // written by Walter Bright | 5 // written by Walter Bright |
6 // http://www.digitalmars.com | 6 // http://www.digitalmars.com |
7 // License for redistribution is by either the Artistic License | 7 // License for redistribution is by either the Artistic License |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | 8 // in artistic.txt, or the GNU General Public License in gnu.txt. |
9 // See the included readme.txt for details. | 9 // See the included readme.txt for details. |
10 | 10 |
11 #define __C99FEATURES__ 1 // Needed on Solaris for NaN and more | |
11 #define __USE_ISOC99 1 // so signbit() gets defined | 12 #define __USE_ISOC99 1 // so signbit() gets defined |
13 | |
14 #if (defined (__SVR4) && defined (__sun)) | |
15 #include <alloca.h> | |
16 #endif | |
12 | 17 |
13 #ifdef __DMC__ | 18 #ifdef __DMC__ |
14 #include <math.h> | 19 #include <math.h> |
15 #else | 20 #else |
16 #include <cmath> | 21 #include <cmath> |
17 #endif | 22 #endif |
18 | 23 |
19 #include <stdio.h> | 24 #include <stdio.h> |
20 #include <assert.h> | 25 #include <assert.h> |
21 #include <float.h> | 26 #include <float.h> |
22 | |
23 #ifdef __DMC__ | |
24 #include <fp.h> | |
25 #endif | |
26 | 27 |
27 #if _MSC_VER | 28 #if _MSC_VER |
28 #include <malloc.h> | 29 #include <malloc.h> |
29 #include <complex> | 30 #include <complex> |
30 #include <limits> | 31 #include <limits> |
31 #elif __DMC__ | 32 #elif __DMC__ |
32 #include <complex.h> | 33 #include <complex.h> |
33 #elif __MINGW32__ | 34 #elif __MINGW32__ |
34 #include <malloc.h> | 35 #include <malloc.h> |
35 #else | 36 #endif |
36 //#define signbit 56 | 37 |
37 #endif | 38 #include "rmem.h" |
38 | 39 #include "port.h" |
39 #if __GNUC__ | |
40 #if !(defined (__SVR4) && defined (__sun)) | |
41 #include <bits/nan.h> | |
42 #include <bits/mathdef.h> | |
43 #endif | |
44 #endif | |
45 static double zero = 0; | |
46 | |
47 #include "mem.h" | |
48 | 40 |
49 #include "dsymbol.h" | 41 #include "dsymbol.h" |
50 #include "mtype.h" | 42 #include "mtype.h" |
51 #include "scope.h" | 43 #include "scope.h" |
52 #include "init.h" | 44 #include "init.h" |
58 #include "enum.h" | 50 #include "enum.h" |
59 #include "import.h" | 51 #include "import.h" |
60 #include "aggregate.h" | 52 #include "aggregate.h" |
61 #include "hdrgen.h" | 53 #include "hdrgen.h" |
62 | 54 |
63 #include "gen/tollvm.h" | 55 #if IN_LLVM |
56 //#include "gen/tollvm.h" | |
57 Ir* Type::sir = NULL; | |
58 unsigned GetTypeAlignment(Ir* ir, Type* t); | |
59 #endif | |
64 | 60 |
65 FuncDeclaration *hasThis(Scope *sc); | 61 FuncDeclaration *hasThis(Scope *sc); |
66 | 62 |
67 | 63 |
68 #define LOGDOTEXP 0 // log ::dotExp() | 64 #define LOGDOTEXP 0 // log ::dotExp() |
74 /* These have default values for 32 bit code, they get | 70 /* These have default values for 32 bit code, they get |
75 * adjusted for 64 bit code. | 71 * adjusted for 64 bit code. |
76 */ | 72 */ |
77 | 73 |
78 int PTRSIZE = 4; | 74 int PTRSIZE = 4; |
79 #if IN_LLVM | 75 |
80 int REALSIZE = 8; | 76 /* REALSIZE = size a real consumes in memory |
81 int REALPAD = 0; | 77 * REALPAD = 'padding' added to the CPU real size to bring it up to REALSIZE |
82 #elif TARGET_LINUX | 78 * REALALIGNSIZE = alignment for reals |
79 */ | |
80 #if TARGET_OSX | |
81 int REALSIZE = 16; | |
82 int REALPAD = 6; | |
83 int REALALIGNSIZE = 16; | |
84 #elif TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS | |
83 int REALSIZE = 12; | 85 int REALSIZE = 12; |
84 int REALPAD = 2; | 86 int REALPAD = 2; |
87 int REALALIGNSIZE = 4; | |
85 #else | 88 #else |
86 int REALSIZE = 10; | 89 int REALSIZE = 10; |
87 int REALPAD = 0; | 90 int REALPAD = 0; |
88 #endif | 91 int REALALIGNSIZE = 2; |
92 #endif | |
93 | |
89 int Tsize_t = Tuns32; | 94 int Tsize_t = Tuns32; |
90 int Tptrdiff_t = Tint32; | 95 int Tptrdiff_t = Tint32; |
96 | |
97 #if _WIN32 && !defined __MINGW32__ | |
98 static double zero = 0; | |
99 double Port::nan = NAN; | |
100 double Port::infinity = 1/zero; | |
101 #endif | |
91 | 102 |
92 /***************************** Type *****************************/ | 103 /***************************** Type *****************************/ |
93 | 104 |
94 ClassDeclaration *Type::typeinfo; | 105 ClassDeclaration *Type::typeinfo; |
95 ClassDeclaration *Type::typeinfoclass; | 106 ClassDeclaration *Type::typeinfoclass; |
104 ClassDeclaration *Type::typeinfofunction; | 115 ClassDeclaration *Type::typeinfofunction; |
105 ClassDeclaration *Type::typeinfodelegate; | 116 ClassDeclaration *Type::typeinfodelegate; |
106 ClassDeclaration *Type::typeinfotypelist; | 117 ClassDeclaration *Type::typeinfotypelist; |
107 ClassDeclaration *Type::typeinfoconst; | 118 ClassDeclaration *Type::typeinfoconst; |
108 ClassDeclaration *Type::typeinfoinvariant; | 119 ClassDeclaration *Type::typeinfoinvariant; |
120 ClassDeclaration *Type::typeinfoshared; | |
109 | 121 |
110 Type *Type::tvoidptr; | 122 Type *Type::tvoidptr; |
111 Type *Type::basic[TMAX]; | 123 Type *Type::basic[TMAX]; |
112 unsigned char Type::mangleChar[TMAX]; | 124 unsigned char Type::mangleChar[TMAX]; |
113 unsigned char Type::sizeTy[TMAX]; | 125 unsigned char Type::sizeTy[TMAX]; |
114 StringTable Type::stringtable; | 126 StringTable Type::stringtable; |
115 | 127 |
116 | 128 #if IN_LLVM |
117 Type::Type(TY ty) | 129 StringTable Type::deco_stringtable; |
130 #endif | |
131 | |
132 | |
133 Type::Type(TY ty/*, Type *next*/) | |
118 { | 134 { |
119 this->ty = ty; | 135 this->ty = ty; |
120 this->mod = 0; | 136 this->mod = 0; |
137 //this->next = next; | |
121 this->deco = NULL; | 138 this->deco = NULL; |
122 #if DMDV2 | 139 #if DMDV2 |
123 this->cto = NULL; | 140 this->cto = NULL; |
124 this->ito = NULL; | 141 this->ito = NULL; |
142 this->sto = NULL; | |
143 this->scto = NULL; | |
125 #endif | 144 #endif |
126 this->pto = NULL; | 145 this->pto = NULL; |
127 this->rto = NULL; | 146 this->rto = NULL; |
128 this->arrayof = NULL; | 147 this->arrayof = NULL; |
129 this->vtinfo = NULL; | 148 this->vtinfo = NULL; |
149 #if IN_DMD | |
130 this->ctype = NULL; | 150 this->ctype = NULL; |
151 #endif | |
152 | |
153 #if IN_LLVM | |
154 this->irtype = NULL; | |
155 #endif | |
131 } | 156 } |
132 | 157 |
133 Type *Type::syntaxCopy() | 158 Type *Type::syntaxCopy() |
134 { | 159 { |
135 print(); | 160 print(); |
157 char Type::needThisPrefix() | 182 char Type::needThisPrefix() |
158 { | 183 { |
159 return 'M'; // name mangling prefix for functions needing 'this' | 184 return 'M'; // name mangling prefix for functions needing 'this' |
160 } | 185 } |
161 | 186 |
187 #if IN_LLVM | |
188 void Type::init(Ir* _sir) | |
189 #else | |
162 void Type::init() | 190 void Type::init() |
191 #endif | |
163 { int i; | 192 { int i; |
164 int j; | 193 int j; |
165 | 194 |
166 Lexer::initKeywords(); | 195 Lexer::initKeywords(); |
167 | 196 |
254 } | 283 } |
255 basic[Terror] = basic[Tint32]; | 284 basic[Terror] = basic[Tint32]; |
256 | 285 |
257 tvoidptr = tvoid->pointerTo(); | 286 tvoidptr = tvoid->pointerTo(); |
258 | 287 |
288 // LDC | |
289 sir = _sir; | |
290 | |
259 // set size_t / ptrdiff_t types and pointer size | 291 // set size_t / ptrdiff_t types and pointer size |
260 if (global.params.is64bit) | 292 if (global.params.is64bit) |
261 { | 293 { |
262 Tsize_t = Tuns64; | 294 Tsize_t = Tuns64; |
263 Tptrdiff_t = Tint64; | 295 Tptrdiff_t = Tint64; |
264 PTRSIZE = 8; | 296 PTRSIZE = 8; |
265 } | 297 } |
266 else | 298 else |
267 { | 299 { |
300 PTRSIZE = 4; | |
301 #if TARGET_OSX | |
302 REALSIZE = 16; | |
303 REALPAD = 6; | |
304 #elif TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS | |
305 REALSIZE = 12; | |
306 REALPAD = 2; | |
307 #else | |
308 REALSIZE = 10; | |
309 REALPAD = 0; | |
310 #endif | |
268 Tsize_t = Tuns32; | 311 Tsize_t = Tuns32; |
269 Tptrdiff_t = Tint32; | 312 Tptrdiff_t = Tint32; |
270 PTRSIZE = 4; | 313 PTRSIZE = 4; |
271 } | 314 } |
272 | 315 |
305 } | 348 } |
306 | 349 |
307 Type *Type::semantic(Loc loc, Scope *sc) | 350 Type *Type::semantic(Loc loc, Scope *sc) |
308 { | 351 { |
309 return merge(); | 352 return merge(); |
353 } | |
354 | |
355 Type *Type::trySemantic(Loc loc, Scope *sc) | |
356 { | |
357 unsigned errors = global.errors; | |
358 global.gag++; // suppress printing of error messages | |
359 Type *t = semantic(loc, sc); | |
360 global.gag--; | |
361 if (errors != global.errors) // if any errors happened | |
362 { | |
363 global.errors = errors; | |
364 t = NULL; | |
365 } | |
366 return t; | |
310 } | 367 } |
311 | 368 |
312 /******************************* | 369 /******************************* |
313 * Determine if converting 'this' to 'to' is an identity operation, | 370 * Determine if converting 'this' to 'to' is an identity operation, |
314 * a conversion to const operation, or the types aren't the same. | 371 * a conversion to const operation, or the types aren't the same. |
325 if (ty == to->ty && to->mod == MODconst) | 382 if (ty == to->ty && to->mod == MODconst) |
326 return MATCHconst; | 383 return MATCHconst; |
327 return MATCHnomatch; | 384 return MATCHnomatch; |
328 } | 385 } |
329 | 386 |
387 /******************************** | |
388 * Convert to 'const'. | |
389 */ | |
390 | |
330 Type *Type::constOf() | 391 Type *Type::constOf() |
331 { | 392 { |
393 #if 0 | |
332 //printf("Type::constOf() %p %s\n", this, toChars()); | 394 //printf("Type::constOf() %p %s\n", this, toChars()); |
333 if (isConst()) | 395 if (isConst()) |
334 return this; | 396 return this; |
335 if (cto) | 397 if (cto) |
336 return cto; | 398 return cto; |
340 if (ito) | 402 if (ito) |
341 ito->cto = t; | 403 ito->cto = t; |
342 //if (t->nextOf()) assert(t->nextOf()->isConst()); | 404 //if (t->nextOf()) assert(t->nextOf()->isConst()); |
343 //printf("-Type::constOf() %p %s\n", t, toChars()); | 405 //printf("-Type::constOf() %p %s\n", t, toChars()); |
344 return t; | 406 return t; |
345 } | 407 #else |
408 //printf("Type::constOf() %p %s\n", this, toChars()); | |
409 if (mod == MODconst) | |
410 return this; | |
411 if (cto) | |
412 { assert(cto->mod == MODconst); | |
413 return cto; | |
414 } | |
415 Type *t = makeConst(); | |
416 t = t->merge(); | |
417 t->fixTo(this); | |
418 //printf("-Type::constOf() %p %s\n", t, toChars()); | |
419 return t; | |
420 #endif | |
421 } | |
422 | |
423 /******************************** | |
424 * Convert to 'immutable'. | |
425 */ | |
346 | 426 |
347 Type *Type::invariantOf() | 427 Type *Type::invariantOf() |
348 { | 428 { |
429 #if 0 | |
349 //printf("Type::invariantOf() %p %s\n", this, toChars()); | 430 //printf("Type::invariantOf() %p %s\n", this, toChars()); |
350 if (isInvariant()) | 431 if (isInvariant()) |
351 { | 432 { |
352 return this; | 433 return this; |
353 } | 434 } |
368 assert(0); | 449 assert(0); |
369 } | 450 } |
370 #endif | 451 #endif |
371 //printf("\t%p\n", t); | 452 //printf("\t%p\n", t); |
372 return t; | 453 return t; |
373 } | 454 #else |
455 //printf("Type::invariantOf() %p %s\n", this, toChars()); | |
456 if (isInvariant()) | |
457 { | |
458 return this; | |
459 } | |
460 if (ito) | |
461 { | |
462 assert(ito->isInvariant()); | |
463 return ito; | |
464 } | |
465 Type *t = makeInvariant(); | |
466 t = t->merge(); | |
467 t->fixTo(this); | |
468 //printf("\t%p\n", t); | |
469 return t; | |
470 #endif | |
471 } | |
472 | |
473 /******************************** | |
474 * Make type mutable. | |
475 */ | |
374 | 476 |
375 Type *Type::mutableOf() | 477 Type *Type::mutableOf() |
376 { | 478 { |
479 #if 0 | |
377 //printf("Type::mutableOf() %p, %s\n", this, toChars()); | 480 //printf("Type::mutableOf() %p, %s\n", this, toChars()); |
378 Type *t = this; | 481 Type *t = this; |
379 if (isConst()) | 482 if (isConst()) |
380 { t = cto; | 483 { t = cto; |
381 assert(!t || t->isMutable()); | 484 assert(!t || t->isMutable()); |
394 t->arrayof = NULL; | 497 t->arrayof = NULL; |
395 t->pto = NULL; | 498 t->pto = NULL; |
396 t->rto = NULL; | 499 t->rto = NULL; |
397 t->cto = NULL; | 500 t->cto = NULL; |
398 t->ito = NULL; | 501 t->ito = NULL; |
502 t->sto = NULL; | |
503 t->scto = NULL; | |
399 t->vtinfo = NULL; | 504 t->vtinfo = NULL; |
400 if (ty == Tsarray) | 505 if (ty == Tsarray) |
401 { TypeSArray *ta = (TypeSArray *)t; | 506 { TypeSArray *ta = (TypeSArray *)t; |
402 //ta->next = ta->next->mutableOf(); | 507 //ta->next = ta->next->mutableOf(); |
403 } | 508 } |
414 if (cto) | 519 if (cto) |
415 cto->ito = this; | 520 cto->ito = this; |
416 } | 521 } |
417 } | 522 } |
418 return t; | 523 return t; |
524 #else | |
525 //printf("Type::mutableOf() %p, %s\n", this, toChars()); | |
526 Type *t = this; | |
527 if (isConst()) | |
528 { if (isShared()) | |
529 t = sto; // shared const => shared | |
530 else | |
531 t = cto; | |
532 assert(!t || t->isMutable()); | |
533 } | |
534 else if (isInvariant()) | |
535 { t = ito; | |
536 assert(!t || (t->isMutable() && !t->isShared())); | |
537 } | |
538 if (!t) | |
539 { | |
540 unsigned sz = sizeTy[ty]; | |
541 t = (Type *)mem.malloc(sz); | |
542 memcpy(t, this, sz); | |
543 t->mod = 0; | |
544 t->deco = NULL; | |
545 t->arrayof = NULL; | |
546 t->pto = NULL; | |
547 t->rto = NULL; | |
548 t->cto = NULL; | |
549 t->ito = NULL; | |
550 t->sto = NULL; | |
551 t->scto = NULL; | |
552 t->vtinfo = NULL; | |
553 t = t->merge(); | |
554 | |
555 t->fixTo(this); | |
556 | |
557 switch (mod) | |
558 { | |
559 case MODconst: | |
560 t->cto = this; | |
561 break; | |
562 | |
563 case MODinvariant: | |
564 t->ito = this; | |
565 break; | |
566 | |
567 case MODshared: | |
568 t->sto = this; | |
569 break; | |
570 | |
571 case MODshared | MODconst: | |
572 t->scto = this; | |
573 break; | |
574 | |
575 default: | |
576 assert(0); | |
577 } | |
578 } | |
579 return t; | |
580 #endif | |
581 } | |
582 | |
583 Type *Type::sharedOf() | |
584 { | |
585 //printf("Type::sharedOf() %p, %s\n", this, toChars()); | |
586 if (mod == MODshared) | |
587 { | |
588 return this; | |
589 } | |
590 if (sto) | |
591 { | |
592 assert(sto->isShared()); | |
593 return sto; | |
594 } | |
595 Type *t = makeShared(); | |
596 t = t->merge(); | |
597 t->fixTo(this); | |
598 //printf("\t%p\n", t); | |
599 return t; | |
600 } | |
601 | |
602 Type *Type::sharedConstOf() | |
603 { | |
604 //printf("Type::sharedConstOf() %p, %s\n", this, toChars()); | |
605 if (mod == (MODshared | MODconst)) | |
606 { | |
607 return this; | |
608 } | |
609 if (scto) | |
610 { | |
611 assert(scto->mod == (MODshared | MODconst)); | |
612 return scto; | |
613 } | |
614 Type *t = makeSharedConst(); | |
615 t = t->merge(); | |
616 t->fixTo(this); | |
617 //printf("\t%p\n", t); | |
618 return t; | |
619 } | |
620 | |
621 | |
622 /********************************** | |
623 * For our new type 'this', which is type-constructed from t, | |
624 * fill in the cto, ito, sto, scto shortcuts. | |
625 */ | |
626 | |
627 void Type::fixTo(Type *t) | |
628 { | |
629 ito = t->ito; | |
630 #if 0 | |
631 /* Cannot do these because these are not fully transitive: | |
632 * there can be a shared ptr to immutable, for example. | |
633 * Immutable subtypes are always immutable, though. | |
634 */ | |
635 cto = t->cto; | |
636 sto = t->sto; | |
637 scto = t->scto; | |
638 #endif | |
639 | |
640 assert(mod != t->mod); | |
641 #define X(m, n) (((m) << 3) | (n)) | |
642 switch (X(mod, t->mod)) | |
643 { | |
644 case X(0, MODconst): | |
645 cto = t; | |
646 break; | |
647 | |
648 case X(0, MODinvariant): | |
649 ito = t; | |
650 break; | |
651 | |
652 case X(0, MODshared): | |
653 sto = t; | |
654 break; | |
655 | |
656 case X(0, MODshared | MODconst): | |
657 scto = t; | |
658 break; | |
659 | |
660 | |
661 case X(MODconst, 0): | |
662 cto = NULL; | |
663 goto L2; | |
664 | |
665 case X(MODconst, MODinvariant): | |
666 ito = t; | |
667 goto L2; | |
668 | |
669 case X(MODconst, MODshared): | |
670 sto = t; | |
671 goto L2; | |
672 | |
673 case X(MODconst, MODshared | MODconst): | |
674 scto = t; | |
675 L2: | |
676 t->cto = this; | |
677 break; | |
678 | |
679 | |
680 case X(MODinvariant, 0): | |
681 ito = NULL; | |
682 goto L3; | |
683 | |
684 case X(MODinvariant, MODconst): | |
685 cto = t; | |
686 goto L3; | |
687 | |
688 case X(MODinvariant, MODshared): | |
689 sto = t; | |
690 goto L3; | |
691 | |
692 case X(MODinvariant, MODshared | MODconst): | |
693 scto = t; | |
694 L3: | |
695 t->ito = this; | |
696 if (t->cto) t->cto->ito = this; | |
697 if (t->sto) t->sto->ito = this; | |
698 if (t->scto) t->scto->ito = this; | |
699 break; | |
700 | |
701 | |
702 case X(MODshared, 0): | |
703 sto = NULL; | |
704 goto L4; | |
705 | |
706 case X(MODshared, MODconst): | |
707 cto = t; | |
708 goto L4; | |
709 | |
710 case X(MODshared, MODinvariant): | |
711 ito = t; | |
712 goto L4; | |
713 | |
714 case X(MODshared, MODshared | MODconst): | |
715 scto = t; | |
716 L4: | |
717 t->sto = this; | |
718 break; | |
719 | |
720 | |
721 case X(MODshared | MODconst, 0): | |
722 scto = NULL; | |
723 break; | |
724 | |
725 case X(MODshared | MODconst, MODconst): | |
726 cto = t; | |
727 break; | |
728 | |
729 case X(MODshared | MODconst, MODinvariant): | |
730 ito = t; | |
731 break; | |
732 | |
733 case X(MODshared | MODconst, MODshared): | |
734 sto = t; | |
735 L5: | |
736 t->scto = this; | |
737 break; | |
738 | |
739 default: | |
740 assert(0); | |
741 } | |
742 #undef X | |
743 | |
744 check(); | |
745 t->check(); | |
746 //printf("fixTo: %s, %s\n", toChars(), t->toChars()); | |
747 } | |
748 | |
749 /*************************** | |
750 * Look for bugs in constructing types. | |
751 */ | |
752 | |
753 void Type::check() | |
754 { | |
755 switch (mod) | |
756 { | |
757 case 0: | |
758 if (cto) assert(cto->mod == MODconst); | |
759 if (ito) assert(ito->mod == MODinvariant); | |
760 if (sto) assert(sto->mod == MODshared); | |
761 if (scto) assert(scto->mod == (MODshared | MODconst)); | |
762 break; | |
763 | |
764 case MODconst: | |
765 if (cto) assert(cto->mod == 0); | |
766 if (ito) assert(ito->mod == MODinvariant); | |
767 if (sto) assert(sto->mod == MODshared); | |
768 if (scto) assert(scto->mod == (MODshared | MODconst)); | |
769 break; | |
770 | |
771 case MODinvariant: | |
772 if (cto) assert(cto->mod == MODconst); | |
773 if (ito) assert(ito->mod == 0); | |
774 if (sto) assert(sto->mod == MODshared); | |
775 if (scto) assert(scto->mod == (MODshared | MODconst)); | |
776 break; | |
777 | |
778 case MODshared: | |
779 if (cto) assert(cto->mod == MODconst); | |
780 if (ito) assert(ito->mod == MODinvariant); | |
781 if (sto) assert(sto->mod == 0); | |
782 if (scto) assert(scto->mod == (MODshared | MODconst)); | |
783 break; | |
784 | |
785 case MODshared | MODconst: | |
786 if (cto) assert(cto->mod == MODconst); | |
787 if (ito) assert(ito->mod == MODinvariant); | |
788 if (sto) assert(sto->mod == MODshared); | |
789 if (scto) assert(scto->mod == 0); | |
790 break; | |
791 | |
792 default: | |
793 assert(0); | |
794 } | |
795 | |
796 Type *tn = nextOf(); | |
797 if (tn && ty != Tfunction && ty != Tdelegate) | |
798 { // Verify transitivity | |
799 switch (mod) | |
800 { | |
801 case 0: | |
802 break; | |
803 | |
804 case MODconst: | |
805 assert(tn->mod & MODinvariant || tn->mod & MODconst); | |
806 break; | |
807 | |
808 case MODinvariant: | |
809 assert(tn->mod == MODinvariant); | |
810 break; | |
811 | |
812 case MODshared: | |
813 assert(tn->mod & MODinvariant || tn->mod & MODshared); | |
814 break; | |
815 | |
816 case MODshared | MODconst: | |
817 assert(tn->mod & MODinvariant || tn->mod & (MODshared | MODconst)); | |
818 break; | |
819 | |
820 default: | |
821 assert(0); | |
822 } | |
823 tn->check(); | |
824 } | |
419 } | 825 } |
420 | 826 |
421 Type *Type::makeConst() | 827 Type *Type::makeConst() |
422 { | 828 { |
423 //printf("Type::makeConst() %p, %s\n", this, toChars()); | 829 //printf("Type::makeConst() %p, %s\n", this, toChars()); |
431 t->arrayof = NULL; | 837 t->arrayof = NULL; |
432 t->pto = NULL; | 838 t->pto = NULL; |
433 t->rto = NULL; | 839 t->rto = NULL; |
434 t->cto = NULL; | 840 t->cto = NULL; |
435 t->ito = NULL; | 841 t->ito = NULL; |
842 t->sto = NULL; | |
843 t->scto = NULL; | |
436 t->vtinfo = NULL; | 844 t->vtinfo = NULL; |
437 //printf("-Type::makeConst() %p, %s\n", t, toChars()); | 845 //printf("-Type::makeConst() %p, %s\n", t, toChars()); |
438 return t; | 846 return t; |
439 } | 847 } |
440 | 848 |
450 t->arrayof = NULL; | 858 t->arrayof = NULL; |
451 t->pto = NULL; | 859 t->pto = NULL; |
452 t->rto = NULL; | 860 t->rto = NULL; |
453 t->cto = NULL; | 861 t->cto = NULL; |
454 t->ito = NULL; | 862 t->ito = NULL; |
863 t->sto = NULL; | |
864 t->scto = NULL; | |
455 t->vtinfo = NULL; | 865 t->vtinfo = NULL; |
456 return t; | 866 return t; |
867 } | |
868 | |
869 Type *Type::makeShared() | |
870 { | |
871 if (sto) | |
872 return sto; | |
873 unsigned sz = sizeTy[ty]; | |
874 Type *t = (Type *)mem.malloc(sz); | |
875 memcpy(t, this, sz); | |
876 t->mod = MODshared; | |
877 t->deco = NULL; | |
878 t->arrayof = NULL; | |
879 t->pto = NULL; | |
880 t->rto = NULL; | |
881 t->cto = NULL; | |
882 t->ito = NULL; | |
883 t->sto = NULL; | |
884 t->scto = NULL; | |
885 t->vtinfo = NULL; | |
886 return t; | |
887 } | |
888 | |
889 Type *Type::makeSharedConst() | |
890 { | |
891 if (scto) | |
892 return scto; | |
893 unsigned sz = sizeTy[ty]; | |
894 Type *t = (Type *)mem.malloc(sz); | |
895 memcpy(t, this, sz); | |
896 t->mod = MODshared | MODconst; | |
897 t->deco = NULL; | |
898 t->arrayof = NULL; | |
899 t->pto = NULL; | |
900 t->rto = NULL; | |
901 t->cto = NULL; | |
902 t->ito = NULL; | |
903 t->sto = NULL; | |
904 t->scto = NULL; | |
905 t->vtinfo = NULL; | |
906 return t; | |
907 } | |
908 | |
909 /************************************ | |
910 * Apply MODxxxx bits to existing type. | |
911 */ | |
912 | |
913 Type *Type::castMod(unsigned mod) | |
914 { Type *t; | |
915 | |
916 switch (mod) | |
917 { | |
918 case 0: | |
919 t = mutableOf(); | |
920 break; | |
921 | |
922 case MODconst: | |
923 t = constOf(); | |
924 break; | |
925 | |
926 case MODinvariant: | |
927 t = invariantOf(); | |
928 break; | |
929 | |
930 case MODshared: | |
931 t = sharedOf(); | |
932 break; | |
933 | |
934 case MODshared | MODconst: | |
935 t = sharedConstOf(); | |
936 break; | |
937 | |
938 default: | |
939 assert(0); | |
940 } | |
941 return t; | |
942 } | |
943 | |
944 /************************************ | |
945 * Add MODxxxx bits to existing type. | |
946 * We're adding, not replacing, so adding const to | |
947 * a shared type => "shared const" | |
948 */ | |
949 | |
950 Type *Type::addMod(unsigned mod) | |
951 { Type *t = this; | |
952 | |
953 /* Add anything to immutable, and it remains immutable | |
954 */ | |
955 if (!t->isInvariant()) | |
956 { | |
957 switch (mod) | |
958 { | |
959 case 0: | |
960 break; | |
961 | |
962 case MODconst: | |
963 if (isShared()) | |
964 t = sharedConstOf(); | |
965 else | |
966 t = constOf(); | |
967 break; | |
968 | |
969 case MODinvariant: | |
970 t = invariantOf(); | |
971 break; | |
972 | |
973 case MODshared: | |
974 if (isConst()) | |
975 t = sharedConstOf(); | |
976 else | |
977 t = sharedOf(); | |
978 break; | |
979 | |
980 case MODshared | MODconst: | |
981 t = sharedConstOf(); | |
982 break; | |
983 | |
984 default: | |
985 assert(0); | |
986 } | |
987 } | |
988 return t; | |
989 } | |
990 | |
991 /************************************ | |
992 * Add storage class modifiers to type. | |
993 */ | |
994 | |
995 Type *Type::addStorageClass(unsigned stc) | |
996 { | |
997 /* Just translate to MOD bits and let addMod() do the work | |
998 */ | |
999 unsigned mod = 0; | |
1000 | |
1001 if (stc & STCimmutable) | |
1002 mod = MODinvariant; | |
1003 else | |
1004 { if (stc & (STCconst | STCin)) | |
1005 mod = MODconst; | |
1006 if (stc & STCshared) | |
1007 mod |= MODshared; | |
1008 } | |
1009 return addMod(mod); | |
457 } | 1010 } |
458 | 1011 |
459 /************************** | 1012 /************************** |
460 * Return type with the top level of it being mutable. | 1013 * Return type with the top level of it being mutable. |
461 */ | 1014 */ |
518 * Name mangling. | 1071 * Name mangling. |
519 * Input: | 1072 * Input: |
520 * flag 0x100 do not do const/invariant | 1073 * flag 0x100 do not do const/invariant |
521 */ | 1074 */ |
522 | 1075 |
523 void Type::toDecoBuffer(OutBuffer *buf, int flag) | 1076 void Type::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) // Possible conflict from merge |
524 { | 1077 { |
525 if (flag != mod && flag != 0x100) | 1078 if (flag != mod && flag != 0x100) |
526 { | 1079 { |
527 if (mod & MODshared) | 1080 if (mod & MODshared) |
528 buf->writeByte('O'); | 1081 buf->writeByte('O'); |
572 void Type::toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod) | 1125 void Type::toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod) |
573 { | 1126 { |
574 if (mod != this->mod) | 1127 if (mod != this->mod) |
575 { const char *p; | 1128 { const char *p; |
576 | 1129 |
577 if (mod & MODshared) | 1130 if (this->mod & MODshared) |
578 buf->writestring("shared("); | 1131 buf->writestring("shared("); |
579 switch (this->mod & (MODconst | MODinvariant)) | 1132 switch (this->mod & (MODconst | MODinvariant)) |
580 { | 1133 { |
581 case 0: | 1134 case 0: |
582 toCBuffer2(buf, hgs, this->mod); | 1135 toCBuffer2(buf, hgs, this->mod); |
583 break; | 1136 break; |
584 case MODconst: | 1137 case MODconst: |
585 p = "const("; | 1138 p = "const("; |
586 goto L1; | 1139 goto L1; |
587 case MODinvariant: | 1140 case MODinvariant: |
588 p = "invariant("; | 1141 p = "immutable("; |
589 L1: buf->writestring(p); | 1142 L1: buf->writestring(p); |
590 toCBuffer2(buf, hgs, this->mod); | 1143 toCBuffer2(buf, hgs, this->mod); |
591 buf->writeByte(')'); | 1144 buf->writeByte(')'); |
592 break; | 1145 break; |
593 default: | 1146 default: |
594 assert(0); | 1147 assert(0); |
595 } | 1148 } |
596 if (mod & MODshared) | 1149 if (this->mod & MODshared) |
597 buf->writeByte(')'); | 1150 buf->writeByte(')'); |
598 } | 1151 } |
599 } | 1152 } |
600 | 1153 |
601 /************************************ | 1154 /************************************ |
612 OutBuffer buf; | 1165 OutBuffer buf; |
613 StringValue *sv; | 1166 StringValue *sv; |
614 | 1167 |
615 //if (next) | 1168 //if (next) |
616 //next = next->merge(); | 1169 //next = next->merge(); |
617 toDecoBuffer(&buf); | 1170 toDecoBuffer(&buf, false); |
618 sv = stringtable.update((char *)buf.data, buf.offset); | 1171 sv = stringtable.update((char *)buf.data, buf.offset); |
619 if (sv->ptrvalue) | 1172 if (sv->ptrvalue) |
620 { t = (Type *) sv->ptrvalue; | 1173 { t = (Type *) sv->ptrvalue; |
621 assert(t->deco); | 1174 assert(t->deco); |
622 //printf("old value, deco = '%s' %p\n", t->deco, t->deco); | 1175 //printf("old value, deco = '%s' %p\n", t->deco, t->deco); |
623 } | 1176 } |
624 else | 1177 else |
625 { | 1178 { |
626 sv->ptrvalue = this; | 1179 sv->ptrvalue = this; |
627 deco = sv->lstring.string; | 1180 |
1181 // we still need deco strings to be unique | |
1182 // or Type::equals fails, which breaks a bunch of stuff, | |
1183 // like covariant member function overloads. | |
1184 OutBuffer mangle; | |
1185 toDecoBuffer(&mangle, true); | |
1186 StringValue* sv2 = deco_stringtable.update((char *)mangle.data, mangle.offset); | |
1187 if (sv2->ptrvalue) | |
1188 { Type* t2 = (Type *) sv2->ptrvalue; | |
1189 assert(t2->deco); | |
1190 deco = t2->deco; | |
1191 } | |
1192 else | |
1193 { | |
1194 sv2->ptrvalue = this; | |
1195 deco = (char *)sv2->lstring.string; | |
1196 } | |
628 //printf("new value, deco = '%s' %p\n", t->deco, t->deco); | 1197 //printf("new value, deco = '%s' %p\n", t->deco, t->deco); |
629 } | 1198 } |
630 } | 1199 } |
1200 return t; | |
1201 } | |
1202 | |
1203 /************************************* | |
1204 * This version does a merge even if the deco is already computed. | |
1205 * Necessary for types that have a deco, but are not merged. | |
1206 */ | |
1207 Type *Type::merge2() | |
1208 { | |
1209 //printf("merge2(%s)\n", toChars()); | |
1210 Type *t = this; | |
1211 assert(t); | |
1212 if (!t->deco) | |
1213 return t->merge(); | |
1214 | |
1215 StringValue *sv = deco_stringtable.lookup((char *)t->deco, strlen(t->deco)); | |
1216 if (sv && sv->ptrvalue) | |
1217 { t = (Type *) sv->ptrvalue; | |
1218 assert(t->deco); | |
1219 } | |
1220 else | |
1221 assert(0); | |
631 return t; | 1222 return t; |
632 } | 1223 } |
633 | 1224 |
634 int Type::isintegral() | 1225 int Type::isintegral() |
635 { | 1226 { |
717 printf("Type::defaultInit() '%s'\n", toChars()); | 1308 printf("Type::defaultInit() '%s'\n", toChars()); |
718 #endif | 1309 #endif |
719 return NULL; | 1310 return NULL; |
720 } | 1311 } |
721 | 1312 |
722 int Type::isZeroInit() | 1313 int Type::isZeroInit(Loc loc) |
723 { | 1314 { |
724 return 0; // assume not | 1315 return 0; // assume not |
725 } | 1316 } |
726 | 1317 |
727 int Type::isBaseOf(Type *t, int *poffset) | 1318 int Type::isBaseOf(Type *t, int *poffset) |
757 e = new IntegerExp(loc, size(loc), Type::tsize_t); | 1348 e = new IntegerExp(loc, size(loc), Type::tsize_t); |
758 } | 1349 } |
759 else if (ident == Id::size) | 1350 else if (ident == Id::size) |
760 { | 1351 { |
761 error(loc, ".size property should be replaced with .sizeof"); | 1352 error(loc, ".size property should be replaced with .sizeof"); |
762 e = new IntegerExp(loc, size(loc), Type::tsize_t); | 1353 e = new ErrorExp(); |
763 } | 1354 } |
764 else if (ident == Id::alignof) | 1355 else if (ident == Id::alignof) |
765 { | 1356 { |
766 e = new IntegerExp(loc, alignsize(), Type::tsize_t); | 1357 e = new IntegerExp(loc, alignsize(), Type::tsize_t); |
767 } | 1358 } |
776 if (ty == Tvoid) | 1367 if (ty == Tvoid) |
777 error(loc, "void does not have an initializer"); | 1368 error(loc, "void does not have an initializer"); |
778 e = defaultInit(loc); | 1369 e = defaultInit(loc); |
779 } | 1370 } |
780 else if (ident == Id::mangleof) | 1371 else if (ident == Id::mangleof) |
781 { | 1372 { const char *s; |
782 assert(deco); | 1373 if (!deco) |
783 e = new StringExp(loc, deco, strlen(deco), 'c'); | 1374 { s = toChars(); |
1375 error(loc, "forward reference of type %s.mangleof", s); | |
1376 } | |
1377 else | |
1378 s = deco; | |
1379 e = new StringExp(loc, (char *)s, strlen(s), 'c'); | |
784 Scope sc; | 1380 Scope sc; |
785 e = e->semantic(&sc); | 1381 e = e->semantic(&sc); |
786 } | 1382 } |
787 else if (ident == Id::stringof) | 1383 else if (ident == Id::stringof) |
788 { char *s = toChars(); | 1384 { char *s = toChars(); |
791 e = e->semantic(&sc); | 1387 e = e->semantic(&sc); |
792 } | 1388 } |
793 else | 1389 else |
794 { | 1390 { |
795 error(loc, "no property '%s' for type '%s'", ident->toChars(), toChars()); | 1391 error(loc, "no property '%s' for type '%s'", ident->toChars(), toChars()); |
796 e = new IntegerExp(loc, 1, Type::tint32); | 1392 e = new ErrorExp(); |
797 } | 1393 } |
798 return e; | 1394 return e; |
799 } | 1395 } |
800 | 1396 |
801 Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident) | 1397 Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident) |
894 va_start(ap, format); | 1490 va_start(ap, format); |
895 ::verror(loc, format, ap); | 1491 ::verror(loc, format, ap); |
896 va_end( ap ); | 1492 va_end( ap ); |
897 } | 1493 } |
898 | 1494 |
1495 void Type::warning(Loc loc, const char *format, ...) | |
1496 { | |
1497 if (global.params.warnings && !global.gag) | |
1498 { | |
1499 va_list ap; | |
1500 va_start(ap, format); | |
1501 ::vwarning(loc, format, ap); | |
1502 va_end( ap ); | |
1503 } | |
1504 } | |
1505 | |
899 Identifier *Type::getTypeInfoIdent(int internal) | 1506 Identifier *Type::getTypeInfoIdent(int internal) |
900 { | 1507 { |
901 // _init_10TypeInfo_%s | 1508 // _init_10TypeInfo_%s |
902 OutBuffer buf; | 1509 OutBuffer buf; |
903 Identifier *id; | 1510 Identifier *id; |
908 { buf.writeByte(mangleChar[ty]); | 1515 { buf.writeByte(mangleChar[ty]); |
909 if (ty == Tarray) | 1516 if (ty == Tarray) |
910 buf.writeByte(mangleChar[((TypeArray *)this)->next->ty]); | 1517 buf.writeByte(mangleChar[((TypeArray *)this)->next->ty]); |
911 } | 1518 } |
912 else | 1519 else |
913 toDecoBuffer(&buf); | 1520 toDecoBuffer(&buf, true); |
914 len = buf.offset; | 1521 len = buf.offset; |
915 name = (char *)alloca(19 + sizeof(len) * 3 + len + 1); | 1522 name = (char *)alloca(19 + sizeof(len) * 3 + len + 1); |
916 buf.writeByte(0); | 1523 buf.writeByte(0); |
1524 #if TARGET_OSX | |
1525 // The LINKc will prepend the _ | |
1526 sprintf(name, "D%dTypeInfo_%s6__initZ", 9 + len, buf.data); | |
1527 #else | |
917 sprintf(name, "_D%dTypeInfo_%s6__initZ", 9 + len, buf.data); | 1528 sprintf(name, "_D%dTypeInfo_%s6__initZ", 9 + len, buf.data); |
1529 #endif | |
918 // LDC | 1530 // LDC |
919 // it is not clear where the underscore that's stripped here is added back in | 1531 // it is not clear where the underscore that's stripped here is added back in |
920 // if (global.params.isWindows) | 1532 // if (global.params.isWindows) |
921 // name++; // C mangling will add it back in | 1533 // name++; // C mangling will add it back in |
922 //printf("name = %s\n", name); | 1534 //printf("name = %s\n", name); |
985 : Type(ty) | 1597 : Type(ty) |
986 { | 1598 { |
987 this->next = next; | 1599 this->next = next; |
988 } | 1600 } |
989 | 1601 |
990 void TypeNext::toDecoBuffer(OutBuffer *buf, int flag) | 1602 void TypeNext::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) |
991 { | 1603 { |
992 Type::toDecoBuffer(buf, flag); | 1604 Type::toDecoBuffer(buf, flag, mangle); |
993 assert(next != this); | 1605 assert(next != this); |
994 //printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this->ty, next, next->ty); | 1606 //printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this->ty, next, next->ty); |
995 next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); | 1607 next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod, mangle); |
996 } | 1608 } |
997 | 1609 |
998 void TypeNext::checkDeprecated(Loc loc, Scope *sc) | 1610 void TypeNext::checkDeprecated(Loc loc, Scope *sc) |
999 { | 1611 { |
1000 Type::checkDeprecated(loc, sc); | 1612 Type::checkDeprecated(loc, sc); |
1014 | 1626 |
1015 Type *TypeNext::makeConst() | 1627 Type *TypeNext::makeConst() |
1016 { | 1628 { |
1017 //printf("TypeNext::makeConst() %p, %s\n", this, toChars()); | 1629 //printf("TypeNext::makeConst() %p, %s\n", this, toChars()); |
1018 if (cto) | 1630 if (cto) |
1631 { assert(cto->mod == MODconst); | |
1019 return cto; | 1632 return cto; |
1633 } | |
1020 TypeNext *t = (TypeNext *)Type::makeConst(); | 1634 TypeNext *t = (TypeNext *)Type::makeConst(); |
1021 if (ty != Tfunction && ty != Tdelegate && next->deco && | 1635 if (ty != Tfunction && ty != Tdelegate && next->deco && |
1022 !next->isInvariant()) | 1636 !next->isInvariant() && !next->isConst()) |
1023 t->next = next->constOf(); | 1637 { if (next->isShared()) |
1638 t->next = next->sharedConstOf(); | |
1639 else | |
1640 t->next = next->constOf(); | |
1641 } | |
1024 //printf("TypeNext::makeConst() returns %p, %s\n", t, t->toChars()); | 1642 //printf("TypeNext::makeConst() returns %p, %s\n", t, t->toChars()); |
1025 return t; | 1643 return t; |
1026 } | 1644 } |
1027 | 1645 |
1028 Type *TypeNext::makeInvariant() | 1646 Type *TypeNext::makeInvariant() |
1031 if (ito) | 1649 if (ito) |
1032 { assert(ito->isInvariant()); | 1650 { assert(ito->isInvariant()); |
1033 return ito; | 1651 return ito; |
1034 } | 1652 } |
1035 TypeNext *t = (TypeNext *)Type::makeInvariant(); | 1653 TypeNext *t = (TypeNext *)Type::makeInvariant(); |
1036 if (ty != Tfunction && ty != Tdelegate && next->deco) | 1654 if (ty != Tfunction && ty != Tdelegate && next->deco && |
1655 !next->isInvariant()) | |
1037 { t->next = next->invariantOf(); | 1656 { t->next = next->invariantOf(); |
1038 } | 1657 } |
1658 return t; | |
1659 } | |
1660 | |
1661 Type *TypeNext::makeShared() | |
1662 { | |
1663 //printf("TypeNext::makeShared() %s\n", toChars()); | |
1664 if (sto) | |
1665 { assert(sto->mod == MODshared); | |
1666 return sto; | |
1667 } | |
1668 TypeNext *t = (TypeNext *)Type::makeShared(); | |
1669 if (ty != Tfunction && ty != Tdelegate && next->deco && | |
1670 !next->isInvariant() && !next->isShared()) | |
1671 { | |
1672 if (next->isConst()) | |
1673 t->next = next->sharedConstOf(); | |
1674 else | |
1675 t->next = next->sharedOf(); | |
1676 } | |
1677 //printf("TypeNext::makeShared() returns %p, %s\n", t, t->toChars()); | |
1678 return t; | |
1679 } | |
1680 | |
1681 Type *TypeNext::makeSharedConst() | |
1682 { | |
1683 //printf("TypeNext::makeSharedConst() %s\n", toChars()); | |
1684 if (scto) | |
1685 { assert(scto->mod == (MODshared | MODconst)); | |
1686 return scto; | |
1687 } | |
1688 TypeNext *t = (TypeNext *)Type::makeSharedConst(); | |
1689 if (ty != Tfunction && ty != Tdelegate && next->deco && | |
1690 !next->isInvariant() && !next->isSharedConst()) | |
1691 { | |
1692 t->next = next->sharedConstOf(); | |
1693 } | |
1694 //printf("TypeNext::makeSharedConst() returns %p, %s\n", t, t->toChars()); | |
1039 return t; | 1695 return t; |
1040 } | 1696 } |
1041 | 1697 |
1042 MATCH TypeNext::constConv(Type *to) | 1698 MATCH TypeNext::constConv(Type *to) |
1043 { MATCH m = Type::constConv(to); | 1699 { MATCH m = Type::constConv(to); |
1046 next->constConv(((TypeNext *)to)->next) == MATCHnomatch) | 1702 next->constConv(((TypeNext *)to)->next) == MATCHnomatch) |
1047 m = MATCHnomatch; | 1703 m = MATCHnomatch; |
1048 return m; | 1704 return m; |
1049 } | 1705 } |
1050 | 1706 |
1707 | |
1708 void TypeNext::transitive() | |
1709 { | |
1710 /* Invoke transitivity of type attributes | |
1711 */ | |
1712 next = next->addMod(mod); | |
1713 } | |
1051 | 1714 |
1052 /* ============================= TypeBasic =========================== */ | 1715 /* ============================= TypeBasic =========================== */ |
1053 | 1716 |
1054 TypeBasic::TypeBasic(TY ty) | 1717 TypeBasic::TypeBasic(TY ty) |
1055 : Type(ty) | 1718 : Type(ty) |
1232 | 1895 |
1233 unsigned TypeBasic::alignsize() | 1896 unsigned TypeBasic::alignsize() |
1234 { | 1897 { |
1235 if (ty == Tvoid) | 1898 if (ty == Tvoid) |
1236 return 1; | 1899 return 1; |
1237 return getABITypeAlign(DtoType(this)); | 1900 return GetTypeAlignment(sir, this); |
1901 #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS | |
1902 case Tint64: | |
1903 case Tuns64: | |
1904 case Tfloat64: | |
1905 case Timaginary64: | |
1906 case Tcomplex32: | |
1907 case Tcomplex64: | |
1908 sz = 4; | |
1909 break; | |
1910 #endif | |
1911 #if IN_DMD | |
1912 default: | |
1913 sz = size(0); | |
1914 break; | |
1915 } | |
1916 return sz; | |
1917 #endif | |
1238 } | 1918 } |
1239 | 1919 |
1240 | 1920 |
1241 Expression *TypeBasic::getProperty(Loc loc, Identifier *ident) | 1921 Expression *TypeBasic::getProperty(Loc loc, Identifier *ident) |
1242 { | 1922 { |
1317 case Timaginary80: | 1997 case Timaginary80: |
1318 case Tfloat32: | 1998 case Tfloat32: |
1319 case Tfloat64: | 1999 case Tfloat64: |
1320 case Tfloat80: | 2000 case Tfloat80: |
1321 { | 2001 { |
1322 #if IN_GCC | 2002 fvalue = Port::nan; |
1323 // mode doesn't matter, will be converted in RealExp anyway | |
1324 fvalue = real_t::getnan(real_t::LongDouble); | |
1325 #elif __GNUC__ | |
1326 // gcc nan's have the sign bit set by default, so turn it off | |
1327 // Need the volatile to prevent gcc from doing incorrect | |
1328 // constant folding. | |
1329 volatile d_float80 foo; | |
1330 foo = NAN; | |
1331 if (std::signbit(foo)) // signbit sometimes, not always, set | |
1332 foo = -foo; // turn off sign bit | |
1333 fvalue = foo; | |
1334 #elif _MSC_VER | |
1335 unsigned long nan[2]= { 0xFFFFFFFF, 0x7FFFFFFF }; | |
1336 fvalue = *(double*)nan; | |
1337 #else | |
1338 fvalue = NAN; | |
1339 #endif | |
1340 goto Lfvalue; | 2003 goto Lfvalue; |
1341 } | 2004 } |
1342 } | 2005 } |
1343 } | 2006 } |
1344 else if (ident == Id::infinity) | 2007 else if (ident == Id::infinity) |
1352 case Timaginary64: | 2015 case Timaginary64: |
1353 case Timaginary80: | 2016 case Timaginary80: |
1354 case Tfloat32: | 2017 case Tfloat32: |
1355 case Tfloat64: | 2018 case Tfloat64: |
1356 case Tfloat80: | 2019 case Tfloat80: |
1357 #if IN_GCC | 2020 fvalue = Port::infinity; |
1358 fvalue = real_t::getinfinity(); | |
1359 #elif __GNUC__ | |
1360 fvalue = 1 / zero; | |
1361 #elif _MSC_VER | |
1362 fvalue = std::numeric_limits<long double>::infinity(); | |
1363 #else | |
1364 fvalue = INFINITY; | |
1365 #endif | |
1366 goto Lfvalue; | 2021 goto Lfvalue; |
1367 } | 2022 } |
1368 } | 2023 } |
1369 else if (ident == Id::dig) | 2024 else if (ident == Id::dig) |
1370 { | 2025 { |
1577 } | 2232 } |
1578 return e; | 2233 return e; |
1579 } | 2234 } |
1580 | 2235 |
1581 Expression *TypeBasic::defaultInit(Loc loc) | 2236 Expression *TypeBasic::defaultInit(Loc loc) |
1582 { integer_t value = 0; | 2237 { dinteger_t value = 0; |
2238 | |
2239 #if SNAN_DEFAULT_INIT | |
2240 /* | |
2241 * Use a payload which is different from the machine NaN, | |
2242 * so that uninitialised variables can be | |
2243 * detected even if exceptions are disabled. | |
2244 */ | |
2245 unsigned short snan[8] = { 0, 0, 0, 0xA000, 0x7FFF }; | |
2246 /* | |
2247 * Although long doubles are 10 bytes long, some | |
2248 * C ABIs pad them out to 12 or even 16 bytes, so | |
2249 * leave enough space in the snan array. | |
2250 */ | |
2251 assert(REALSIZE <= sizeof(snan)); | |
2252 d_float80 fvalue = *(long double*)snan; | |
2253 #endif | |
1583 | 2254 |
1584 #if LOGDEFAULTINIT | 2255 #if LOGDEFAULTINIT |
1585 printf("TypeBasic::defaultInit() '%s'\n", toChars()); | 2256 printf("TypeBasic::defaultInit() '%s'\n", toChars()); |
1586 #endif | 2257 #endif |
1587 switch (ty) | 2258 switch (ty) |
1588 { | 2259 { |
1589 case Tvoid: | |
1590 return new IntegerExp(loc, value, Type::tbool); | |
1591 | |
1592 case Tchar: | 2260 case Tchar: |
1593 value = 0xFF; | 2261 value = 0xFF; |
1594 break; | 2262 break; |
1595 | 2263 |
1596 case Twchar: | 2264 case Twchar: |
1602 case Timaginary64: | 2270 case Timaginary64: |
1603 case Timaginary80: | 2271 case Timaginary80: |
1604 case Tfloat32: | 2272 case Tfloat32: |
1605 case Tfloat64: | 2273 case Tfloat64: |
1606 case Tfloat80: | 2274 case Tfloat80: |
2275 #if SNAN_DEFAULT_INIT | |
2276 return new RealExp(loc, fvalue, this); | |
2277 #else | |
2278 return getProperty(loc, Id::nan); | |
2279 #endif | |
2280 | |
1607 case Tcomplex32: | 2281 case Tcomplex32: |
1608 case Tcomplex64: | 2282 case Tcomplex64: |
1609 case Tcomplex80: | 2283 case Tcomplex80: |
2284 #if SNAN_DEFAULT_INIT | |
2285 { // Can't use fvalue + I*fvalue (the im part becomes a quiet NaN). | |
2286 complex_t cvalue; | |
2287 ((real_t *)&cvalue)[0] = fvalue; | |
2288 ((real_t *)&cvalue)[1] = fvalue; | |
2289 return new ComplexExp(loc, cvalue, this); | |
2290 } | |
2291 #else | |
1610 return getProperty(loc, Id::nan); | 2292 return getProperty(loc, Id::nan); |
2293 #endif | |
2294 | |
2295 case Tvoid: | |
2296 error(loc, "void does not have a default initializer"); | |
1611 } | 2297 } |
1612 return new IntegerExp(loc, value, this); | 2298 return new IntegerExp(loc, value, this); |
1613 } | 2299 } |
1614 | 2300 |
1615 int TypeBasic::isZeroInit() | 2301 int TypeBasic::isZeroInit(Loc loc) |
1616 { | 2302 { |
1617 switch (ty) | 2303 switch (ty) |
1618 { | 2304 { |
1619 case Tchar: | 2305 case Tchar: |
1620 case Twchar: | 2306 case Twchar: |
1867 arguments->push(new IntegerExp(0, size, Type::tsize_t)); | 2553 arguments->push(new IntegerExp(0, size, Type::tsize_t)); |
1868 e = new CallExp(e->loc, ec, arguments); | 2554 e = new CallExp(e->loc, ec, arguments); |
1869 if (ident == Id::idup) | 2555 if (ident == Id::idup) |
1870 { Type *einv = next->invariantOf(); | 2556 { Type *einv = next->invariantOf(); |
1871 if (next->implicitConvTo(einv) < MATCHconst) | 2557 if (next->implicitConvTo(einv) < MATCHconst) |
1872 error(e->loc, "cannot implicitly convert element type %s to invariant", next->toChars()); | 2558 error(e->loc, "cannot implicitly convert element type %s to immutable", next->toChars()); |
1873 e->type = einv->arrayOf(); | 2559 e->type = einv->arrayOf(); |
1874 } | 2560 } |
1875 else | 2561 else |
1876 e->type = next->mutableOf()->arrayOf(); | 2562 e->type = next->mutableOf()->arrayOf(); |
1877 } | 2563 } |
1907 // LDC repaint array type to void[] | 2593 // LDC repaint array type to void[] |
1908 if (n->ty != Tvoid) { | 2594 if (n->ty != Tvoid) { |
1909 e = new CastExp(e->loc, e, e->type); | 2595 e = new CastExp(e->loc, e, e->type); |
1910 e->type = Type::tvoid->arrayOf(); | 2596 e->type = Type::tvoid->arrayOf(); |
1911 } | 2597 } |
1912 arguments->push(e); | 2598 arguments->push(e); |
1913 | 2599 |
1914 arguments->push(n->getTypeInfo(sc)); // LDC, we don't support the getInternalTypeInfo | 2600 if (next->ty != Tbit) |
1915 // optimization arbitrarily, not yet at least... | 2601 arguments->push(n->getTypeInfo(sc)); // LDC, we don't support the getInternalTypeInfo |
2602 // optimization arbitrarily, not yet at least... | |
1916 e = new CallExp(e->loc, ec, arguments); | 2603 e = new CallExp(e->loc, ec, arguments); |
1917 e->type = next->arrayOf(); | 2604 e->type = next->arrayOf(); |
1918 } | 2605 } |
1919 else | 2606 else |
1920 { | 2607 { |
1921 e = Type::dotExp(sc, e, ident); | 2608 e = Type::dotExp(sc, e, ident); |
1922 } | 2609 } |
1923 return e; | 2610 return e; |
1924 } | 2611 } |
1925 | |
1926 | 2612 |
1927 | 2613 |
1928 /***************************** TypeSArray *****************************/ | 2614 /***************************** TypeSArray *****************************/ |
1929 | 2615 |
1930 TypeSArray::TypeSArray(Type *t, Expression *dim) | 2616 TypeSArray::TypeSArray(Type *t, Expression *dim) |
1942 t->mod = mod; | 2628 t->mod = mod; |
1943 return t; | 2629 return t; |
1944 } | 2630 } |
1945 | 2631 |
1946 d_uns64 TypeSArray::size(Loc loc) | 2632 d_uns64 TypeSArray::size(Loc loc) |
1947 { integer_t sz; | 2633 { dinteger_t sz; |
1948 | 2634 |
1949 if (!dim) | 2635 if (!dim) |
1950 return Type::size(loc); | 2636 return Type::size(loc); |
1951 sz = dim->toInteger(); | 2637 sz = dim->toInteger(); |
1952 | 2638 |
1953 { integer_t n, n2; | 2639 { dinteger_t n, n2; |
1954 | 2640 |
1955 n = next->size(); | 2641 n = next->size(); |
1956 n2 = n * sz; | 2642 n2 = n * sz; |
1957 if (n && (n2 / n) != sz) | 2643 if (n && (n2 / n) != sz) |
1958 goto Loverflow; | 2644 goto Loverflow; |
1959 sz = n2; | 2645 sz = n2; |
1960 } | 2646 } |
1961 return sz; | 2647 return sz; |
1962 | 2648 |
1963 Loverflow: | 2649 Loverflow: |
1964 error(loc, "index %lld overflow for static array", sz); | 2650 error(loc, "index %jd overflow for static array", sz); |
1965 return 1; | 2651 return 1; |
1966 } | 2652 } |
1967 | 2653 |
1968 unsigned TypeSArray::alignsize() | 2654 unsigned TypeSArray::alignsize() |
1969 { | 2655 { |
2026 uinteger_t d = dim->toUInteger(); | 2712 uinteger_t d = dim->toUInteger(); |
2027 | 2713 |
2028 sc = sc->pop(); | 2714 sc = sc->pop(); |
2029 | 2715 |
2030 if (d >= td->objects->dim) | 2716 if (d >= td->objects->dim) |
2031 { error(loc, "tuple index %llu exceeds %u", d, td->objects->dim); | 2717 { error(loc, "tuple index %ju exceeds %u", d, td->objects->dim); |
2032 goto Ldefault; | 2718 goto Ldefault; |
2033 } | 2719 } |
2034 Object *o = (Object *)td->objects->data[(size_t)d]; | 2720 Object *o = (Object *)td->objects->data[(size_t)d]; |
2035 if (o->dyncast() == DYNCAST_DSYMBOL) | 2721 if (o->dyncast() == DYNCAST_DSYMBOL) |
2036 { | 2722 { |
2080 dim = semanticLength(sc, sd, dim); | 2766 dim = semanticLength(sc, sd, dim); |
2081 dim = dim->optimize(WANTvalue | WANTinterpret); | 2767 dim = dim->optimize(WANTvalue | WANTinterpret); |
2082 uinteger_t d = dim->toUInteger(); | 2768 uinteger_t d = dim->toUInteger(); |
2083 | 2769 |
2084 if (d >= sd->objects->dim) | 2770 if (d >= sd->objects->dim) |
2085 { error(loc, "tuple index %llu exceeds %u", d, sd->objects->dim); | 2771 { error(loc, "tuple index %ju exceeds %u", d, sd->objects->dim); |
2086 return Type::terror; | 2772 return Type::terror; |
2087 } | 2773 } |
2088 Object *o = (Object *)sd->objects->data[(size_t)d]; | 2774 Object *o = (Object *)sd->objects->data[(size_t)d]; |
2089 if (o->dyncast() != DYNCAST_TYPE) | 2775 if (o->dyncast() != DYNCAST_TYPE) |
2090 { error(loc, "%s is not a type", toChars()); | 2776 { error(loc, "%s is not a type", toChars()); |
2093 t = (Type *)o; | 2779 t = (Type *)o; |
2094 return t; | 2780 return t; |
2095 } | 2781 } |
2096 | 2782 |
2097 next = next->semantic(loc,sc); | 2783 next = next->semantic(loc,sc); |
2098 if (mod == MODconst && !next->isInvariant()) | 2784 transitive(); |
2099 next = next->constOf(); | |
2100 else if (mod == MODinvariant) | |
2101 next = next->invariantOf(); | |
2102 | 2785 |
2103 Type *tbn = next->toBasetype(); | 2786 Type *tbn = next->toBasetype(); |
2104 | 2787 |
2105 if (dim) | 2788 if (dim) |
2106 { integer_t n, n2; | 2789 { dinteger_t n, n2; |
2107 | 2790 |
2108 dim = semanticLength(sc, tbn, dim); | 2791 dim = semanticLength(sc, tbn, dim); |
2109 | 2792 |
2110 dim = dim->optimize(WANTvalue | WANTinterpret); | 2793 dim = dim->optimize(WANTvalue | WANTinterpret); |
2111 if (sc && sc->parameterSpecialization && dim->op == TOKvar && | 2794 if (sc && sc->parameterSpecialization && dim->op == TOKvar && |
2114 /* It could be a template parameter N which has no value yet: | 2797 /* It could be a template parameter N which has no value yet: |
2115 * template Foo(T : T[N], size_t N); | 2798 * template Foo(T : T[N], size_t N); |
2116 */ | 2799 */ |
2117 return this; | 2800 return this; |
2118 } | 2801 } |
2119 integer_t d1 = dim->toInteger(); | 2802 dinteger_t d1 = dim->toInteger(); |
2120 dim = dim->castTo(sc, tsize_t); | 2803 dim = dim->castTo(sc, tsize_t); |
2121 dim = dim->optimize(WANTvalue); | 2804 dim = dim->optimize(WANTvalue); |
2122 integer_t d2 = dim->toInteger(); | 2805 dinteger_t d2 = dim->toInteger(); |
2123 | 2806 |
2124 if (d1 != d2) | 2807 if (d1 != d2) |
2125 goto Loverflow; | 2808 goto Loverflow; |
2126 | 2809 |
2127 if (tbn->isintegral() || | 2810 if (tbn->isintegral() || |
2142 if (n2 >= 0x1000000) // put a 'reasonable' limit on it | 2825 if (n2 >= 0x1000000) // put a 'reasonable' limit on it |
2143 goto Loverflow; | 2826 goto Loverflow; |
2144 if (n && n2 / n != d2) | 2827 if (n && n2 / n != d2) |
2145 { | 2828 { |
2146 Loverflow: | 2829 Loverflow: |
2147 error(loc, "index %lld overflow for static array", d1); | 2830 error(loc, "index %jd overflow for static array", d1); |
2148 dim = new IntegerExp(0, 1, tsize_t); | 2831 dim = new IntegerExp(0, 1, tsize_t); |
2149 } | 2832 } |
2150 } | 2833 } |
2151 } | 2834 } |
2152 switch (tbn->ty) | 2835 switch (tbn->ty) |
2156 assert(dim); | 2839 assert(dim); |
2157 TypeTuple *tt = (TypeTuple *)tbn; | 2840 TypeTuple *tt = (TypeTuple *)tbn; |
2158 uinteger_t d = dim->toUInteger(); | 2841 uinteger_t d = dim->toUInteger(); |
2159 | 2842 |
2160 if (d >= tt->arguments->dim) | 2843 if (d >= tt->arguments->dim) |
2161 { error(loc, "tuple index %llu exceeds %u", d, tt->arguments->dim); | 2844 { error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim); |
2162 return Type::terror; | 2845 return Type::terror; |
2163 } | 2846 } |
2164 Argument *arg = (Argument *)tt->arguments->data[(size_t)d]; | 2847 Argument *arg = (Argument *)tt->arguments->data[(size_t)d]; |
2165 return arg->type; | 2848 return arg->type; |
2849 } | |
2850 case Tstruct: | |
2851 { TypeStruct *ts = (TypeStruct *)tbn; | |
2852 if (ts->sym->isnested) | |
2853 error(loc, "cannot have array of inner structs %s", ts->toChars()); | |
2854 break; | |
2166 } | 2855 } |
2167 case Tfunction: | 2856 case Tfunction: |
2168 case Tnone: | 2857 case Tnone: |
2169 error(loc, "can't have array of %s", tbn->toChars()); | 2858 error(loc, "can't have array of %s", tbn->toChars()); |
2170 tbn = next = tint32; | 2859 tbn = next = tint32; |
2173 if (tbn->isauto()) | 2862 if (tbn->isauto()) |
2174 error(loc, "cannot have array of auto %s", tbn->toChars()); | 2863 error(loc, "cannot have array of auto %s", tbn->toChars()); |
2175 return merge(); | 2864 return merge(); |
2176 } | 2865 } |
2177 | 2866 |
2178 void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag) | 2867 void TypeSArray::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) |
2179 { | 2868 { |
2180 Type::toDecoBuffer(buf, flag); | 2869 Type::toDecoBuffer(buf, flag, mangle); |
2181 if (dim) | 2870 if (dim) |
2182 buf->printf("%llu", dim->toInteger()); | 2871 buf->printf("%ju", dim->toInteger()); |
2183 if (next) | 2872 if (next) |
2184 /* Note that static arrays are value types, so | 2873 /* Note that static arrays are value types, so |
2185 * for a parameter, propagate the 0x100 to the next | 2874 * for a parameter, propagate the 0x100 to the next |
2186 * level, since for T[4][3], any const should apply to the T, | 2875 * level, since for T[4][3], any const should apply to the T, |
2187 * not the [4]. | 2876 * not the [4]. |
2188 */ | 2877 */ |
2189 next->toDecoBuffer(buf, (flag & 0x100) ? flag : mod); | 2878 next->toDecoBuffer(buf, (flag & 0x100) ? flag : mod, mangle); |
2190 } | 2879 } |
2191 | 2880 |
2192 void TypeSArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | 2881 void TypeSArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) |
2193 { | 2882 { |
2194 if (mod != this->mod) | 2883 if (mod != this->mod) |
2305 printf("TypeSArray::defaultInit() '%s'\n", toChars()); | 2994 printf("TypeSArray::defaultInit() '%s'\n", toChars()); |
2306 #endif | 2995 #endif |
2307 return next->defaultInit(loc); | 2996 return next->defaultInit(loc); |
2308 } | 2997 } |
2309 | 2998 |
2310 int TypeSArray::isZeroInit() | 2999 int TypeSArray::isZeroInit(Loc loc) |
2311 { | 3000 { |
2312 return next->isZeroInit(); | 3001 return next->isZeroInit(loc); |
2313 } | 3002 } |
2314 | 3003 |
2315 | 3004 |
2316 Expression *TypeSArray::toExpression() | 3005 Expression *TypeSArray::toExpression() |
2317 { | 3006 { |
2373 case Tnone: | 3062 case Tnone: |
2374 case Ttuple: | 3063 case Ttuple: |
2375 error(loc, "can't have array of %s", tbn->toChars()); | 3064 error(loc, "can't have array of %s", tbn->toChars()); |
2376 tn = next = tint32; | 3065 tn = next = tint32; |
2377 break; | 3066 break; |
3067 case Tstruct: | |
3068 { TypeStruct *ts = (TypeStruct *)tbn; | |
3069 if (ts->sym->isnested) | |
3070 error(loc, "cannot have array of inner structs %s", ts->toChars()); | |
3071 break; | |
3072 } | |
2378 } | 3073 } |
2379 if (tn->isauto()) | 3074 if (tn->isauto()) |
2380 error(loc, "cannot have array of auto %s", tn->toChars()); | 3075 error(loc, "cannot have array of auto %s", tn->toChars()); |
2381 | 3076 |
2382 if (mod == MODconst && !tn->isInvariant()) | |
2383 tn = tn->constOf(); | |
2384 else if (mod == MODinvariant) | |
2385 tn = tn->invariantOf(); | |
2386 | |
2387 next = tn; | 3077 next = tn; |
3078 transitive(); | |
2388 return merge(); | 3079 return merge(); |
2389 } | 3080 } |
2390 | 3081 |
2391 void TypeDArray::toDecoBuffer(OutBuffer *buf, int flag) | 3082 void TypeDArray::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) |
2392 { | 3083 { |
2393 Type::toDecoBuffer(buf, flag); | 3084 Type::toDecoBuffer(buf, flag, mangle); |
2394 if (next) | 3085 if (next) |
2395 next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); | 3086 next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod, mangle); |
2396 } | 3087 } |
2397 | 3088 |
2398 void TypeDArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | 3089 void TypeDArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) |
2399 { | 3090 { |
2400 if (mod != this->mod) | 3091 if (mod != this->mod) |
2509 e = new NullExp(loc); | 3200 e = new NullExp(loc); |
2510 e->type = this; | 3201 e->type = this; |
2511 return e; | 3202 return e; |
2512 } | 3203 } |
2513 | 3204 |
2514 int TypeDArray::isZeroInit() | 3205 int TypeDArray::isZeroInit(Loc loc) |
2515 { | 3206 { |
2516 return 1; | 3207 return 1; |
2517 } | 3208 } |
2518 | 3209 |
2519 int TypeDArray::checkBoolean() | 3210 int TypeDArray::checkBoolean() |
2583 index = index->semantic(loc,sc); | 3274 index = index->semantic(loc,sc); |
2584 | 3275 |
2585 if (index->nextOf() && !index->nextOf()->isInvariant()) | 3276 if (index->nextOf() && !index->nextOf()->isInvariant()) |
2586 { | 3277 { |
2587 index = index->constOf()->mutableOf(); | 3278 index = index->constOf()->mutableOf(); |
3279 #if 0 | |
3280 printf("index is %p %s\n", index, index->toChars()); | |
3281 index->check(); | |
3282 printf("index->mod = x%x\n", index->mod); | |
3283 printf("index->ito = x%x\n", index->ito); | |
3284 if (index->ito) { | |
3285 printf("index->ito->mod = x%x\n", index->ito->mod); | |
3286 printf("index->ito->ito = x%x\n", index->ito->ito); | |
3287 } | |
3288 #endif | |
2588 } | 3289 } |
2589 | 3290 |
2590 switch (index->toBasetype()->ty) | 3291 switch (index->toBasetype()->ty) |
2591 { | 3292 { |
2592 case Tbool: | 3293 case Tbool: |
2595 case Tnone: | 3296 case Tnone: |
2596 error(loc, "can't have associative array key of %s", index->toBasetype()->toChars()); | 3297 error(loc, "can't have associative array key of %s", index->toBasetype()->toChars()); |
2597 break; | 3298 break; |
2598 } | 3299 } |
2599 next = next->semantic(loc,sc); | 3300 next = next->semantic(loc,sc); |
2600 if (mod == MODconst && !next->isInvariant()) | 3301 transitive(); |
2601 next = next->constOf(); | |
2602 else if (mod == MODinvariant) | |
2603 next = next->invariantOf(); | |
2604 | 3302 |
2605 switch (next->toBasetype()->ty) | 3303 switch (next->toBasetype()->ty) |
2606 { | 3304 { |
2607 case Tfunction: | 3305 case Tfunction: |
2608 case Tnone: | 3306 case Tnone: |
2664 | 3362 |
2665 ec = new VarExp(0, aaLen_fd); | 3363 ec = new VarExp(0, aaLen_fd); |
2666 arguments = new Expressions(); | 3364 arguments = new Expressions(); |
2667 arguments->push(e); | 3365 arguments->push(e); |
2668 e = new CallExp(e->loc, ec, arguments); | 3366 e = new CallExp(e->loc, ec, arguments); |
2669 e->type = ((TypeFunction *)aaLen_fd->type)->next; | 3367 e->type = aaLen_fd->type->nextOf(); |
2670 } | 3368 } |
2671 else if (ident == Id::keys) | 3369 else if (ident == Id::keys) |
2672 { | 3370 { |
2673 Expression *ec; | 3371 Expression *ec; |
2674 Expressions *arguments; | 3372 Expressions *arguments; |
2731 } | 3429 } |
2732 | 3430 |
2733 ec = new VarExp(0, aaRehash_fd); | 3431 ec = new VarExp(0, aaRehash_fd); |
2734 arguments = new Expressions(); | 3432 arguments = new Expressions(); |
2735 arguments->push(e->addressOf(sc)); | 3433 arguments->push(e->addressOf(sc)); |
2736 arguments->push(index->getInternalTypeInfo(sc)); | 3434 arguments->push(index->getInternalTypeInfo(sc)); // LDC doesn't support getInternalTypeInfo, see above |
2737 e = new CallExp(e->loc, ec, arguments); | 3435 e = new CallExp(e->loc, ec, arguments); |
2738 e->type = this; | 3436 e->type = this; |
2739 } | 3437 } |
2740 else | 3438 else |
2741 { | 3439 { |
2742 e = Type::dotExp(sc, e, ident); | 3440 e = Type::dotExp(sc, e, ident); |
2743 } | 3441 } |
2744 return e; | 3442 return e; |
2745 } | 3443 } |
2746 | 3444 |
2747 void TypeAArray::toDecoBuffer(OutBuffer *buf, int flag) | 3445 void TypeAArray::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) |
2748 { | 3446 { |
2749 Type::toDecoBuffer(buf, flag); | 3447 Type::toDecoBuffer(buf, flag, mangle); |
2750 index->toDecoBuffer(buf); | 3448 index->toDecoBuffer(buf, mangle); |
2751 next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); | 3449 next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod, mangle); |
2752 } | 3450 } |
2753 | 3451 |
2754 void TypeAArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | 3452 void TypeAArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) |
2755 { | 3453 { |
2756 if (mod != this->mod) | 3454 if (mod != this->mod) |
2772 e = new NullExp(loc); | 3470 e = new NullExp(loc); |
2773 e->type = this; | 3471 e->type = this; |
2774 return e; | 3472 return e; |
2775 } | 3473 } |
2776 | 3474 |
2777 int TypeAArray::isZeroInit() | 3475 int TypeAArray::isZeroInit(Loc loc) |
2778 { | 3476 { |
2779 return TRUE; | 3477 return TRUE; |
2780 } | 3478 } |
2781 | 3479 |
2782 int TypeAArray::checkBoolean() | 3480 int TypeAArray::checkBoolean() |
2863 break; | 3561 break; |
2864 } | 3562 } |
2865 if (n != next) | 3563 if (n != next) |
2866 deco = NULL; | 3564 deco = NULL; |
2867 next = n; | 3565 next = n; |
2868 if (mod == MODconst && !next->isInvariant()) | 3566 transitive(); |
2869 next = next->constOf(); | |
2870 else if (mod == MODinvariant) | |
2871 next = next->invariantOf(); | |
2872 return merge(); | 3567 return merge(); |
2873 } | 3568 } |
2874 | 3569 |
2875 | 3570 |
2876 d_uns64 TypePointer::size(Loc loc) | 3571 d_uns64 TypePointer::size(Loc loc) |
2941 e = new NullExp(loc); | 3636 e = new NullExp(loc); |
2942 e->type = this; | 3637 e->type = this; |
2943 return e; | 3638 return e; |
2944 } | 3639 } |
2945 | 3640 |
2946 int TypePointer::isZeroInit() | 3641 int TypePointer::isZeroInit(Loc loc) |
2947 { | 3642 { |
2948 return 1; | 3643 return 1; |
2949 } | 3644 } |
2950 | 3645 |
2951 int TypePointer::hasPointers() | 3646 int TypePointer::hasPointers() |
2979 //printf("TypeReference::semantic()\n"); | 3674 //printf("TypeReference::semantic()\n"); |
2980 Type *n = next->semantic(loc, sc); | 3675 Type *n = next->semantic(loc, sc); |
2981 if (n != next) | 3676 if (n != next) |
2982 deco = NULL; | 3677 deco = NULL; |
2983 next = n; | 3678 next = n; |
2984 if (mod == MODconst && !next->isInvariant()) | 3679 transitive(); |
2985 next = next->constOf(); | |
2986 else if (mod == MODinvariant) | |
2987 next = next->invariantOf(); | |
2988 return merge(); | 3680 return merge(); |
2989 } | 3681 } |
2990 | 3682 |
2991 | 3683 |
2992 d_uns64 TypeReference::size(Loc loc) | 3684 d_uns64 TypeReference::size(Loc loc) |
3022 Expression *e = new NullExp(loc); | 3714 Expression *e = new NullExp(loc); |
3023 e->type = this; | 3715 e->type = this; |
3024 return e; | 3716 return e; |
3025 } | 3717 } |
3026 | 3718 |
3027 int TypeReference::isZeroInit() | 3719 int TypeReference::isZeroInit(Loc loc) |
3028 { | 3720 { |
3029 return 1; | 3721 return 1; |
3030 } | 3722 } |
3031 | 3723 |
3032 | 3724 |
3044 this->inuse = 0; | 3736 this->inuse = 0; |
3045 this->isnothrow = false; | 3737 this->isnothrow = false; |
3046 this->ispure = false; | 3738 this->ispure = false; |
3047 this->isref = false; | 3739 this->isref = false; |
3048 | 3740 |
3049 // LDC | 3741 #if IN_LLVM |
3050 this->fty = NULL; | 3742 this->funcdecl = NULL; |
3743 #endif | |
3051 } | 3744 } |
3052 | 3745 |
3053 Type *TypeFunction::syntaxCopy() | 3746 Type *TypeFunction::syntaxCopy() |
3054 { | 3747 { |
3055 Type *treturn = next ? next->syntaxCopy() : NULL; | 3748 Type *treturn = next ? next->syntaxCopy() : NULL; |
3075 { | 3768 { |
3076 #if 0 | 3769 #if 0 |
3077 printf("Type::covariant(t = %s) %s\n", t->toChars(), toChars()); | 3770 printf("Type::covariant(t = %s) %s\n", t->toChars(), toChars()); |
3078 printf("deco = %p, %p\n", deco, t->deco); | 3771 printf("deco = %p, %p\n", deco, t->deco); |
3079 // printf("ty = %d\n", next->ty); | 3772 // printf("ty = %d\n", next->ty); |
3773 printf("mod = %x, %x\n", mod, t->mod); | |
3080 #endif | 3774 #endif |
3081 | 3775 |
3082 int inoutmismatch = 0; | 3776 int inoutmismatch = 0; |
3083 | 3777 |
3084 TypeFunction *t1; | 3778 TypeFunction *t1; |
3152 goto Lcovariant; | 3846 goto Lcovariant; |
3153 } | 3847 } |
3154 goto Lnotcovariant; | 3848 goto Lnotcovariant; |
3155 | 3849 |
3156 Lcovariant: | 3850 Lcovariant: |
3851 /* Can convert mutable to const | |
3852 */ | |
3853 if (t1->mod != t2->mod) | |
3854 { | |
3855 if (!(t1->mod & MODconst) && (t2->mod & MODconst)) | |
3856 goto Lnotcovariant; | |
3857 if (!(t1->mod & MODshared) && (t2->mod & MODshared)) | |
3858 goto Lnotcovariant; | |
3859 } | |
3860 | |
3157 /* Can convert pure to impure, and nothrow to throw | 3861 /* Can convert pure to impure, and nothrow to throw |
3158 */ | 3862 */ |
3159 if (!t1->ispure && t2->ispure) | 3863 if (!t1->ispure && t2->ispure) |
3160 goto Lnotcovariant; | 3864 goto Lnotcovariant; |
3161 | 3865 |
3175 Lnotcovariant: | 3879 Lnotcovariant: |
3176 //printf("\tcovaraint: 2\n"); | 3880 //printf("\tcovaraint: 2\n"); |
3177 return 2; | 3881 return 2; |
3178 } | 3882 } |
3179 | 3883 |
3180 void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag) | 3884 void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) |
3181 { unsigned char mc; | 3885 { unsigned char mc; |
3182 | 3886 |
3183 //printf("TypeFunction::toDecoBuffer() this = %p %s\n", this, toChars()); | 3887 //printf("TypeFunction::toDecoBuffer() this = %p %s\n", this, toChars()); |
3184 //static int nest; if (++nest == 50) *(char*)0=0; | 3888 //static int nest; if (++nest == 50) *(char*)0=0; |
3185 if (inuse) | 3889 if (inuse) |
3208 | 3912 |
3209 default: | 3913 default: |
3210 assert(0); | 3914 assert(0); |
3211 } | 3915 } |
3212 buf->writeByte(mc); | 3916 buf->writeByte(mc); |
3917 // Possible conflict from merge | |
3213 if (ispure || isnothrow || isref) | 3918 if (ispure || isnothrow || isref) |
3214 { | 3919 { |
3215 if (ispure) | 3920 if (ispure) |
3216 buf->writestring("Na"); | 3921 buf->writestring("Na"); |
3217 if (isnothrow) | 3922 if (isnothrow) |
3218 buf->writestring("Nb"); | 3923 buf->writestring("Nb"); |
3219 if (isref) | 3924 if (isref) |
3220 buf->writestring("Nc"); | 3925 buf->writestring("Nc"); |
3221 } | 3926 } |
3222 // Write argument types | 3927 // Write argument types |
3223 Argument::argsToDecoBuffer(buf, parameters); | 3928 Argument::argsToDecoBuffer(buf, parameters, mangle); |
3224 //if (buf->data[buf->offset - 1] == '@') halt(); | 3929 //if (buf->data[buf->offset - 1] == '@') halt(); |
3225 buf->writeByte('Z' - varargs); // mark end of arg list | 3930 buf->writeByte('Z' - varargs); // mark end of arg list |
3226 next->toDecoBuffer(buf); | 3931 next->toDecoBuffer(buf, mangle); |
3227 inuse--; | 3932 inuse--; |
3228 } | 3933 } |
3229 | 3934 |
3230 void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs) | 3935 void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs) |
3231 { | 3936 { |
3232 //printf("TypeFunction::toCBuffer() this = %p %s\n", this, toChars()); | 3937 //printf("TypeFunction::toCBuffer() this = %p\n", this); |
3233 const char *p = NULL; | 3938 const char *p = NULL; |
3234 | 3939 |
3235 if (inuse) | 3940 if (inuse) |
3236 { inuse = 2; // flag error to caller | 3941 { inuse = 2; // flag error to caller |
3237 return; | 3942 return; |
3241 /* Use 'storage class' style for attributes | 3946 /* Use 'storage class' style for attributes |
3242 */ | 3947 */ |
3243 if (mod & MODconst) | 3948 if (mod & MODconst) |
3244 buf->writestring("const "); | 3949 buf->writestring("const "); |
3245 if (mod & MODinvariant) | 3950 if (mod & MODinvariant) |
3246 buf->writestring("invariant "); | 3951 buf->writestring("immutable "); |
3247 if (mod & MODshared) | 3952 if (mod & MODshared) |
3248 buf->writestring("shared "); | 3953 buf->writestring("shared "); |
3249 | 3954 |
3250 if (ispure) | 3955 if (ispure) |
3251 buf->writestring("pure "); | 3956 buf->writestring("pure "); |
3284 inuse--; | 3989 inuse--; |
3285 } | 3990 } |
3286 | 3991 |
3287 void TypeFunction::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | 3992 void TypeFunction::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) |
3288 { | 3993 { |
3289 //printf("TypeFunction::toCBuffer2() this = %p %s\n", this, toChars()); | 3994 //printf("TypeFunction::toCBuffer2() this = %p, ref = %d\n", this, isref); |
3290 const char *p = NULL; | 3995 const char *p = NULL; |
3291 | 3996 |
3292 if (inuse) | 3997 if (inuse) |
3293 { inuse = 2; // flag error to caller | 3998 { inuse = 2; // flag error to caller |
3294 return; | 3999 return; |
3346 { | 4051 { |
3347 //printf("already done\n"); | 4052 //printf("already done\n"); |
3348 return this; | 4053 return this; |
3349 } | 4054 } |
3350 //printf("TypeFunction::semantic() this = %p\n", this); | 4055 //printf("TypeFunction::semantic() this = %p\n", this); |
4056 //printf("TypeFunction::semantic() %s, sc->stc = %x\n", toChars(), sc->stc); | |
3351 | 4057 |
3352 TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction)); | 4058 TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction)); |
3353 memcpy(tf, this, sizeof(TypeFunction)); | 4059 memcpy(tf, this, sizeof(TypeFunction)); |
3354 if (parameters) | 4060 if (parameters) |
3355 { tf->parameters = (Arguments *)parameters->copy(); | 4061 { tf->parameters = (Arguments *)parameters->copy(); |
3386 if (tf->next->toBasetype()->ty == Ttuple) | 4092 if (tf->next->toBasetype()->ty == Ttuple) |
3387 { error(loc, "functions cannot return a tuple"); | 4093 { error(loc, "functions cannot return a tuple"); |
3388 tf->next = Type::terror; | 4094 tf->next = Type::terror; |
3389 } | 4095 } |
3390 if (tf->next->isauto() && !(sc->flags & SCOPEctor)) | 4096 if (tf->next->isauto() && !(sc->flags & SCOPEctor)) |
3391 error(loc, "functions cannot return auto %s", tf->next->toChars()); | 4097 error(loc, "functions cannot return scope %s", tf->next->toChars()); |
3392 | 4098 |
3393 if (tf->parameters) | 4099 if (tf->parameters) |
3394 { size_t dim = Argument::dim(tf->parameters); | 4100 { size_t dim = Argument::dim(tf->parameters); |
3395 | 4101 |
3396 for (size_t i = 0; i < dim; i++) | 4102 for (size_t i = 0; i < dim; i++) |
3398 | 4104 |
3399 tf->inuse++; | 4105 tf->inuse++; |
3400 arg->type = arg->type->semantic(loc,sc); | 4106 arg->type = arg->type->semantic(loc,sc); |
3401 if (tf->inuse == 1) tf->inuse--; | 4107 if (tf->inuse == 1) tf->inuse--; |
3402 | 4108 |
3403 if (arg->storageClass & (STCconst | STCin)) | 4109 arg->type = arg->type->addStorageClass(arg->storageClass); |
3404 { | |
3405 if (!arg->type->isInvariant()) | |
3406 arg->type = arg->type->constOf(); | |
3407 } | |
3408 else if (arg->storageClass & STCinvariant) | |
3409 arg->type = arg->type->invariantOf(); | |
3410 | 4110 |
3411 if (arg->storageClass & (STCauto | STCalias | STCstatic)) | 4111 if (arg->storageClass & (STCauto | STCalias | STCstatic)) |
3412 { | 4112 { |
3413 if (!arg->type) | 4113 if (!arg->type) |
3414 continue; | 4114 continue; |
3415 } | 4115 } |
3416 | 4116 // Possible merge conflict |
3417 Type *t = arg->type->toBasetype(); | 4117 Type *t = arg->type->toBasetype(); |
3418 | 4118 |
3419 if (arg->storageClass & (STCout | STCref | STClazy)) | 4119 if (arg->storageClass & (STCout | STCref | STClazy)) |
3420 { | 4120 { |
3421 if (t->ty == Tsarray) | 4121 if (t->ty == Tsarray) |
3529 { | 4229 { |
3530 L1: | 4230 L1: |
3531 if (varargs == 2 && u + 1 == nparams) // if last varargs param | 4231 if (varargs == 2 && u + 1 == nparams) // if last varargs param |
3532 { Type *tb = p->type->toBasetype(); | 4232 { Type *tb = p->type->toBasetype(); |
3533 TypeSArray *tsa; | 4233 TypeSArray *tsa; |
3534 integer_t sz; | 4234 dinteger_t sz; |
3535 | 4235 |
3536 switch (tb->ty) | 4236 switch (tb->ty) |
3537 { | 4237 { |
3538 case Tsarray: | 4238 case Tsarray: |
3539 tsa = (TypeSArray *)tb; | 4239 tsa = (TypeSArray *)tb; |
3717 e = new NullExp(loc); | 4417 e = new NullExp(loc); |
3718 e->type = this; | 4418 e->type = this; |
3719 return e; | 4419 return e; |
3720 } | 4420 } |
3721 | 4421 |
3722 int TypeDelegate::isZeroInit() | 4422 int TypeDelegate::isZeroInit(Loc loc) |
3723 { | 4423 { |
3724 return 1; | 4424 return 1; |
3725 } | 4425 } |
3726 | 4426 |
3727 int TypeDelegate::checkBoolean() | 4427 int TypeDelegate::checkBoolean() |
3984 t = t->semantic(loc, scx); | 4684 t = t->semantic(loc, scx); |
3985 //((TypeIdentifier *)t)->resolve(loc, scx, pe, &t, ps); | 4685 //((TypeIdentifier *)t)->resolve(loc, scx, pe, &t, ps); |
3986 } | 4686 } |
3987 } | 4687 } |
3988 if (t->ty == Ttuple) | 4688 if (t->ty == Ttuple) |
3989 *pt = t->syntaxCopy(); | 4689 *pt = t; |
3990 else | 4690 else |
3991 *pt = t->merge(); | 4691 *pt = t->merge(); |
3992 } | 4692 } |
3993 if (!s) | 4693 if (!s) |
3994 { | 4694 { |
4013 t->syntaxCopyHelper(this); | 4713 t->syntaxCopyHelper(this); |
4014 t->mod = mod; | 4714 t->mod = mod; |
4015 return t; | 4715 return t; |
4016 } | 4716 } |
4017 | 4717 |
4018 void TypeIdentifier::toDecoBuffer(OutBuffer *buf, int flag) | 4718 void TypeIdentifier::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) |
4019 { unsigned len; | 4719 { unsigned len; |
4020 char *name; | 4720 char *name; |
4021 | 4721 |
4022 Type::toDecoBuffer(buf, flag); | 4722 Type::toDecoBuffer(buf, flag, mangle); |
4023 name = ident->toChars(); | 4723 name = ident->toChars(); |
4024 len = strlen(name); | 4724 len = strlen(name); |
4025 buf->printf("%d%s", len, name); | 4725 buf->printf("%d%s", len, name); |
4026 } | 4726 } |
4027 | 4727 |
4048 Dsymbol *scopesym; | 4748 Dsymbol *scopesym; |
4049 | 4749 |
4050 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars()); | 4750 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars()); |
4051 s = sc->search(loc, ident, &scopesym); | 4751 s = sc->search(loc, ident, &scopesym); |
4052 resolveHelper(loc, sc, s, scopesym, pe, pt, ps); | 4752 resolveHelper(loc, sc, s, scopesym, pe, pt, ps); |
4053 if (*pt && mod) | 4753 if (*pt) |
4054 { | 4754 (*pt) = (*pt)->addMod(mod); |
4055 if (mod & MODconst) | |
4056 *pt = (*pt)->constOf(); | |
4057 else if (mod & MODinvariant) | |
4058 *pt = (*pt)->invariantOf(); | |
4059 } | |
4060 } | 4755 } |
4061 | 4756 |
4062 /***************************************** | 4757 /***************************************** |
4063 * See if type resolves to a symbol, if so, | 4758 * See if type resolves to a symbol, if so, |
4064 * return that symbol. | 4759 * return that symbol. |
4104 { TypeTypedef *tt = (TypeTypedef *)t; | 4799 { TypeTypedef *tt = (TypeTypedef *)t; |
4105 | 4800 |
4106 if (tt->sym->sem == 1) | 4801 if (tt->sym->sem == 1) |
4107 error(loc, "circular reference of typedef %s", tt->toChars()); | 4802 error(loc, "circular reference of typedef %s", tt->toChars()); |
4108 } | 4803 } |
4109 if (isConst()) | 4804 t = t->addMod(mod); |
4110 t = t->constOf(); | |
4111 else if (isInvariant()) | |
4112 t = t->invariantOf(); | |
4113 } | 4805 } |
4114 else | 4806 else |
4115 { | 4807 { |
4116 #ifdef DEBUG | 4808 #ifdef DEBUG |
4117 if (!global.gag) | 4809 if (!global.gag) |
4198 //printf("TypeInstance::resolve(sc = %p, idents = '%s')\n", sc, id->toChars()); | 4890 //printf("TypeInstance::resolve(sc = %p, idents = '%s')\n", sc, id->toChars()); |
4199 s = tempinst; | 4891 s = tempinst; |
4200 if (s) | 4892 if (s) |
4201 s->semantic(sc); | 4893 s->semantic(sc); |
4202 resolveHelper(loc, sc, s, NULL, pe, pt, ps); | 4894 resolveHelper(loc, sc, s, NULL, pe, pt, ps); |
4203 if (*pt && mod) | 4895 if (*pt) |
4204 { | 4896 *pt = (*pt)->addMod(mod); |
4205 if (mod & MODconst) | |
4206 *pt = (*pt)->constOf(); | |
4207 else if (mod & MODinvariant) | |
4208 *pt = (*pt)->invariantOf(); | |
4209 } | |
4210 //printf("pt = '%s'\n", (*pt)->toChars()); | 4897 //printf("pt = '%s'\n", (*pt)->toChars()); |
4211 } | 4898 } |
4212 | 4899 |
4213 Type *TypeInstance::semantic(Loc loc, Scope *sc) | 4900 Type *TypeInstance::semantic(Loc loc, Scope *sc) |
4214 { | 4901 { |
4244 t = tvoid; | 4931 t = tvoid; |
4245 } | 4932 } |
4246 return t; | 4933 return t; |
4247 } | 4934 } |
4248 | 4935 |
4936 Dsymbol *TypeInstance::toDsymbol(Scope *sc) | |
4937 { | |
4938 Type *t; | |
4939 Expression *e; | |
4940 Dsymbol *s; | |
4941 | |
4942 //printf("TypeInstance::semantic(%s)\n", toChars()); | |
4943 | |
4944 if (sc->parameterSpecialization) | |
4945 { | |
4946 unsigned errors = global.errors; | |
4947 global.gag++; | |
4948 | |
4949 resolve(loc, sc, &e, &t, &s); | |
4950 | |
4951 global.gag--; | |
4952 if (errors != global.errors) | |
4953 { if (global.gag == 0) | |
4954 global.errors = errors; | |
4955 return NULL; | |
4956 } | |
4957 } | |
4958 else | |
4959 resolve(loc, sc, &e, &t, &s); | |
4960 | |
4961 return s; | |
4962 } | |
4963 | |
4249 | 4964 |
4250 /***************************** TypeTypeof *****************************/ | 4965 /***************************** TypeTypeof *****************************/ |
4251 | 4966 |
4252 TypeTypeof::TypeTypeof(Loc loc, Expression *exp) | 4967 TypeTypeof::TypeTypeof(Loc loc, Expression *exp) |
4253 : TypeQualified(Ttypeof, loc) | 4968 : TypeQualified(Ttypeof, loc) |
4255 this->exp = exp; | 4970 this->exp = exp; |
4256 } | 4971 } |
4257 | 4972 |
4258 Type *TypeTypeof::syntaxCopy() | 4973 Type *TypeTypeof::syntaxCopy() |
4259 { | 4974 { |
4975 //printf("TypeTypeof::syntaxCopy() %s\n", toChars()); | |
4260 TypeTypeof *t; | 4976 TypeTypeof *t; |
4261 | 4977 |
4262 t = new TypeTypeof(loc, exp->syntaxCopy()); | 4978 t = new TypeTypeof(loc, exp->syntaxCopy()); |
4263 t->syntaxCopyHelper(this); | 4979 t->syntaxCopyHelper(this); |
4264 t->mod = mod; | 4980 t->mod = mod; |
4361 /* typeof should reflect the true type, | 5077 /* typeof should reflect the true type, |
4362 * not what 'auto' would have gotten us. | 5078 * not what 'auto' would have gotten us. |
4363 */ | 5079 */ |
4364 //t = t->toHeadMutable(); | 5080 //t = t->toHeadMutable(); |
4365 } | 5081 } |
4366 | |
4367 if (idents.dim) | 5082 if (idents.dim) |
4368 { | 5083 { |
4369 Dsymbol *s = t->toDsymbol(sc); | 5084 Dsymbol *s = t->toDsymbol(sc); |
4370 for (size_t i = 0; i < idents.dim; i++) | 5085 for (size_t i = 0; i < idents.dim; i++) |
4371 { | 5086 { |
4372 if (!s) | 5087 if (!s) |
4373 break; | 5088 break; |
4374 Identifier *id = (Identifier *)idents.data[i]; | 5089 Identifier *id = (Identifier *)idents.data[i]; |
4375 s = s->searchX(loc, sc, id); | 5090 s = s->searchX(loc, sc, id); |
4376 } | 5091 } |
5092 | |
4377 if (s) | 5093 if (s) |
4378 { | 5094 { |
4379 t = s->getType(); | 5095 t = s->getType(); |
4380 if (!t) | 5096 if (!t) |
4381 { error(loc, "%s is not a type", s->toChars()); | 5097 { error(loc, "%s is not a type", s->toChars()); |
4432 if (!sc->func) | 5148 if (!sc->func) |
4433 { error(loc, "typeof(return) must be inside function"); | 5149 { error(loc, "typeof(return) must be inside function"); |
4434 goto Lerr; | 5150 goto Lerr; |
4435 } | 5151 } |
4436 t = sc->func->type->nextOf(); | 5152 t = sc->func->type->nextOf(); |
4437 | 5153 t = t->addMod(mod); |
4438 if (mod & MODinvariant) | |
4439 t = t->invariantOf(); | |
4440 else if (mod & MODconst) | |
4441 t = t->constOf(); | |
4442 | 5154 |
4443 if (idents.dim) | 5155 if (idents.dim) |
4444 { | 5156 { |
4445 Dsymbol *s = t->toDsymbol(sc); | 5157 Dsymbol *s = t->toDsymbol(sc); |
4446 for (size_t i = 0; i < idents.dim; i++) | 5158 for (size_t i = 0; i < idents.dim; i++) |
4546 return tint32; | 5258 return tint32; |
4547 } | 5259 } |
4548 return sym->memtype->toBasetype(); | 5260 return sym->memtype->toBasetype(); |
4549 } | 5261 } |
4550 | 5262 |
4551 void TypeEnum::toDecoBuffer(OutBuffer *buf, int flag) | 5263 void TypeEnum::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) |
4552 { | 5264 { |
4553 const char *name = sym->mangle(); | 5265 const char *name = sym->mangle(); |
4554 Type::toDecoBuffer(buf, flag); | 5266 Type::toDecoBuffer(buf, flag, mangle); |
4555 buf->printf("%s", name); | 5267 buf->printf("%s", name); |
4556 } | 5268 } |
4557 | 5269 |
4558 void TypeEnum::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | 5270 void TypeEnum::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) |
4559 { | 5271 { |
4570 printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e->toChars(), ident->toChars(), toChars()); | 5282 printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e->toChars(), ident->toChars(), toChars()); |
4571 #endif | 5283 #endif |
4572 Dsymbol *s = sym->search(e->loc, ident, 0); | 5284 Dsymbol *s = sym->search(e->loc, ident, 0); |
4573 if (!s) | 5285 if (!s) |
4574 { | 5286 { |
4575 return getProperty(e->loc, ident); | 5287 if (ident == Id::max || |
5288 ident == Id::min || | |
5289 ident == Id::init || | |
5290 ident == Id::stringof || | |
5291 !sym->memtype | |
5292 ) | |
5293 { | |
5294 return getProperty(e->loc, ident); | |
5295 } | |
5296 return sym->memtype->dotExp(sc, e, ident); | |
4576 } | 5297 } |
4577 EnumMember *m = s->isEnumMember(); | 5298 EnumMember *m = s->isEnumMember(); |
4578 Expression *em = m->value->copy(); | 5299 Expression *em = m->value->copy(); |
4579 em->loc = e->loc; | 5300 em->loc = e->loc; |
4580 return em; | 5301 return em; |
4611 } | 5332 } |
4612 return e; | 5333 return e; |
4613 | 5334 |
4614 Lfwd: | 5335 Lfwd: |
4615 error(loc, "forward reference of %s.%s", toChars(), ident->toChars()); | 5336 error(loc, "forward reference of %s.%s", toChars(), ident->toChars()); |
4616 return new IntegerExp(0, 0, this); | 5337 return new ErrorExp(); |
4617 } | 5338 } |
4618 | 5339 |
4619 int TypeEnum::isintegral() | 5340 int TypeEnum::isintegral() |
4620 { | 5341 { |
4621 return 1; | 5342 return 1; |
4669 // Initialize to first member of enum | 5390 // Initialize to first member of enum |
4670 //printf("%s\n", sym->defaultval->type->toChars()); | 5391 //printf("%s\n", sym->defaultval->type->toChars()); |
4671 if (!sym->defaultval) | 5392 if (!sym->defaultval) |
4672 { | 5393 { |
4673 error(loc, "forward reference of %s.init", toChars()); | 5394 error(loc, "forward reference of %s.init", toChars()); |
4674 return new IntegerExp(0, 0, this); | 5395 return new ErrorExp(); |
4675 } | 5396 } |
4676 return sym->defaultval; | 5397 return sym->defaultval; |
4677 } | 5398 } |
4678 | 5399 |
4679 int TypeEnum::isZeroInit() | 5400 int TypeEnum::isZeroInit(Loc loc) |
4680 { | 5401 { |
5402 if (!sym->defaultval) | |
5403 { | |
5404 #ifdef DEBUG | |
5405 printf("3: "); | |
5406 #endif | |
5407 error(loc, "enum %s is forward referenced", sym->toChars()); | |
5408 return 0; | |
5409 } | |
4681 return sym->defaultval->isBool(FALSE); | 5410 return sym->defaultval->isBool(FALSE); |
4682 } | 5411 } |
4683 | 5412 |
4684 int TypeEnum::hasPointers() | 5413 int TypeEnum::hasPointers() |
4685 { | 5414 { |
4737 return this; | 5466 return this; |
4738 else | 5467 else |
4739 return mutableOf(); | 5468 return mutableOf(); |
4740 } | 5469 } |
4741 | 5470 |
4742 void TypeTypedef::toDecoBuffer(OutBuffer *buf, int flag) | 5471 void TypeTypedef::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) |
4743 { | 5472 { |
4744 Type::toDecoBuffer(buf, flag); | 5473 Type::toDecoBuffer(buf, flag, mangle); |
4745 const char *name = sym->mangle(); | 5474 const char *name = sym->mangle(); |
4746 buf->printf("%s", name); | 5475 buf->printf("%s", name); |
4747 } | 5476 } |
4748 | 5477 |
4749 void TypeTypedef::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | 5478 void TypeTypedef::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) |
4837 return Type::terror; | 5566 return Type::terror; |
4838 } | 5567 } |
4839 sym->inuse = 1; | 5568 sym->inuse = 1; |
4840 Type *t = sym->basetype->toBasetype(); | 5569 Type *t = sym->basetype->toBasetype(); |
4841 sym->inuse = 0; | 5570 sym->inuse = 0; |
4842 if (mod == MODconst && !t->isInvariant()) | 5571 t = t->addMod(mod); |
4843 t = t->constOf(); | |
4844 else if (mod == MODinvariant) | |
4845 t = t->invariantOf(); | |
4846 return t; | 5572 return t; |
4847 } | 5573 } |
4848 | 5574 |
4849 MATCH TypeTypedef::implicitConvTo(Type *to) | 5575 MATCH TypeTypedef::implicitConvTo(Type *to) |
4850 { MATCH m; | 5576 { MATCH m; |
4894 bt = tsa->next->toBasetype(); | 5620 bt = tsa->next->toBasetype(); |
4895 } | 5621 } |
4896 return e; | 5622 return e; |
4897 } | 5623 } |
4898 | 5624 |
4899 int TypeTypedef::isZeroInit() | 5625 int TypeTypedef::isZeroInit(Loc loc) |
4900 { | 5626 { |
4901 if (sym->init) | 5627 if (sym->init) |
4902 { | 5628 { |
4903 if (sym->init->isVoidInitializer()) | 5629 if (sym->init->isVoidInitializer()) |
4904 return 1; // initialize voids to 0 | 5630 return 1; // initialize voids to 0 |
4911 { | 5637 { |
4912 sym->error("circular definition"); | 5638 sym->error("circular definition"); |
4913 sym->basetype = Type::terror; | 5639 sym->basetype = Type::terror; |
4914 } | 5640 } |
4915 sym->inuse = 1; | 5641 sym->inuse = 1; |
4916 int result = sym->basetype->isZeroInit(); | 5642 int result = sym->basetype->isZeroInit(loc); |
4917 sym->inuse = 0; | 5643 sym->inuse = 0; |
4918 return result; | 5644 return result; |
4919 } | 5645 } |
4920 | 5646 |
4921 int TypeTypedef::hasPointers() | 5647 int TypeTypedef::hasPointers() |
4982 Dsymbol *TypeStruct::toDsymbol(Scope *sc) | 5708 Dsymbol *TypeStruct::toDsymbol(Scope *sc) |
4983 { | 5709 { |
4984 return sym; | 5710 return sym; |
4985 } | 5711 } |
4986 | 5712 |
4987 void TypeStruct::toDecoBuffer(OutBuffer *buf, int flag) | 5713 void TypeStruct::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) |
4988 { | 5714 { |
4989 const char *name = sym->mangle(); | 5715 const char *name = sym->mangle(); |
4990 //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", toChars(), name); | 5716 //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", toChars(), name); |
4991 Type::toDecoBuffer(buf, flag); | 5717 Type::toDecoBuffer(buf, flag, mangle); |
4992 buf->printf("%s", name); | 5718 buf->printf("%s", name); |
4993 } | 5719 } |
4994 | 5720 |
4995 void TypeStruct::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | 5721 void TypeStruct::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) |
4996 { | 5722 { |
5006 } | 5732 } |
5007 | 5733 |
5008 Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident) | 5734 Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident) |
5009 { unsigned offset; | 5735 { unsigned offset; |
5010 | 5736 |
5011 Expression *b; | |
5012 VarDeclaration *v; | 5737 VarDeclaration *v; |
5013 Dsymbol *s; | 5738 Dsymbol *s; |
5014 DotVarExp *de; | 5739 DotVarExp *de; |
5015 Declaration *d; | 5740 Declaration *d; |
5016 | 5741 |
5018 printf("TypeStruct::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); | 5743 printf("TypeStruct::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); |
5019 #endif | 5744 #endif |
5020 if (!sym->members) | 5745 if (!sym->members) |
5021 { | 5746 { |
5022 error(e->loc, "struct %s is forward referenced", sym->toChars()); | 5747 error(e->loc, "struct %s is forward referenced", sym->toChars()); |
5023 return new IntegerExp(e->loc, 0, Type::tint32); | 5748 return new ErrorExp(); |
5024 } | 5749 } |
5025 | 5750 |
5026 /* If e.tupleof | 5751 /* If e.tupleof |
5027 */ | 5752 */ |
5028 if (ident == Id::tupleof) | 5753 if (ident == Id::tupleof) |
5070 ident != Id::init && | 5795 ident != Id::init && |
5071 ident != Id::mangleof && | 5796 ident != Id::mangleof && |
5072 ident != Id::stringof && | 5797 ident != Id::stringof && |
5073 ident != Id::offsetof) | 5798 ident != Id::offsetof) |
5074 { | 5799 { |
5800 /* See if we should forward to the alias this. | |
5801 */ | |
5802 if (sym->aliasthis) | |
5803 { /* Rewrite e.ident as: | |
5804 * e.aliasthis.ident | |
5805 */ | |
5806 e = new DotIdExp(e->loc, e, sym->aliasthis->ident); | |
5807 e = new DotIdExp(e->loc, e, ident); | |
5808 return e->semantic(sc); | |
5809 } | |
5810 | |
5075 /* Look for overloaded opDot() to see if we should forward request | 5811 /* Look for overloaded opDot() to see if we should forward request |
5076 * to it. | 5812 * to it. |
5077 */ | 5813 */ |
5078 Dsymbol *fd = search_function(sym, Id::opDot); | 5814 Dsymbol *fd = search_function(sym, Id::opDot); |
5079 if (fd) | 5815 if (fd) |
5141 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, ti)); | 5877 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, ti)); |
5142 de->type = e->type; | 5878 de->type = e->type; |
5143 return de; | 5879 return de; |
5144 } | 5880 } |
5145 | 5881 |
5882 Import *timp = s->isImport(); | |
5883 if (timp) | |
5884 { | |
5885 e = new DsymbolExp(e->loc, s, 0); | |
5886 e = e->semantic(sc); | |
5887 return e; | |
5888 } | |
5889 | |
5890 OverloadSet *o = s->isOverloadSet(); | |
5891 if (o) | |
5892 { /* We really should allow this, triggered by: | |
5893 * template c() | |
5894 * { | |
5895 * void a(); | |
5896 * void b () { this.a(); } | |
5897 * } | |
5898 * struct S | |
5899 * { | |
5900 * mixin c; | |
5901 * mixin c; | |
5902 * } | |
5903 * alias S e; | |
5904 */ | |
5905 error(e->loc, "overload set for %s.%s not allowed in struct declaration", e->toChars(), ident->toChars()); | |
5906 return new ErrorExp(); | |
5907 } | |
5908 | |
5146 d = s->isDeclaration(); | 5909 d = s->isDeclaration(); |
5147 #ifdef DEBUG | 5910 #ifdef DEBUG |
5148 if (!d) | 5911 if (!d) |
5149 printf("d = %s '%s'\n", s->kind(), s->toChars()); | 5912 printf("d = %s '%s'\n", s->kind(), s->toChars()); |
5150 #endif | 5913 #endif |
5151 assert(d); | 5914 assert(d); |
5152 | 5915 |
5153 if (e->op == TOKtype) | 5916 if (e->op == TOKtype) |
5154 { FuncDeclaration *fd = sc->func; | 5917 { FuncDeclaration *fd = sc->func; |
5155 | 5918 |
5156 if (d->needThis() && fd && fd->vthis) | 5919 if (d->isTupleDeclaration()) |
5157 { | 5920 { |
5158 e = new DotVarExp(e->loc, new ThisExp(e->loc), d); | 5921 e = new TupleExp(e->loc, d->isTupleDeclaration()); |
5159 e = e->semantic(sc); | 5922 e = e->semantic(sc); |
5160 return e; | 5923 return e; |
5161 } | 5924 } |
5162 if (d->isTupleDeclaration()) | 5925 if (d->needThis() && fd && fd->vthis) |
5163 { | 5926 { |
5164 e = new TupleExp(e->loc, d->isTupleDeclaration()); | 5927 e = new DotVarExp(e->loc, new ThisExp(e->loc), d); |
5165 e = e->semantic(sc); | 5928 e = e->semantic(sc); |
5166 return e; | 5929 return e; |
5167 } | 5930 } |
5168 return new VarExp(e->loc, d, 1); | 5931 return new VarExp(e->loc, d, 1); |
5169 } | 5932 } |
5185 if (v->toParent() != sym) | 5948 if (v->toParent() != sym) |
5186 sym->error(e->loc, "'%s' is not a member", v->toChars()); | 5949 sym->error(e->loc, "'%s' is not a member", v->toChars()); |
5187 | 5950 |
5188 // *(&e + offset) | 5951 // *(&e + offset) |
5189 accessCheck(e->loc, sc, e, d); | 5952 accessCheck(e->loc, sc, e, d); |
5190 | 5953 #if 0 |
5191 // LDC we don't want dot exprs turned into pointer arithmetic. it complicates things for no apparent gain | 5954 Expression *b = new AddrExp(e->loc, e); |
5192 #ifndef IN_LLVM | |
5193 b = new AddrExp(e->loc, e); | |
5194 b->type = e->type->pointerTo(); | 5955 b->type = e->type->pointerTo(); |
5195 b = new AddExp(e->loc, b, new IntegerExp(e->loc, v->offset, Type::tint32)); | 5956 b = new AddExp(e->loc, b, new IntegerExp(e->loc, v->offset, Type::tint32)); |
5196 b->type = v->type->pointerTo(); | 5957 b->type = v->type->pointerTo(); |
5197 b = new PtrExp(e->loc, b); | 5958 b = new PtrExp(e->loc, b); |
5198 b->type = v->type; | 5959 b->type = v->type->addMod(e->type->mod); |
5199 if (e->type->isConst()) | |
5200 b->type = b->type->constOf(); | |
5201 else if (e->type->isInvariant()) | |
5202 b->type = b->type->invariantOf(); | |
5203 return b; | 5960 return b; |
5204 #endif | 5961 #endif |
5205 } | 5962 } |
5206 | 5963 |
5207 de = new DotVarExp(e->loc, e, d); | 5964 de = new DotVarExp(e->loc, e, d); |
5224 assert(d); | 5981 assert(d); |
5225 d->type = this; | 5982 d->type = this; |
5226 return new VarExp(sym->loc, d); | 5983 return new VarExp(sym->loc, d); |
5227 } | 5984 } |
5228 | 5985 |
5229 int TypeStruct::isZeroInit() | 5986 int TypeStruct::isZeroInit(Loc loc) |
5230 { | 5987 { |
5231 return sym->zeroInit; | 5988 return sym->zeroInit; |
5232 } | 5989 } |
5233 | 5990 |
5234 int TypeStruct::checkBoolean() | 5991 int TypeStruct::checkBoolean() |
5255 | 6012 |
5256 sym->size(0); // give error for forward references | 6013 sym->size(0); // give error for forward references |
5257 for (size_t i = 0; i < s->fields.dim; i++) | 6014 for (size_t i = 0; i < s->fields.dim; i++) |
5258 { | 6015 { |
5259 Dsymbol *sm = (Dsymbol *)s->fields.data[i]; | 6016 Dsymbol *sm = (Dsymbol *)s->fields.data[i]; |
5260 if (sm->hasPointers()) | 6017 Declaration *d = sm->isDeclaration(); |
6018 if (d->storage_class & STCref || d->hasPointers()) | |
5261 return TRUE; | 6019 return TRUE; |
5262 } | 6020 } |
5263 return FALSE; | 6021 return FALSE; |
5264 } | 6022 } |
5265 | 6023 |
5281 { Dsymbol *s = (Dsymbol *)sym->fields.data[i]; | 6039 { Dsymbol *s = (Dsymbol *)sym->fields.data[i]; |
5282 VarDeclaration *v = s->isVarDeclaration(); | 6040 VarDeclaration *v = s->isVarDeclaration(); |
5283 assert(v && v->storage_class & STCfield); | 6041 assert(v && v->storage_class & STCfield); |
5284 | 6042 |
5285 // 'from' type | 6043 // 'from' type |
5286 Type *tvf = v->type; | 6044 Type *tvf = v->type->addMod(mod); |
5287 if (mod == MODconst) | |
5288 tvf = tvf->constOf(); | |
5289 else if (mod == MODinvariant) | |
5290 tvf = tvf->invariantOf(); | |
5291 | 6045 |
5292 // 'to' type | 6046 // 'to' type |
5293 Type *tv = v->type; | 6047 Type *tv = v->type->castMod(to->mod); |
5294 if (to->mod == 0) | |
5295 tv = tv->mutableOf(); | |
5296 else | |
5297 { assert(to->mod == MODinvariant); | |
5298 tv = tv->invariantOf(); | |
5299 } | |
5300 | 6048 |
5301 //printf("\t%s => %s, match = %d\n", v->type->toChars(), tv->toChars(), tvf->implicitConvTo(tv)); | 6049 //printf("\t%s => %s, match = %d\n", v->type->toChars(), tv->toChars(), tvf->implicitConvTo(tv)); |
5302 if (tvf->implicitConvTo(tv) < MATCHconst) | 6050 if (tvf->implicitConvTo(tv) < MATCHconst) |
5303 return MATCHnomatch; | 6051 return MATCHnomatch; |
5304 } | 6052 } |
5305 m = MATCHconst; | 6053 m = MATCHconst; |
5306 } | 6054 } |
5307 } | 6055 } |
5308 } | 6056 } |
6057 else if (sym->aliasthis) | |
6058 { | |
6059 m = MATCHnomatch; | |
6060 Declaration *d = sym->aliasthis->isDeclaration(); | |
6061 if (d) | |
6062 { assert(d->type); | |
6063 Type *t = d->type->addMod(mod); | |
6064 m = t->implicitConvTo(to); | |
6065 } | |
6066 } | |
5309 else | 6067 else |
5310 m = MATCHnomatch; // no match | 6068 m = MATCHnomatch; // no match |
5311 return m; | 6069 return m; |
5312 } | 6070 } |
5313 | 6071 |
5363 Dsymbol *TypeClass::toDsymbol(Scope *sc) | 6121 Dsymbol *TypeClass::toDsymbol(Scope *sc) |
5364 { | 6122 { |
5365 return sym; | 6123 return sym; |
5366 } | 6124 } |
5367 | 6125 |
5368 void TypeClass::toDecoBuffer(OutBuffer *buf, int flag) | 6126 void TypeClass::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) |
5369 { | 6127 { |
5370 const char *name = sym->mangle(); | 6128 const char *name = sym->mangle(); |
5371 //printf("TypeClass::toDecoBuffer('%s' flag=%d mod=%x) = '%s'\n", toChars(), flag, mod, name); | 6129 //printf("TypeClass::toDecoBuffer('%s' flag=%d mod=%x) = '%s'\n", toChars(), flag, mod, name); |
5372 Type::toDecoBuffer(buf, flag); | 6130 Type::toDecoBuffer(buf, flag, mangle); |
5373 buf->printf("%s", name); | 6131 buf->printf("%s", name); |
5374 } | 6132 } |
5375 | 6133 |
5376 void TypeClass::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | 6134 void TypeClass::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) |
5377 { | 6135 { |
5566 ident != Id::init && | 6324 ident != Id::init && |
5567 ident != Id::mangleof && | 6325 ident != Id::mangleof && |
5568 ident != Id::stringof && | 6326 ident != Id::stringof && |
5569 ident != Id::offsetof) | 6327 ident != Id::offsetof) |
5570 { | 6328 { |
6329 /* See if we should forward to the alias this. | |
6330 */ | |
6331 if (sym->aliasthis) | |
6332 { /* Rewrite e.ident as: | |
6333 * e.aliasthis.ident | |
6334 */ | |
6335 e = new DotIdExp(e->loc, e, sym->aliasthis->ident); | |
6336 e = new DotIdExp(e->loc, e, ident); | |
6337 return e->semantic(sc); | |
6338 } | |
6339 | |
5571 /* Look for overloaded opDot() to see if we should forward request | 6340 /* Look for overloaded opDot() to see if we should forward request |
5572 * to it. | 6341 * to it. |
5573 */ | 6342 */ |
5574 Dsymbol *fd = search_function(sym, Id::opDot); | 6343 Dsymbol *fd = search_function(sym, Id::opDot); |
5575 if (fd) | 6344 if (fd) |
5639 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, ti)); | 6408 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, ti)); |
5640 de->type = e->type; | 6409 de->type = e->type; |
5641 return de; | 6410 return de; |
5642 } | 6411 } |
5643 | 6412 |
6413 OverloadSet *o = s->isOverloadSet(); | |
6414 if (o) | |
6415 { /* We really should allow this | |
6416 */ | |
6417 error(e->loc, "overload set for %s.%s not allowed in struct declaration", e->toChars(), ident->toChars()); | |
6418 return new ErrorExp(); | |
6419 } | |
6420 | |
5644 Declaration *d = s->isDeclaration(); | 6421 Declaration *d = s->isDeclaration(); |
5645 if (!d) | 6422 if (!d) |
5646 { | 6423 { |
5647 e->error("%s.%s is not a declaration", e->toChars(), ident->toChars()); | 6424 e->error("%s.%s is not a declaration", e->toChars(), ident->toChars()); |
5648 return new IntegerExp(e->loc, 1, Type::tint32); | 6425 return new ErrorExp(); |
5649 } | 6426 } |
5650 | 6427 |
5651 if (e->op == TOKtype) | 6428 if (e->op == TOKtype) |
5652 { | 6429 { |
5653 /* It's: | 6430 /* It's: |
5654 * Class.d | 6431 * Class.d |
5655 */ | 6432 */ |
5656 if (d->needThis() && (hasThis(sc) || !d->isFuncDeclaration())) | 6433 if (d->isTupleDeclaration()) |
6434 { | |
6435 e = new TupleExp(e->loc, d->isTupleDeclaration()); | |
6436 e = e->semantic(sc); | |
6437 return e; | |
6438 } | |
6439 else if (d->needThis() && (hasThis(sc) || !d->isFuncDeclaration())) | |
5657 { | 6440 { |
5658 if (sc->func) | 6441 if (sc->func) |
5659 { | 6442 { |
5660 ClassDeclaration *thiscd; | 6443 ClassDeclaration *thiscd; |
5661 thiscd = sc->func->toParent()->isClassDeclaration(); | 6444 thiscd = sc->func->toParent()->isClassDeclaration(); |
5683 */ | 6466 */ |
5684 DotVarExp *de = new DotVarExp(e->loc, new ThisExp(e->loc), d); | 6467 DotVarExp *de = new DotVarExp(e->loc, new ThisExp(e->loc), d); |
5685 e = de->semantic(sc); | 6468 e = de->semantic(sc); |
5686 return e; | 6469 return e; |
5687 } | 6470 } |
5688 else if (d->isTupleDeclaration()) | |
5689 { | |
5690 e = new TupleExp(e->loc, d->isTupleDeclaration()); | |
5691 e = e->semantic(sc); | |
5692 return e; | |
5693 } | |
5694 else | 6471 else |
5695 { | 6472 { |
5696 VarExp *ve = new VarExp(e->loc, d, 1); | 6473 VarExp *ve = new VarExp(e->loc, d, 1); |
5697 return ve; | 6474 return ve; |
5698 } | 6475 } |
5764 // Allow conversion to (void *) | 6541 // Allow conversion to (void *) |
5765 if (to->ty == Tpointer && ((TypePointer *)to)->next->ty == Tvoid) | 6542 if (to->ty == Tpointer && ((TypePointer *)to)->next->ty == Tvoid) |
5766 return MATCHconvert; | 6543 return MATCHconvert; |
5767 } | 6544 } |
5768 | 6545 |
5769 return MATCHnomatch; | 6546 m = MATCHnomatch; |
6547 if (sym->aliasthis) | |
6548 { | |
6549 Declaration *d = sym->aliasthis->isDeclaration(); | |
6550 if (d) | |
6551 { assert(d->type); | |
6552 Type *t = d->type->addMod(mod); | |
6553 m = t->implicitConvTo(to); | |
6554 } | |
6555 } | |
6556 | |
6557 return m; | |
5770 } | 6558 } |
5771 | 6559 |
5772 MATCH TypeClass::constConv(Type *to) | 6560 MATCH TypeClass::constConv(Type *to) |
5773 { | 6561 { |
5774 if (equals(to)) | 6562 if (equals(to)) |
5793 e = new NullExp(loc); | 6581 e = new NullExp(loc); |
5794 e->type = this; | 6582 e->type = this; |
5795 return e; | 6583 return e; |
5796 } | 6584 } |
5797 | 6585 |
5798 int TypeClass::isZeroInit() | 6586 int TypeClass::isZeroInit(Loc loc) |
5799 { | 6587 { |
5800 return 1; | 6588 return 1; |
5801 } | 6589 } |
5802 | 6590 |
5803 int TypeClass::checkBoolean() | 6591 int TypeClass::checkBoolean() |
5937 void TypeTuple::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | 6725 void TypeTuple::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) |
5938 { | 6726 { |
5939 Argument::argsToCBuffer(buf, hgs, arguments, 0); | 6727 Argument::argsToCBuffer(buf, hgs, arguments, 0); |
5940 } | 6728 } |
5941 | 6729 |
5942 void TypeTuple::toDecoBuffer(OutBuffer *buf, int flag) | 6730 void TypeTuple::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) |
5943 { | 6731 { |
5944 //printf("TypeTuple::toDecoBuffer() this = %p, %s\n", this, toChars()); | 6732 //printf("TypeTuple::toDecoBuffer() this = %p, %s\n", this, toChars()); |
5945 Type::toDecoBuffer(buf, flag); | 6733 Type::toDecoBuffer(buf, flag, mangle); |
5946 OutBuffer buf2; | 6734 OutBuffer buf2; |
5947 Argument::argsToDecoBuffer(&buf2, arguments); | 6735 Argument::argsToDecoBuffer(&buf2, arguments, mangle); |
5948 unsigned len = buf2.offset; | 6736 unsigned len = buf2.offset; |
5949 buf->printf("%d%.*s", len, len, (char *)buf2.extractData()); | 6737 buf->printf("%d%.*s", len, len, (char *)buf2.extractData()); |
5950 } | 6738 } |
5951 | 6739 |
5952 Expression *TypeTuple::getProperty(Loc loc, Identifier *ident) | 6740 Expression *TypeTuple::getProperty(Loc loc, Identifier *ident) |
5960 e = new IntegerExp(loc, arguments->dim, Type::tsize_t); | 6748 e = new IntegerExp(loc, arguments->dim, Type::tsize_t); |
5961 } | 6749 } |
5962 else | 6750 else |
5963 { | 6751 { |
5964 error(loc, "no property '%s' for tuple '%s'", ident->toChars(), toChars()); | 6752 error(loc, "no property '%s' for tuple '%s'", ident->toChars(), toChars()); |
5965 e = new IntegerExp(loc, 1, Type::tint32); | 6753 e = new ErrorExp(); |
5966 } | 6754 } |
5967 return e; | 6755 return e; |
5968 } | 6756 } |
5969 | 6757 |
5970 /***************************** TypeSlice *****************************/ | 6758 /***************************** TypeSlice *****************************/ |
5988 | 6776 |
5989 Type *TypeSlice::semantic(Loc loc, Scope *sc) | 6777 Type *TypeSlice::semantic(Loc loc, Scope *sc) |
5990 { | 6778 { |
5991 //printf("TypeSlice::semantic() %s\n", toChars()); | 6779 //printf("TypeSlice::semantic() %s\n", toChars()); |
5992 next = next->semantic(loc, sc); | 6780 next = next->semantic(loc, sc); |
5993 if (mod == MODconst && !next->isInvariant()) | 6781 transitive(); |
5994 next = next->constOf(); | |
5995 else if (mod == MODinvariant) | |
5996 next = next->invariantOf(); | |
5997 //printf("next: %s\n", next->toChars()); | 6782 //printf("next: %s\n", next->toChars()); |
5998 | 6783 |
5999 Type *tbn = next->toBasetype(); | 6784 Type *tbn = next->toBasetype(); |
6000 if (tbn->ty != Ttuple) | 6785 if (tbn->ty != Ttuple) |
6001 { error(loc, "can only slice tuple types, not %s", tbn->toChars()); | 6786 { error(loc, "can only slice tuple types, not %s", tbn->toChars()); |
6010 upr = semanticLength(sc, tbn, upr); | 6795 upr = semanticLength(sc, tbn, upr); |
6011 upr = upr->optimize(WANTvalue); | 6796 upr = upr->optimize(WANTvalue); |
6012 uinteger_t i2 = upr->toUInteger(); | 6797 uinteger_t i2 = upr->toUInteger(); |
6013 | 6798 |
6014 if (!(i1 <= i2 && i2 <= tt->arguments->dim)) | 6799 if (!(i1 <= i2 && i2 <= tt->arguments->dim)) |
6015 { error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, tt->arguments->dim); | 6800 { error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, tt->arguments->dim); |
6016 return Type::terror; | 6801 return Type::terror; |
6017 } | 6802 } |
6018 | 6803 |
6019 Arguments *args = new Arguments; | 6804 Arguments *args = new Arguments; |
6020 args->reserve(i2 - i1); | 6805 args->reserve(i2 - i1); |
6055 uinteger_t i2 = upr->toUInteger(); | 6840 uinteger_t i2 = upr->toUInteger(); |
6056 | 6841 |
6057 sc = sc->pop(); | 6842 sc = sc->pop(); |
6058 | 6843 |
6059 if (!(i1 <= i2 && i2 <= td->objects->dim)) | 6844 if (!(i1 <= i2 && i2 <= td->objects->dim)) |
6060 { error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim); | 6845 { error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, td->objects->dim); |
6061 goto Ldefault; | 6846 goto Ldefault; |
6062 } | 6847 } |
6063 | 6848 |
6064 if (i1 == 0 && i2 == td->objects->dim) | 6849 if (i1 == 0 && i2 == td->objects->dim) |
6065 { | 6850 { |
6196 else if (arg->storageClass & STCalias) | 6981 else if (arg->storageClass & STCalias) |
6197 buf->writestring("alias "); | 6982 buf->writestring("alias "); |
6198 else if (arg->storageClass & STCauto) | 6983 else if (arg->storageClass & STCauto) |
6199 buf->writestring("auto "); | 6984 buf->writestring("auto "); |
6200 | 6985 |
6201 if (arg->storageClass & STCscope) | 6986 unsigned stc = arg->storageClass; |
6202 buf->writestring("scope "); | 6987 if (arg->type && arg->type->mod & MODshared) |
6203 | 6988 stc &= ~STCshared; |
6204 if (arg->storageClass & STCconst) | 6989 |
6205 buf->writestring("const "); | 6990 StorageClassDeclaration::stcToCBuffer(buf, |
6206 if (arg->storageClass & STCinvariant) | 6991 stc & (STCconst | STCimmutable | STCshared | STCscope)); |
6207 buf->writestring("invariant "); | |
6208 if (arg->storageClass & STCshared) | |
6209 buf->writestring("shared "); | |
6210 | 6992 |
6211 argbuf.reset(); | 6993 argbuf.reset(); |
6212 if (arg->storageClass & STCalias) | 6994 if (arg->storageClass & STCalias) |
6213 { if (arg->ident) | 6995 { if (arg->ident) |
6214 argbuf.writestring(arg->ident->toChars()); | 6996 argbuf.writestring(arg->ident->toChars()); |
6231 } | 7013 } |
6232 buf->writeByte(')'); | 7014 buf->writeByte(')'); |
6233 } | 7015 } |
6234 | 7016 |
6235 | 7017 |
6236 void Argument::argsToDecoBuffer(OutBuffer *buf, Arguments *arguments) | 7018 void Argument::argsToDecoBuffer(OutBuffer *buf, Arguments *arguments, bool mangle) |
6237 { | 7019 { |
6238 //printf("Argument::argsToDecoBuffer()\n"); | 7020 //printf("Argument::argsToDecoBuffer()\n"); |
6239 | 7021 |
6240 // Write argument types | 7022 // Write argument types |
6241 if (arguments) | 7023 if (arguments) |
6242 { | 7024 { |
6243 size_t dim = Argument::dim(arguments); | 7025 size_t dim = Argument::dim(arguments); |
6244 for (size_t i = 0; i < dim; i++) | 7026 for (size_t i = 0; i < dim; i++) |
6245 { | 7027 { |
6246 Argument *arg = Argument::getNth(arguments, i); | 7028 Argument *arg = Argument::getNth(arguments, i); |
6247 arg->toDecoBuffer(buf); | 7029 arg->toDecoBuffer(buf, mangle); |
6248 } | 7030 } |
6249 } | 7031 } |
6250 } | 7032 } |
6251 | 7033 |
6252 | 7034 |
6299 } | 7081 } |
6300 } | 7082 } |
6301 return NULL; | 7083 return NULL; |
6302 } | 7084 } |
6303 | 7085 |
6304 void Argument::toDecoBuffer(OutBuffer *buf) | 7086 void Argument::toDecoBuffer(OutBuffer *buf, bool mangle) |
6305 { | 7087 { |
6306 if (storageClass & STCscope) | 7088 if (storageClass & STCscope) |
6307 buf->writeByte('M'); | 7089 buf->writeByte('M'); |
6308 switch (storageClass & (STCin | STCout | STCref | STClazy)) | 7090 switch (storageClass & (STCin | STCout | STCref | STClazy)) |
6309 { case 0: | 7091 { case 0: |
6329 if (type->toBasetype()->ty == Tclass) | 7111 if (type->toBasetype()->ty == Tclass) |
6330 mod = 0; | 7112 mod = 0; |
6331 type->toDecoBuffer(buf, mod); | 7113 type->toDecoBuffer(buf, mod); |
6332 #else | 7114 #else |
6333 //type->toHeadMutable()->toDecoBuffer(buf, 0); | 7115 //type->toHeadMutable()->toDecoBuffer(buf, 0); |
6334 type->toDecoBuffer(buf, 0); | 7116 type->toDecoBuffer(buf, 0, mangle); |
6335 #endif | 7117 #endif |
6336 } | 7118 } |
6337 | 7119 |
6338 /*************************************** | 7120 /*************************************** |
6339 * Determine number of arguments, folding in tuples. | 7121 * Determine number of arguments, folding in tuples. |