Mercurial > projects > ldc
comparison dmd2/attrib.c @ 1577:e4f7b5d9c68a
DMD 2.032 Merge.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Tue, 08 Sep 2009 10:07:56 +0100 |
parents | 54b3c1394d62 |
children |
comparison
equal
deleted
inserted
replaced
1576:4551475bc6b6 | 1577:e4f7b5d9c68a |
---|---|
75 } | 75 } |
76 } | 76 } |
77 return m; | 77 return m; |
78 } | 78 } |
79 | 79 |
80 void AttribDeclaration::semanticNewSc(Scope *sc, | 80 void AttribDeclaration::setScopeNewSc(Scope *sc, |
81 unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection, | 81 unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection, |
82 unsigned structalign) | 82 unsigned structalign) |
83 { | 83 { |
84 if (decl) | 84 if (decl) |
85 { | 85 { |
100 newsc->structalign = structalign; | 100 newsc->structalign = structalign; |
101 } | 101 } |
102 for (unsigned i = 0; i < decl->dim; i++) | 102 for (unsigned i = 0; i < decl->dim; i++) |
103 { Dsymbol *s = (Dsymbol *)decl->data[i]; | 103 { Dsymbol *s = (Dsymbol *)decl->data[i]; |
104 | 104 |
105 s->setScope(newsc); // yes, the only difference from semanticNewSc() | |
106 } | |
107 if (newsc != sc) | |
108 { | |
109 sc->offset = newsc->offset; | |
110 newsc->pop(); | |
111 } | |
112 } | |
113 } | |
114 | |
115 void AttribDeclaration::semanticNewSc(Scope *sc, | |
116 unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection, | |
117 unsigned structalign) | |
118 { | |
119 if (decl) | |
120 { | |
121 Scope *newsc = sc; | |
122 if (stc != sc->stc || | |
123 linkage != sc->linkage || | |
124 protection != sc->protection || | |
125 explicitProtection != sc->explicitProtection || | |
126 structalign != sc->structalign) | |
127 { | |
128 // create new one for changes | |
129 newsc = new Scope(*sc); | |
130 newsc->flags &= ~SCOPEfree; | |
131 newsc->stc = stc; | |
132 newsc->linkage = linkage; | |
133 newsc->protection = protection; | |
134 newsc->explicitProtection = explicitProtection; | |
135 newsc->structalign = structalign; | |
136 } | |
137 for (unsigned i = 0; i < decl->dim; i++) | |
138 { Dsymbol *s = (Dsymbol *)decl->data[i]; | |
139 | |
105 s->semantic(newsc); | 140 s->semantic(newsc); |
106 } | 141 } |
107 if (newsc != sc) | 142 if (newsc != sc) |
108 { | 143 { |
109 sc->offset = newsc->offset; | 144 sc->offset = newsc->offset; |
338 assert(!s); | 373 assert(!s); |
339 scd = new StorageClassDeclaration(stc, Dsymbol::arraySyntaxCopy(decl)); | 374 scd = new StorageClassDeclaration(stc, Dsymbol::arraySyntaxCopy(decl)); |
340 return scd; | 375 return scd; |
341 } | 376 } |
342 | 377 |
343 void StorageClassDeclaration::semantic(Scope *sc) | 378 void StorageClassDeclaration::setScope(Scope *sc) |
344 { | 379 { |
345 if (decl) | 380 if (decl) |
346 { | 381 { |
347 #if 1 | |
348 unsigned scstc = sc->stc; | 382 unsigned scstc = sc->stc; |
349 | 383 |
350 /* These sets of storage classes are mutually exclusive, | 384 /* These sets of storage classes are mutually exclusive, |
351 * so choose the innermost or most recent one. | 385 * so choose the innermost or most recent one. |
352 */ | 386 */ |
358 scstc &= ~(STCconst | STCimmutable | STCmanifest); | 392 scstc &= ~(STCconst | STCimmutable | STCmanifest); |
359 if (stc & (STCgshared | STCshared | STCtls)) | 393 if (stc & (STCgshared | STCshared | STCtls)) |
360 scstc &= ~(STCgshared | STCshared | STCtls); | 394 scstc &= ~(STCgshared | STCshared | STCtls); |
361 scstc |= stc; | 395 scstc |= stc; |
362 | 396 |
363 semanticNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign); | 397 setScopeNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign); |
364 #else | 398 } |
365 unsigned stc_save = sc->stc; | 399 } |
400 | |
401 void StorageClassDeclaration::semantic(Scope *sc) | |
402 { | |
403 if (decl) | |
404 { | |
405 unsigned scstc = sc->stc; | |
366 | 406 |
367 /* These sets of storage classes are mutually exclusive, | 407 /* These sets of storage classes are mutually exclusive, |
368 * so choose the innermost or most recent one. | 408 * so choose the innermost or most recent one. |
369 */ | 409 */ |
370 if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) | 410 if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) |
371 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); | 411 scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); |
372 if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared)) | 412 if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared)) |
373 sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared); | 413 scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared); |
374 if (stc & (STCconst | STCimmutable | STCmanifest)) | 414 if (stc & (STCconst | STCimmutable | STCmanifest)) |
375 sc->stc &= ~(STCconst | STCimmutable | STCmanifest); | 415 scstc &= ~(STCconst | STCimmutable | STCmanifest); |
376 if (stc & (STCgshared | STCshared | STCtls)) | 416 if (stc & (STCgshared | STCshared | STCtls)) |
377 sc->stc &= ~(STCgshared | STCshared | STCtls); | 417 scstc &= ~(STCgshared | STCshared | STCtls); |
378 sc->stc |= stc; | 418 scstc |= stc; |
379 for (unsigned i = 0; i < decl->dim; i++) | 419 |
380 { | 420 semanticNewSc(sc, scstc, sc->linkage, sc->protection, sc->explicitProtection, sc->structalign); |
381 Dsymbol *s = (Dsymbol *)decl->data[i]; | |
382 | |
383 s->semantic(sc); | |
384 } | |
385 sc->stc = stc_save; | |
386 #endif | |
387 } | 421 } |
388 } | 422 } |
389 | 423 |
390 void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc) | 424 void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc) |
391 { | 425 { |
400 { STCauto, TOKauto }, | 434 { STCauto, TOKauto }, |
401 { STCscope, TOKscope }, | 435 { STCscope, TOKscope }, |
402 { STCstatic, TOKstatic }, | 436 { STCstatic, TOKstatic }, |
403 { STCextern, TOKextern }, | 437 { STCextern, TOKextern }, |
404 { STCconst, TOKconst }, | 438 { STCconst, TOKconst }, |
405 { STCimmutable, TOKimmutable }, | |
406 { STCshared, TOKshared }, | |
407 { STCfinal, TOKfinal }, | 439 { STCfinal, TOKfinal }, |
408 { STCabstract, TOKabstract }, | 440 { STCabstract, TOKabstract }, |
409 { STCsynchronized, TOKsynchronized }, | 441 { STCsynchronized, TOKsynchronized }, |
410 { STCdeprecated, TOKdeprecated }, | 442 { STCdeprecated, TOKdeprecated }, |
411 { STCoverride, TOKoverride }, | 443 { STCoverride, TOKoverride }, |
444 { STClazy, TOKlazy }, | |
445 { STCalias, TOKalias }, | |
446 { STCout, TOKout }, | |
447 { STCin, TOKin }, | |
448 #if DMDV2 | |
449 { STCimmutable, TOKimmutable }, | |
450 { STCshared, TOKshared }, | |
412 { STCnothrow, TOKnothrow }, | 451 { STCnothrow, TOKnothrow }, |
413 { STCpure, TOKpure }, | 452 { STCpure, TOKpure }, |
414 { STCref, TOKref }, | 453 { STCref, TOKref }, |
415 { STCtls, TOKtls }, | 454 { STCtls, TOKtls }, |
416 { STCgshared, TOKgshared }, | 455 { STCgshared, TOKgshared }, |
417 { STClazy, TOKlazy }, | 456 #endif |
418 { STCalias, TOKalias }, | |
419 { STCout, TOKout }, | |
420 { STCin, TOKin }, | |
421 }; | 457 }; |
422 | 458 |
423 for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++) | 459 for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++) |
424 { | 460 { |
425 if (stc & table[i].stc) | 461 if (stc & table[i].stc) |
452 assert(!s); | 488 assert(!s); |
453 ld = new LinkDeclaration(linkage, Dsymbol::arraySyntaxCopy(decl)); | 489 ld = new LinkDeclaration(linkage, Dsymbol::arraySyntaxCopy(decl)); |
454 return ld; | 490 return ld; |
455 } | 491 } |
456 | 492 |
493 void LinkDeclaration::setScope(Scope *sc) | |
494 { | |
495 //printf("LinkDeclaration::setScope(linkage = %d, decl = %p)\n", linkage, decl); | |
496 if (decl) | |
497 { | |
498 setScopeNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign); | |
499 } | |
500 } | |
501 | |
457 void LinkDeclaration::semantic(Scope *sc) | 502 void LinkDeclaration::semantic(Scope *sc) |
458 { | 503 { |
459 //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl); | 504 //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl); |
460 if (decl) | 505 if (decl) |
461 { | 506 { |
462 #if 1 | |
463 semanticNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign); | 507 semanticNewSc(sc, sc->stc, linkage, sc->protection, sc->explicitProtection, sc->structalign); |
464 #else | |
465 enum LINK linkage_save = sc->linkage; | |
466 | |
467 sc->linkage = linkage; | |
468 for (unsigned i = 0; i < decl->dim; i++) | |
469 { | |
470 Dsymbol *s = (Dsymbol *)decl->data[i]; | |
471 | |
472 s->semantic(sc); | |
473 } | |
474 sc->linkage = linkage_save; | |
475 #endif | |
476 } | 508 } |
477 } | 509 } |
478 | 510 |
479 void LinkDeclaration::semantic3(Scope *sc) | 511 void LinkDeclaration::semantic3(Scope *sc) |
480 { | 512 { |
542 assert(!s); | 574 assert(!s); |
543 pd = new ProtDeclaration(protection, Dsymbol::arraySyntaxCopy(decl)); | 575 pd = new ProtDeclaration(protection, Dsymbol::arraySyntaxCopy(decl)); |
544 return pd; | 576 return pd; |
545 } | 577 } |
546 | 578 |
579 void ProtDeclaration::setScope(Scope *sc) | |
580 { | |
581 if (decl) | |
582 { | |
583 setScopeNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign); | |
584 } | |
585 } | |
586 | |
547 void ProtDeclaration::semantic(Scope *sc) | 587 void ProtDeclaration::semantic(Scope *sc) |
548 { | 588 { |
549 if (decl) | 589 if (decl) |
550 { | 590 { |
551 #if 1 | |
552 semanticNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign); | 591 semanticNewSc(sc, sc->stc, sc->linkage, protection, 1, sc->structalign); |
553 #else | |
554 enum PROT protection_save = sc->protection; | |
555 int explicitProtection_save = sc->explicitProtection; | |
556 | |
557 sc->protection = protection; | |
558 sc->explicitProtection = 1; | |
559 for (unsigned i = 0; i < decl->dim; i++) | |
560 { | |
561 Dsymbol *s = (Dsymbol *)decl->data[i]; | |
562 | |
563 s->semantic(sc); | |
564 } | |
565 sc->protection = protection_save; | |
566 sc->explicitProtection = explicitProtection_save; | |
567 #endif | |
568 } | 592 } |
569 } | 593 } |
570 | 594 |
571 void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, enum PROT protection) | 595 void ProtDeclaration::protectionToCBuffer(OutBuffer *buf, enum PROT protection) |
572 { | 596 { |
609 assert(!s); | 633 assert(!s); |
610 ad = new AlignDeclaration(loc, salign, Dsymbol::arraySyntaxCopy(decl)); | 634 ad = new AlignDeclaration(loc, salign, Dsymbol::arraySyntaxCopy(decl)); |
611 return ad; | 635 return ad; |
612 } | 636 } |
613 | 637 |
638 void AlignDeclaration::setScope(Scope *sc) | |
639 { | |
640 //printf("\tAlignDeclaration::setScope '%s'\n",toChars()); | |
641 if (decl) | |
642 { | |
643 setScopeNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign); | |
644 } | |
645 } | |
646 | |
614 void AlignDeclaration::semantic(Scope *sc) | 647 void AlignDeclaration::semantic(Scope *sc) |
615 { | 648 { |
616 // LDC | |
617 // we only support packed structs, as from the spec: align(1) struct Packed { ... } | |
618 // other alignments are simply ignored. my tests show this is what llvm-gcc does too ... | |
619 | |
620 //printf("\tAlignDeclaration::semantic '%s'\n",toChars()); | 649 //printf("\tAlignDeclaration::semantic '%s'\n",toChars()); |
621 if (decl) | 650 if (decl) |
622 { | 651 { |
623 #if 1 | |
624 semanticNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign); | 652 semanticNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign); |
625 #else | |
626 unsigned salign_save = sc->structalign; | |
627 | |
628 #if IN_DMD | |
629 sc->structalign = salign; | |
630 #endif | |
631 for (unsigned i = 0; i < decl->dim; i++) | |
632 { | |
633 Dsymbol *s = (Dsymbol *)decl->data[i]; | |
634 | |
635 #if IN_LLVM | |
636 if (s->isStructDeclaration() && salign == 1) | |
637 { | |
638 sc->structalign = salign; | |
639 s->semantic(sc); | |
640 sc->structalign = salign_save; | |
641 } | |
642 else | |
643 { | |
644 #endif | |
645 s->semantic(sc); | |
646 #if IN_LLVM | |
647 } | |
648 #endif | |
649 } | |
650 sc->structalign = salign_save; | |
651 #endif | |
652 } | 653 } |
653 else | 654 else |
654 assert(0 && "what kind of align use triggers this?"); | 655 assert(0 && "what kind of align use triggers this?"); |
655 } | 656 } |
656 | 657 |
868 pd = new PragmaDeclaration(loc, ident, | 869 pd = new PragmaDeclaration(loc, ident, |
869 Expression::arraySyntaxCopy(args), Dsymbol::arraySyntaxCopy(decl)); | 870 Expression::arraySyntaxCopy(args), Dsymbol::arraySyntaxCopy(decl)); |
870 return pd; | 871 return pd; |
871 } | 872 } |
872 | 873 |
874 void PragmaDeclaration::setScope(Scope *sc) | |
875 { | |
876 #if TARGET_NET | |
877 if (ident == Lexer::idPool("assembly")) | |
878 { | |
879 if (!args || args->dim != 1) | |
880 { | |
881 error("pragma has invalid number of arguments"); | |
882 } | |
883 else | |
884 { | |
885 Expression *e = (Expression *)args->data[0]; | |
886 e = e->semantic(sc); | |
887 e = e->optimize(WANTvalue | WANTinterpret); | |
888 args->data[0] = (void *)e; | |
889 if (e->op != TOKstring) | |
890 { | |
891 error("string expected, not '%s'", e->toChars()); | |
892 } | |
893 PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e)); | |
894 | |
895 assert(sc); | |
896 pragma->setScope(sc); | |
897 | |
898 //add to module members | |
899 assert(sc->module); | |
900 assert(sc->module->members); | |
901 sc->module->members->push(pragma); | |
902 } | |
903 } | |
904 #endif // TARGET_NET | |
905 } | |
906 | |
873 void PragmaDeclaration::semantic(Scope *sc) | 907 void PragmaDeclaration::semantic(Scope *sc) |
874 { // Should be merged with PragmaStatement | 908 { // Should be merged with PragmaStatement |
875 | 909 |
876 #if IN_LLVM | 910 #if IN_LLVM |
877 int llvm_internal = 0; | 911 int llvm_internal = 0; |
890 e = e->semantic(sc); | 924 e = e->semantic(sc); |
891 e = e->optimize(WANTvalue | WANTinterpret); | 925 e = e->optimize(WANTvalue | WANTinterpret); |
892 if (e->op == TOKstring) | 926 if (e->op == TOKstring) |
893 { | 927 { |
894 StringExp *se = (StringExp *)e; | 928 StringExp *se = (StringExp *)e; |
895 fprintf(stdmsg, "%.*s", (int)se->len, (char*)se->string); | 929 fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); |
896 } | 930 } |
897 else | 931 else |
898 error("string expected for message, not '%s'", e->toChars()); | 932 error("string expected for message, not '%s'", e->toChars()); |
899 } | 933 } |
900 fprintf(stdmsg, "\n"); | 934 fprintf(stdmsg, "\n"); |
979 goto Lnodecl; | 1013 goto Lnodecl; |
980 } | 1014 } |
981 #if TARGET_NET | 1015 #if TARGET_NET |
982 else if (ident == Lexer::idPool("assembly")) | 1016 else if (ident == Lexer::idPool("assembly")) |
983 { | 1017 { |
984 if (!args || args->dim != 1) | |
985 error("pragma has invalid number of arguments"); | |
986 else | |
987 { | |
988 Expression *e = (Expression *)args->data[0]; | |
989 e = e->semantic(sc); | |
990 e = e->optimize(WANTvalue | WANTinterpret); | |
991 args->data[0] = (void *)e; | |
992 if (e->op != TOKstring) | |
993 { | |
994 error("string expected, not '%s'", e->toChars()); | |
995 } | |
996 PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e)); | |
997 decl = new Array; | |
998 decl->push(pragma); | |
999 } | |
1000 } | 1018 } |
1001 #endif // TARGET_NET | 1019 #endif // TARGET_NET |
1002 // LDC | 1020 // LDC |
1003 #if IN_LLVM | 1021 #if IN_LLVM |
1004 | 1022 |