Mercurial > projects > ldc
comparison dmd2/attrib.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | 2667e3a145be |
children | 54b3c1394d62 |
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. |
10 | 10 |
11 #include <stdio.h> | 11 #include <stdio.h> |
12 #include <stdlib.h> | 12 #include <stdlib.h> |
13 #include <assert.h> | 13 #include <assert.h> |
14 | 14 |
15 #if _WIN32 || IN_GCC || IN_LLVM | 15 #include "rmem.h" |
16 #include "mem.h" | |
17 #elif POSIX | |
18 #include "../root/mem.h" | |
19 #endif | |
20 | 16 |
21 #include "init.h" | 17 #include "init.h" |
22 #include "declaration.h" | 18 #include "declaration.h" |
23 #include "attrib.h" | 19 #include "attrib.h" |
24 #include "cond.h" | 20 #include "cond.h" |
29 #include "aggregate.h" | 25 #include "aggregate.h" |
30 #include "module.h" | 26 #include "module.h" |
31 #include "parse.h" | 27 #include "parse.h" |
32 #include "template.h" | 28 #include "template.h" |
33 | 29 |
30 #if IN_LLVM | |
34 #include "../gen/enums.h" | 31 #include "../gen/enums.h" |
35 | |
36 | 32 |
37 #include "llvm/Support/CommandLine.h" | 33 #include "llvm/Support/CommandLine.h" |
38 | 34 |
39 static llvm::cl::opt<bool> ignoreUnsupportedPragmas("ignore", | 35 static llvm::cl::opt<bool> ignoreUnsupportedPragmas("ignore", |
40 llvm::cl::desc("Ignore unsupported pragmas"), | 36 llvm::cl::desc("Ignore unsupported pragmas"), |
41 llvm::cl::ZeroOrMore); | 37 llvm::cl::ZeroOrMore); |
42 | 38 |
39 #endif | |
43 | 40 |
44 | 41 |
45 extern void obj_includelib(const char *name); | 42 extern void obj_includelib(const char *name); |
43 | |
44 #if IN_DMD | |
46 void obj_startaddress(Symbol *s); | 45 void obj_startaddress(Symbol *s); |
46 #endif | |
47 | 47 |
48 | 48 |
49 /********************************* AttribDeclaration ****************************/ | 49 /********************************* AttribDeclaration ****************************/ |
50 | 50 |
51 AttribDeclaration::AttribDeclaration(Array *decl) | 51 AttribDeclaration::AttribDeclaration(Array *decl) |
149 | 149 |
150 void AttribDeclaration::emitComment(Scope *sc) | 150 void AttribDeclaration::emitComment(Scope *sc) |
151 { | 151 { |
152 //printf("AttribDeclaration::emitComment(sc = %p)\n", sc); | 152 //printf("AttribDeclaration::emitComment(sc = %p)\n", sc); |
153 | 153 |
154 /* If generating doc comment, skip this because if we're inside | 154 /* A general problem with this, illustrated by BUGZILLA 2516, |
155 * a template, then include(NULL, NULL) will fail. | 155 * is that attributes are not transmitted through to the underlying |
156 * member declarations for template bodies, because semantic analysis | |
157 * is not done for template declaration bodies | |
158 * (only template instantiations). | |
159 * Hence, Ddoc omits attributes from template members. | |
156 */ | 160 */ |
157 // if (sc->docbuf) | |
158 // return; | |
159 | 161 |
160 Array *d = include(NULL, NULL); | 162 Array *d = include(NULL, NULL); |
161 | 163 |
162 if (d) | 164 if (d) |
163 { | 165 { |
166 //printf("AttribDeclaration::emitComment %s\n", s->toChars()); | 168 //printf("AttribDeclaration::emitComment %s\n", s->toChars()); |
167 s->emitComment(sc); | 169 s->emitComment(sc); |
168 } | 170 } |
169 } | 171 } |
170 } | 172 } |
173 | |
174 #if IN_DMD | |
171 | 175 |
172 void AttribDeclaration::toObjFile(int multiobj) | 176 void AttribDeclaration::toObjFile(int multiobj) |
173 { | 177 { |
174 Array *d = include(NULL, NULL); | 178 Array *d = include(NULL, NULL); |
175 | 179 |
198 nwritten += n; | 202 nwritten += n; |
199 } | 203 } |
200 } | 204 } |
201 return nwritten; | 205 return nwritten; |
202 } | 206 } |
207 #endif | |
203 | 208 |
204 int AttribDeclaration::hasPointers() | 209 int AttribDeclaration::hasPointers() |
205 { | 210 { |
206 Array *d = include(NULL, NULL); | 211 Array *d = include(NULL, NULL); |
207 | 212 |
300 void StorageClassDeclaration::semantic(Scope *sc) | 305 void StorageClassDeclaration::semantic(Scope *sc) |
301 { | 306 { |
302 if (decl) | 307 if (decl) |
303 { unsigned stc_save = sc->stc; | 308 { unsigned stc_save = sc->stc; |
304 | 309 |
305 /* These sets of storage classes are mutually exclusive, | 310 if (stc & (STCauto | STCscope | STCstatic | STCextern)) |
306 * so choose the innermost or most recent one. | 311 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); |
307 */ | |
308 if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) | |
309 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); | |
310 if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest)) | |
311 sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest); | |
312 if (stc & (STCconst | STCinvariant | STCmanifest)) | |
313 sc->stc &= ~(STCconst | STCinvariant | STCmanifest); | |
314 sc->stc |= stc; | 312 sc->stc |= stc; |
315 for (unsigned i = 0; i < decl->dim; i++) | 313 for (unsigned i = 0; i < decl->dim; i++) |
316 { | 314 { |
317 Dsymbol *s = (Dsymbol *)decl->data[i]; | 315 Dsymbol *s = (Dsymbol *)decl->data[i]; |
318 | 316 |
322 } | 320 } |
323 else | 321 else |
324 sc->stc = stc; | 322 sc->stc = stc; |
325 } | 323 } |
326 | 324 |
327 void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 325 void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc) |
328 { | 326 { |
329 struct SCstring | 327 struct SCstring |
330 { | 328 { |
331 int stc; | 329 int stc; |
332 enum TOK tok; | 330 enum TOK tok; |
337 { STCauto, TOKauto }, | 335 { STCauto, TOKauto }, |
338 { STCscope, TOKscope }, | 336 { STCscope, TOKscope }, |
339 { STCstatic, TOKstatic }, | 337 { STCstatic, TOKstatic }, |
340 { STCextern, TOKextern }, | 338 { STCextern, TOKextern }, |
341 { STCconst, TOKconst }, | 339 { STCconst, TOKconst }, |
342 { STCinvariant, TOKimmutable }, | 340 { STCimmutable, TOKimmutable }, |
343 { STCshared, TOKshared }, | 341 { STCshared, TOKshared }, |
344 { STCfinal, TOKfinal }, | 342 { STCfinal, TOKfinal }, |
345 { STCabstract, TOKabstract }, | 343 { STCabstract, TOKabstract }, |
346 { STCsynchronized, TOKsynchronized }, | 344 { STCsynchronized, TOKsynchronized }, |
347 { STCdeprecated, TOKdeprecated }, | 345 { STCdeprecated, TOKdeprecated }, |
348 { STCoverride, TOKoverride }, | 346 { STCoverride, TOKoverride }, |
349 { STCnothrow, TOKnothrow }, | 347 { STCnothrow, TOKnothrow }, |
350 { STCpure, TOKpure }, | 348 { STCpure, TOKpure }, |
351 { STCref, TOKref }, | 349 { STCref, TOKref }, |
352 { STCtls, TOKtls }, | 350 { STCtls, TOKtls }, |
351 { STCgshared, TOKgshared }, | |
352 { STClazy, TOKlazy }, | |
353 { STCalias, TOKalias }, | |
354 { STCout, TOKout }, | |
355 { STCin, TOKin }, | |
353 }; | 356 }; |
354 | 357 |
355 int written = 0; | |
356 for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++) | 358 for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++) |
357 { | 359 { |
358 if (stc & table[i].stc) | 360 if (stc & table[i].stc) |
359 { | 361 { |
360 if (written) | |
361 buf->writeByte(' '); | |
362 written = 1; | |
363 buf->writestring(Token::toChars(table[i].tok)); | 362 buf->writestring(Token::toChars(table[i].tok)); |
364 } | 363 buf->writeByte(' '); |
365 } | 364 } |
366 | 365 } |
366 } | |
367 | |
368 void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
369 { | |
370 stcToCBuffer(buf, stc); | |
367 AttribDeclaration::toCBuffer(buf, hgs); | 371 AttribDeclaration::toCBuffer(buf, hgs); |
368 } | 372 } |
369 | 373 |
370 /********************************* LinkDeclaration ****************************/ | 374 /********************************* LinkDeclaration ****************************/ |
371 | 375 |
436 case LINKc: p = "C"; break; | 440 case LINKc: p = "C"; break; |
437 case LINKcpp: p = "C++"; break; | 441 case LINKcpp: p = "C++"; break; |
438 case LINKwindows: p = "Windows"; break; | 442 case LINKwindows: p = "Windows"; break; |
439 case LINKpascal: p = "Pascal"; break; | 443 case LINKpascal: p = "Pascal"; break; |
440 | 444 |
441 // LDC | 445 #if IN_LLVM |
442 case LINKintrinsic: p = "Intrinsic"; break; | 446 case LINKintrinsic: p = "Intrinsic"; break; |
443 | 447 #endif |
444 default: | 448 default: |
445 assert(0); | 449 assert(0); |
446 break; | 450 break; |
447 } | 451 } |
448 buf->writestring("extern ("); | 452 buf->writestring("extern ("); |
540 // other alignments are simply ignored. my tests show this is what llvm-gcc does too ... | 544 // other alignments are simply ignored. my tests show this is what llvm-gcc does too ... |
541 | 545 |
542 //printf("\tAlignDeclaration::semantic '%s'\n",toChars()); | 546 //printf("\tAlignDeclaration::semantic '%s'\n",toChars()); |
543 if (decl) | 547 if (decl) |
544 { unsigned salign_save = sc->structalign; | 548 { unsigned salign_save = sc->structalign; |
545 | 549 #if IN_DMD |
550 sc->structalign = salign; | |
551 #endif | |
546 for (unsigned i = 0; i < decl->dim; i++) | 552 for (unsigned i = 0; i < decl->dim; i++) |
547 { | 553 { |
548 Dsymbol *s = (Dsymbol *)decl->data[i]; | 554 Dsymbol *s = (Dsymbol *)decl->data[i]; |
549 | 555 |
550 if (s->isStructDeclaration() && salign == 1) | 556 if (s->isStructDeclaration() && salign == 1) |
629 // printf("\tad = %p\n", ad); | 635 // printf("\tad = %p\n", ad); |
630 // printf("\taad = %p\n", &aad); | 636 // printf("\taad = %p\n", &aad); |
631 | 637 |
632 sc = sc->push(); | 638 sc = sc->push(); |
633 sc->anonAgg = &aad; | 639 sc->anonAgg = &aad; |
634 sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls); | 640 sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCgshared); |
635 sc->inunion = isunion; | 641 sc->inunion = isunion; |
636 sc->offset = 0; | 642 sc->offset = 0; |
637 sc->flags = 0; | 643 sc->flags = 0; |
638 aad.structalign = sc->structalign; | 644 aad.structalign = sc->structalign; |
639 aad.parent = ad; | 645 aad.parent = ad; |
646 | |
640 for (unsigned i = 0; i < decl->dim; i++) | 647 for (unsigned i = 0; i < decl->dim; i++) |
641 { | 648 { |
642 Dsymbol *s = (Dsymbol *)decl->data[i]; | 649 Dsymbol *s = (Dsymbol *)decl->data[i]; |
643 | 650 |
644 s->semantic(sc); | 651 s->semantic(sc); |
685 ad->alignmember(aad.structalign, aad.alignsize, &sc->offset); | 692 ad->alignmember(aad.structalign, aad.alignsize, &sc->offset); |
686 //ad->structsize = sc->offset; | 693 //ad->structsize = sc->offset; |
687 //printf("sc->offset = %d\n", sc->offset); | 694 //printf("sc->offset = %d\n", sc->offset); |
688 | 695 |
689 // Add members of aad to ad | 696 // Add members of aad to ad |
690 //printf("\tadding members of aad (%p) to '%s'\n", &aad, ad->toChars()); | 697 //printf("\tadding members of aad to '%s'\n", ad->toChars()); |
691 for (unsigned i = 0; i < aad.fields.dim; i++) | 698 for (unsigned i = 0; i < aad.fields.dim; i++) |
692 { | 699 { |
693 VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; | 700 VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; |
694 | 701 |
695 // LDC | 702 #if IN_LLVM |
696 v->offset2 = sc->offset; | 703 v->offset2 = sc->offset; |
697 | 704 #endif |
698 v->offset += sc->offset; | 705 v->offset += sc->offset; |
699 | 706 |
700 // LDC | 707 #if IN_LLVM |
701 if (!v->anonDecl) | 708 if (!v->anonDecl) |
702 v->anonDecl = this; | 709 v->anonDecl = this; |
703 | 710 #endif |
704 ad->fields.push(v); | 711 ad->fields.push(v); |
705 } | 712 } |
706 | 713 |
707 // Add size of aad to ad | 714 // Add size of aad to ad |
708 if (adisunion) | 715 if (adisunion) |
769 this->args = args; | 776 this->args = args; |
770 } | 777 } |
771 | 778 |
772 Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s) | 779 Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s) |
773 { | 780 { |
781 //printf("PragmaDeclaration::syntaxCopy(%s)\n", toChars()); | |
774 PragmaDeclaration *pd; | 782 PragmaDeclaration *pd; |
775 | 783 |
776 assert(!s); | 784 assert(!s); |
777 pd = new PragmaDeclaration(loc, ident, | 785 pd = new PragmaDeclaration(loc, ident, |
778 Expression::arraySyntaxCopy(args), Dsymbol::arraySyntaxCopy(decl)); | 786 Expression::arraySyntaxCopy(args), Dsymbol::arraySyntaxCopy(decl)); |
783 { // Should be merged with PragmaStatement | 791 { // Should be merged with PragmaStatement |
784 | 792 |
785 #if IN_LLVM | 793 #if IN_LLVM |
786 int llvm_internal = 0; | 794 int llvm_internal = 0; |
787 std::string arg1str; | 795 std::string arg1str; |
788 | |
789 #endif | 796 #endif |
790 | 797 |
791 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); | 798 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); |
792 if (ident == Id::msg) | 799 if (ident == Id::msg) |
793 { | 800 { |
800 e = e->semantic(sc); | 807 e = e->semantic(sc); |
801 e = e->optimize(WANTvalue | WANTinterpret); | 808 e = e->optimize(WANTvalue | WANTinterpret); |
802 if (e->op == TOKstring) | 809 if (e->op == TOKstring) |
803 { | 810 { |
804 StringExp *se = (StringExp *)e; | 811 StringExp *se = (StringExp *)e; |
805 fprintf(stdmsg, "%.*s", (int)se->len, se->string); | 812 fprintf(stdmsg, "%.*s", (int)se->len, (char*)se->string); |
806 } | 813 } |
807 else | 814 else |
808 error("string expected for message, not '%s'", e->toChars()); | 815 error("string expected for message, not '%s'", e->toChars()); |
809 } | 816 } |
810 fprintf(stdmsg, "\n"); | 817 fprintf(stdmsg, "\n"); |
887 error("function name expected for start address, not '%s'", e->toChars()); | 894 error("function name expected for start address, not '%s'", e->toChars()); |
888 } | 895 } |
889 goto Lnodecl; | 896 goto Lnodecl; |
890 } | 897 } |
891 | 898 |
892 ///////////////////////////////////////////////////////////// | 899 // LDC |
893 ///////////////////////////////////////////////////////////// | |
894 // LDC | |
895 #if IN_LLVM | 900 #if IN_LLVM |
896 | 901 |
897 // pragma(intrinsic, "string") { funcdecl(s) } | 902 // pragma(intrinsic, "string") { funcdecl(s) } |
898 else if (ident == Id::intrinsic) | 903 else if (ident == Id::intrinsic) |
899 { | 904 { |
998 { | 1003 { |
999 sc->module->llvmForceLogging = true; | 1004 sc->module->llvmForceLogging = true; |
1000 } | 1005 } |
1001 else | 1006 else |
1002 { | 1007 { |
1003 error("command '%s' invalid"); | 1008 error("command '%s' invalid", expr->toChars()); |
1004 fatal(); | 1009 fatal(); |
1005 } | 1010 } |
1006 } | 1011 } |
1007 | 1012 |
1008 #endif | 1013 // pragma(llvm_inline_asm) { templdecl(s) } |
1009 // LDC | 1014 else if (ident == Id::llvm_inline_asm) |
1010 ///////////////////////////////////////////////////////////// | 1015 { |
1011 ///////////////////////////////////////////////////////////// | 1016 if (args && args->dim > 0) |
1017 { | |
1018 error("takes no parameters"); | |
1019 fatal(); | |
1020 } | |
1021 llvm_internal = LLVMinline_asm; | |
1022 } | |
1023 | |
1024 #endif // LDC | |
1012 | 1025 |
1013 else if (ignoreUnsupportedPragmas) | 1026 else if (ignoreUnsupportedPragmas) |
1014 { | 1027 { |
1015 if (global.params.verbose) | 1028 if (global.params.verbose) |
1016 { | 1029 { |
1019 printf("pragma %s", ident->toChars()); | 1032 printf("pragma %s", ident->toChars()); |
1020 if (args) | 1033 if (args) |
1021 { | 1034 { |
1022 for (size_t i = 0; i < args->dim; i++) | 1035 for (size_t i = 0; i < args->dim; i++) |
1023 { | 1036 { |
1037 // ignore errors in ignored pragmas. | |
1038 global.gag++; | |
1039 unsigned errors_save = global.errors; | |
1040 | |
1024 Expression *e = (Expression *)args->data[i]; | 1041 Expression *e = (Expression *)args->data[i]; |
1025 e = e->semantic(sc); | 1042 e = e->semantic(sc); |
1026 e = e->optimize(WANTvalue | WANTinterpret); | 1043 e = e->optimize(WANTvalue | WANTinterpret); |
1027 if (i == 0) | 1044 if (i == 0) |
1028 printf(" ("); | 1045 printf(" ("); |
1029 else | 1046 else |
1030 printf(","); | 1047 printf(","); |
1031 printf("%s", e->toChars()); | 1048 printf("%s", e->toChars()); |
1049 | |
1050 // restore error state. | |
1051 global.gag--; | |
1052 global.errors = errors_save; | |
1032 } | 1053 } |
1033 if (args->dim) | 1054 if (args->dim) |
1034 printf(")"); | 1055 printf(")"); |
1035 } | 1056 } |
1036 printf("\n"); | 1057 printf("\n"); |
1037 } | 1058 } |
1038 goto Lnodecl; | |
1039 } | 1059 } |
1040 else | 1060 else |
1041 error("unrecognized pragma(%s)", ident->toChars()); | 1061 error("unrecognized pragma(%s)", ident->toChars()); |
1042 | 1062 |
1043 if (decl) | 1063 if (decl) |
1135 error("the '%s' pragma must only be used on function declarations of type 'void* function(uint nbytes)'", ident->toChars()); | 1155 error("the '%s' pragma must only be used on function declarations of type 'void* function(uint nbytes)'", ident->toChars()); |
1136 fatal(); | 1156 fatal(); |
1137 } | 1157 } |
1138 break; | 1158 break; |
1139 | 1159 |
1160 case LLVMinline_asm: | |
1161 if (TemplateDeclaration* td = s->isTemplateDeclaration()) | |
1162 { | |
1163 if (td->parameters->dim > 1) | |
1164 { | |
1165 error("the '%s' pragma template must have exactly zero or one template parameters", ident->toChars()); | |
1166 fatal(); | |
1167 } | |
1168 else if (!td->onemember) | |
1169 { | |
1170 error("the '%s' pragma template must have exactly one member", ident->toChars()); | |
1171 fatal(); | |
1172 } | |
1173 td->llvmInternal = llvm_internal; | |
1174 } | |
1175 else | |
1176 { | |
1177 error("the '%s' pragma is only allowed on template declarations", ident->toChars()); | |
1178 fatal(); | |
1179 } | |
1180 break; | |
1181 | |
1140 default: | 1182 default: |
1141 warning("the LDC specific pragma '%s' is not yet implemented, ignoring", ident->toChars()); | 1183 warning("the LDC specific pragma '%s' is not yet implemented, ignoring", ident->toChars()); |
1142 } | 1184 } |
1143 } | 1185 } |
1144 | 1186 |
1162 const char *PragmaDeclaration::kind() | 1204 const char *PragmaDeclaration::kind() |
1163 { | 1205 { |
1164 return "pragma"; | 1206 return "pragma"; |
1165 } | 1207 } |
1166 | 1208 |
1209 #if IN_DMD | |
1167 void PragmaDeclaration::toObjFile(int multiobj) | 1210 void PragmaDeclaration::toObjFile(int multiobj) |
1168 { | 1211 { |
1169 if (ident == Id::lib) | 1212 if (ident == Id::lib) |
1170 { | 1213 { |
1171 assert(args && args->dim == 1); | 1214 assert(args && args->dim == 1); |
1176 | 1219 |
1177 StringExp *se = (StringExp *)e; | 1220 StringExp *se = (StringExp *)e; |
1178 char *name = (char *)mem.malloc(se->len + 1); | 1221 char *name = (char *)mem.malloc(se->len + 1); |
1179 memcpy(name, se->string, se->len); | 1222 memcpy(name, se->string, se->len); |
1180 name[se->len] = 0; | 1223 name[se->len] = 0; |
1224 #if OMFOBJ | |
1225 /* The OMF format allows library names to be inserted | |
1226 * into the object file. The linker will then automatically | |
1227 * search that library, too. | |
1228 */ | |
1181 obj_includelib(name); | 1229 obj_includelib(name); |
1182 } | 1230 #elif ELFOBJ || MACHOBJ |
1231 /* The format does not allow embedded library names, | |
1232 * so instead append the library name to the list to be passed | |
1233 * to the linker. | |
1234 */ | |
1235 global.params.libfiles->push((void *) name); | |
1236 #else | |
1237 error("pragma lib not supported"); | |
1238 #endif | |
1239 } | |
1240 #if DMDV2 | |
1183 else if (ident == Id::startaddress) | 1241 else if (ident == Id::startaddress) |
1184 { | 1242 { |
1185 assert(args && args->dim == 1); | 1243 assert(args && args->dim == 1); |
1186 Expression *e = (Expression *)args->data[0]; | 1244 Expression *e = (Expression *)args->data[0]; |
1187 Dsymbol *sa = getDsymbol(e); | 1245 Dsymbol *sa = getDsymbol(e); |
1188 FuncDeclaration *f = sa->isFuncDeclaration(); | 1246 FuncDeclaration *f = sa->isFuncDeclaration(); |
1189 assert(f); | 1247 assert(f); |
1190 Symbol *s = f->toSymbol(); | 1248 Symbol *s = f->toSymbol(); |
1191 assert(0 && "startaddress pragma not implemented"); | 1249 obj_startaddress(s); |
1192 // obj_startaddress(s); | 1250 } |
1193 } | 1251 #endif |
1194 AttribDeclaration::toObjFile(multiobj); | 1252 AttribDeclaration::toObjFile(multiobj); |
1195 } | 1253 } |
1254 #endif | |
1196 | 1255 |
1197 void PragmaDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 1256 void PragmaDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
1198 { | 1257 { |
1199 buf->printf("pragma (%s", ident->toChars()); | 1258 buf->printf("pragma (%s", ident->toChars()); |
1200 if (args && args->dim) | 1259 if (args && args->dim) |
1245 { | 1304 { |
1246 //printf("ConditionalDeclaration::emitComment(sc = %p)\n", sc); | 1305 //printf("ConditionalDeclaration::emitComment(sc = %p)\n", sc); |
1247 if (condition->inc) | 1306 if (condition->inc) |
1248 { | 1307 { |
1249 AttribDeclaration::emitComment(sc); | 1308 AttribDeclaration::emitComment(sc); |
1309 } | |
1310 else if (sc->docbuf) | |
1311 { | |
1312 /* If generating doc comment, be careful because if we're inside | |
1313 * a template, then include(NULL, NULL) will fail. | |
1314 */ | |
1315 Array *d = decl ? decl : elsedecl; | |
1316 for (unsigned i = 0; i < d->dim; i++) | |
1317 { Dsymbol *s = (Dsymbol *)d->data[i]; | |
1318 s->emitComment(sc); | |
1319 } | |
1250 } | 1320 } |
1251 } | 1321 } |
1252 | 1322 |
1253 // Decide if 'then' or 'else' code should be included | 1323 // Decide if 'then' or 'else' code should be included |
1254 | 1324 |