Mercurial > projects > ldc
comparison dmd/dsymbol.c @ 1587:def7a1d494fd
Merge DMD 1.051
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Fri, 06 Nov 2009 23:58:01 +0100 |
parents | 78038e540342 |
children | 207a8a438dea |
comparison
equal
deleted
inserted
replaced
1586:7f728c52e63c | 1587:def7a1d494fd |
---|---|
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. |
26 #include "id.h" | 26 #include "id.h" |
27 #include "scope.h" | 27 #include "scope.h" |
28 #include "init.h" | 28 #include "init.h" |
29 #include "import.h" | 29 #include "import.h" |
30 #include "template.h" | 30 #include "template.h" |
31 | 31 #include "attrib.h" |
32 #include "../gen/enums.h" | 32 #include "../gen/enums.h" |
33 | 33 |
34 /****************************** Dsymbol ******************************/ | 34 /****************************** Dsymbol ******************************/ |
35 | 35 |
36 Dsymbol::Dsymbol() | 36 Dsymbol::Dsymbol() |
43 this->csym = NULL; | 43 this->csym = NULL; |
44 this->isym = NULL; | 44 this->isym = NULL; |
45 #endif | 45 #endif |
46 this->loc = 0; | 46 this->loc = 0; |
47 this->comment = NULL; | 47 this->comment = NULL; |
48 | 48 this->scope = NULL; |
49 #if IN_LLVM | 49 #if IN_LLVM |
50 this->llvmInternal = LLVMnone; | 50 this->llvmInternal = LLVMnone; |
51 this->irsym = NULL; | 51 this->irsym = NULL; |
52 #endif | 52 #endif |
53 } | 53 } |
62 this->csym = NULL; | 62 this->csym = NULL; |
63 this->isym = NULL; | 63 this->isym = NULL; |
64 #endif | 64 #endif |
65 this->loc = 0; | 65 this->loc = 0; |
66 this->comment = NULL; | 66 this->comment = NULL; |
67 | 67 this->scope = NULL; |
68 #if IN_LLVM | 68 #if IN_LLVM |
69 this->llvmInternal = LLVMnone; | 69 this->llvmInternal = LLVMnone; |
70 this->irsym = NULL; | 70 this->irsym = NULL; |
71 #endif | 71 #endif |
72 } | 72 } |
162 char *Dsymbol::toChars() | 162 char *Dsymbol::toChars() |
163 { | 163 { |
164 return ident ? ident->toChars() : (char *)"__anonymous"; | 164 return ident ? ident->toChars() : (char *)"__anonymous"; |
165 } | 165 } |
166 | 166 |
167 char *Dsymbol::toPrettyChars() | 167 const char *Dsymbol::toPrettyChars() |
168 { Dsymbol *p; | 168 { Dsymbol *p; |
169 char *s; | 169 char *s; |
170 char *q; | 170 char *q; |
171 size_t len; | 171 size_t len; |
172 | 172 |
188 q -= len; | 188 q -= len; |
189 memcpy(q, t, len); | 189 memcpy(q, t, len); |
190 if (q == s) | 190 if (q == s) |
191 break; | 191 break; |
192 q--; | 192 q--; |
193 #if TARGET_NET | |
194 if (AggregateDeclaration* ad = p->isAggregateDeclaration()) | |
195 { | |
196 if (ad->isNested() && p->parent && p->parent->isAggregateDeclaration()) | |
197 { | |
198 *q = '/'; | |
199 continue; | |
200 } | |
201 } | |
202 #endif | |
193 *q = '.'; | 203 *q = '.'; |
194 } | 204 } |
195 return s; | 205 return s; |
196 } | 206 } |
197 | 207 |
264 int Dsymbol::isAnonymous() | 274 int Dsymbol::isAnonymous() |
265 { | 275 { |
266 return ident ? 0 : 1; | 276 return ident ? 0 : 1; |
267 } | 277 } |
268 | 278 |
279 /************************************* | |
280 * Set scope for future semantic analysis so we can | |
281 * deal better with forward references. | |
282 */ | |
283 | |
284 void Dsymbol::setScope(Scope *sc) | |
285 { | |
286 //printf("Dsymbol::setScope() %p %s\n", this, toChars()); | |
287 if (!sc->nofree) | |
288 sc->setNoFree(); // may need it even after semantic() finishes | |
289 scope = sc; | |
290 } | |
291 | |
292 void Dsymbol::importAll(Scope *sc) | |
293 { | |
294 } | |
295 | |
296 /************************************* | |
297 * Does semantic analysis on the public face of declarations. | |
298 */ | |
299 | |
269 void Dsymbol::semantic(Scope *sc) | 300 void Dsymbol::semantic(Scope *sc) |
270 { | 301 { |
271 error("%p has no semantic routine", this); | 302 error("%p has no semantic routine", this); |
272 } | 303 } |
273 | 304 |
305 /************************************* | |
306 * Does semantic analysis on initializers and members of aggregates. | |
307 */ | |
308 | |
274 void Dsymbol::semantic2(Scope *sc) | 309 void Dsymbol::semantic2(Scope *sc) |
275 { | 310 { |
276 // Most Dsymbols have no further semantic analysis needed | 311 // Most Dsymbols have no further semantic analysis needed |
277 } | 312 } |
278 | 313 |
314 /************************************* | |
315 * Does semantic analysis on function bodies. | |
316 */ | |
317 | |
279 void Dsymbol::semantic3(Scope *sc) | 318 void Dsymbol::semantic3(Scope *sc) |
280 { | 319 { |
281 // Most Dsymbols have no further semantic analysis needed | 320 // Most Dsymbols have no further semantic analysis needed |
282 } | 321 } |
283 | 322 |
323 /************************************* | |
324 * Look for function inlining possibilities. | |
325 */ | |
326 | |
284 void Dsymbol::inlineScan() | 327 void Dsymbol::inlineScan() |
285 { | 328 { |
286 // Most Dsymbols have no further semantic analysis needed | 329 // Most Dsymbols aren't functions |
287 } | 330 } |
288 | 331 |
289 /********************************************* | 332 /********************************************* |
290 * Search for ident as member of s. | 333 * Search for ident as member of s. |
291 * Input: | 334 * Input: |
339 { | 382 { |
340 error("%s is not a template, it is a %s", id->toChars(), sm->kind()); | 383 error("%s is not a template, it is a %s", id->toChars(), sm->kind()); |
341 return NULL; | 384 return NULL; |
342 } | 385 } |
343 ti->tempdecl = td; | 386 ti->tempdecl = td; |
344 if (!ti->semanticdone) | 387 if (!ti->semanticRun) |
345 ti->semantic(sc); | 388 ti->semantic(sc); |
346 sm = ti->toAlias(); | 389 sm = ti->toAlias(); |
347 break; | 390 break; |
348 } | 391 } |
349 | 392 |
405 | 448 |
406 int Dsymbol::isDeprecated() | 449 int Dsymbol::isDeprecated() |
407 { | 450 { |
408 return FALSE; | 451 return FALSE; |
409 } | 452 } |
453 | |
454 #if DMDV2 | |
455 int Dsymbol::isOverloadable() | |
456 { | |
457 return 0; | |
458 } | |
459 #endif | |
410 | 460 |
411 LabelDsymbol *Dsymbol::isLabel() // is this a LabelDsymbol()? | 461 LabelDsymbol *Dsymbol::isLabel() // is this a LabelDsymbol()? |
412 { | 462 { |
413 return NULL; | 463 return NULL; |
414 } | 464 } |
437 //printf("Dsymbol::addMember(this = %p, '%s' scopesym = '%s')\n", this, toChars(), sd->toChars()); | 487 //printf("Dsymbol::addMember(this = %p, '%s' scopesym = '%s')\n", this, toChars(), sd->toChars()); |
438 //printf("Dsymbol::addMember(this = %p, '%s' sd = %p, sd->symtab = %p)\n", this, toChars(), sd, sd->symtab); | 488 //printf("Dsymbol::addMember(this = %p, '%s' sd = %p, sd->symtab = %p)\n", this, toChars(), sd, sd->symtab); |
439 parent = sd; | 489 parent = sd; |
440 if (!isAnonymous()) // no name, so can't add it to symbol table | 490 if (!isAnonymous()) // no name, so can't add it to symbol table |
441 { | 491 { |
442 if (!sd->symtab->insert(this)) // if name is already defined | 492 if (!sd->symtabInsert(this)) // if name is already defined |
443 { | 493 { |
444 Dsymbol *s2; | 494 Dsymbol *s2; |
445 | 495 |
446 s2 = sd->symtab->lookup(ident); | 496 s2 = sd->symtab->lookup(ident); |
447 if (!s2->overloadInsert(this)) | 497 if (!s2->overloadInsert(this)) |
629 * Ignore NULL comments. | 679 * Ignore NULL comments. |
630 */ | 680 */ |
631 | 681 |
632 void Dsymbol::addComment(unsigned char *comment) | 682 void Dsymbol::addComment(unsigned char *comment) |
633 { | 683 { |
634 // if (comment) | 684 //if (comment) |
635 // printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); | 685 //printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); |
636 | 686 |
637 if (!this->comment) | 687 if (!this->comment) |
638 this->comment = comment; | 688 this->comment = comment; |
639 #if 1 | 689 #if 1 |
640 else if (comment && strcmp((char *)comment, (char *)this->comment)) | 690 else if (comment && strcmp((char *)comment, (char *)this->comment)) |
641 { // Concatenate the two | 691 { // Concatenate the two |
642 this->comment = Lexer::combineComments(this->comment, comment); | 692 this->comment = Lexer::combineComments(this->comment, comment); |
643 } | 693 } |
644 #endif | 694 #endif |
645 } | 695 } |
696 | |
697 /********************************* OverloadSet ****************************/ | |
698 | |
699 #if DMDV2 | |
700 OverloadSet::OverloadSet() | |
701 : Dsymbol() | |
702 { | |
703 } | |
704 | |
705 void OverloadSet::push(Dsymbol *s) | |
706 { | |
707 a.push(s); | |
708 } | |
709 | |
710 const char *OverloadSet::kind() | |
711 { | |
712 return "overloadset"; | |
713 } | |
714 #endif | |
646 | 715 |
647 | 716 |
648 /********************************* ScopeDsymbol ****************************/ | 717 /********************************* ScopeDsymbol ****************************/ |
649 | 718 |
650 ScopeDsymbol::ScopeDsymbol() | 719 ScopeDsymbol::ScopeDsymbol() |
679 } | 748 } |
680 | 749 |
681 Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) | 750 Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) |
682 { | 751 { |
683 //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags); | 752 //printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags); |
753 //if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0; | |
684 | 754 |
685 // Look in symbols declared in this module | 755 // Look in symbols declared in this module |
686 Dsymbol *s = symtab ? symtab->lookup(ident) : NULL; | 756 Dsymbol *s = symtab ? symtab->lookup(ident) : NULL; |
687 | 757 |
688 // hide the aliases generated by selective or renamed private imports | 758 // hide the aliases generated by selective or renamed private imports |
769 { | 839 { |
770 for (int i = 0; i < imports->dim; i++) | 840 for (int i = 0; i < imports->dim; i++) |
771 { ScopeDsymbol *ss; | 841 { ScopeDsymbol *ss; |
772 | 842 |
773 ss = (ScopeDsymbol *) imports->data[i]; | 843 ss = (ScopeDsymbol *) imports->data[i]; |
774 if (ss == s) | 844 if (ss == s) // if already imported |
775 { | 845 { |
776 if (protection > prots[i]) | 846 if (protection > prots[i]) |
777 prots[i] = protection; // upgrade access | 847 prots[i] = protection; // upgrade access |
778 return; | 848 return; |
779 } | 849 } |
847 const char *ScopeDsymbol::kind() | 917 const char *ScopeDsymbol::kind() |
848 { | 918 { |
849 return "ScopeDsymbol"; | 919 return "ScopeDsymbol"; |
850 } | 920 } |
851 | 921 |
922 Dsymbol *ScopeDsymbol::symtabInsert(Dsymbol *s) | |
923 { | |
924 return symtab->insert(s); | |
925 } | |
926 | |
927 /*************************************** | |
928 * Determine number of Dsymbols, folding in AttribDeclaration members. | |
929 */ | |
930 | |
931 #if DMDV2 | |
932 size_t ScopeDsymbol::dim(Array *members) | |
933 { | |
934 size_t n = 0; | |
935 if (members) | |
936 { | |
937 for (size_t i = 0; i < members->dim; i++) | |
938 { Dsymbol *s = (Dsymbol *)members->data[i]; | |
939 AttribDeclaration *a = s->isAttribDeclaration(); | |
940 | |
941 if (a) | |
942 { | |
943 n += dim(a->decl); | |
944 } | |
945 else | |
946 n++; | |
947 } | |
948 } | |
949 return n; | |
950 } | |
951 #endif | |
952 | |
953 /*************************************** | |
954 * Get nth Dsymbol, folding in AttribDeclaration members. | |
955 * Returns: | |
956 * Dsymbol* nth Dsymbol | |
957 * NULL not found, *pn gets incremented by the number | |
958 * of Dsymbols | |
959 */ | |
960 | |
961 #if DMDV2 | |
962 Dsymbol *ScopeDsymbol::getNth(Array *members, size_t nth, size_t *pn) | |
963 { | |
964 if (!members) | |
965 return NULL; | |
966 | |
967 size_t n = 0; | |
968 for (size_t i = 0; i < members->dim; i++) | |
969 { Dsymbol *s = (Dsymbol *)members->data[i]; | |
970 AttribDeclaration *a = s->isAttribDeclaration(); | |
971 | |
972 if (a) | |
973 { | |
974 s = getNth(a->decl, nth - n, &n); | |
975 if (s) | |
976 return s; | |
977 } | |
978 else if (n == nth) | |
979 return s; | |
980 else | |
981 n++; | |
982 } | |
983 | |
984 if (pn) | |
985 *pn += n; | |
986 return NULL; | |
987 } | |
988 #endif | |
852 | 989 |
853 /******************************************* | 990 /******************************************* |
854 * Look for member of the form: | 991 * Look for member of the form: |
855 * const(MemberInfo)[] getMembers(string); | 992 * const(MemberInfo)[] getMembers(string); |
856 * Returns NULL if not found | 993 * Returns NULL if not found |
936 Expression *ce; | 1073 Expression *ce; |
937 | 1074 |
938 L1: | 1075 L1: |
939 | 1076 |
940 if (td) | 1077 if (td) |
941 { | 1078 { /* $ gives the number of elements in the tuple |
1079 */ | |
942 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); | 1080 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); |
943 Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t); | 1081 Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t); |
944 v->init = new ExpInitializer(0, e); | 1082 v->init = new ExpInitializer(0, e); |
945 v->storage_class |= STCconst; | 1083 v->storage_class |= STCconst; |
946 return v; | 1084 return v; |
947 } | 1085 } |
948 | 1086 |
949 if (type) | 1087 if (type) |
950 { | 1088 { /* $ gives the number of type entries in the type tuple |
1089 */ | |
951 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); | 1090 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); |
952 Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t); | 1091 Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t); |
953 v->init = new ExpInitializer(0, e); | 1092 v->init = new ExpInitializer(0, e); |
954 v->storage_class |= STCconst; | 1093 v->storage_class |= STCconst; |
955 return v; | 1094 return v; |
956 } | 1095 } |
957 | 1096 |
958 if (exp->op == TOKindex) | 1097 if (exp->op == TOKindex) |
959 { | 1098 { /* array[index] where index is some function of $ |
1099 */ | |
960 IndexExp *ie = (IndexExp *)exp; | 1100 IndexExp *ie = (IndexExp *)exp; |
961 | 1101 |
962 pvar = &ie->lengthVar; | 1102 pvar = &ie->lengthVar; |
963 ce = ie->e1; | 1103 ce = ie->e1; |
964 } | 1104 } |
965 else if (exp->op == TOKslice) | 1105 else if (exp->op == TOKslice) |
966 { | 1106 { /* array[lwr .. upr] where lwr or upr is some function of $ |
1107 */ | |
967 SliceExp *se = (SliceExp *)exp; | 1108 SliceExp *se = (SliceExp *)exp; |
968 | 1109 |
969 pvar = &se->lengthVar; | 1110 pvar = &se->lengthVar; |
970 ce = se->e1; | 1111 ce = se->e1; |
971 } | 1112 } |
972 else | 1113 else |
1114 /* Didn't find $, look in enclosing scope(s). | |
1115 */ | |
973 return NULL; | 1116 return NULL; |
974 | 1117 |
1118 /* If we are indexing into an array that is really a type | |
1119 * tuple, rewrite this as an index into a type tuple and | |
1120 * try again. | |
1121 */ | |
975 if (ce->op == TOKtype) | 1122 if (ce->op == TOKtype) |
976 { | 1123 { |
977 Type *t = ((TypeExp *)ce)->type; | 1124 Type *t = ((TypeExp *)ce)->type; |
978 if (t->ty == Ttuple) | 1125 if (t->ty == Ttuple) |
979 { type = (TypeTuple *)t; | 1126 { type = (TypeTuple *)t; |
980 goto L1; | 1127 goto L1; |
981 } | 1128 } |
982 } | 1129 } |
983 | 1130 |
984 if (!*pvar) | 1131 /* *pvar is lazily initialized, so if we refer to $ |
985 { | 1132 * multiple times, it gets set only once. |
1133 */ | |
1134 if (!*pvar) // if not already initialized | |
1135 { /* Create variable v and set it to the value of $, | |
1136 * which will be a constant. | |
1137 */ | |
986 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); | 1138 VarDeclaration *v = new VarDeclaration(loc, Type::tsize_t, Id::dollar, NULL); |
987 | 1139 |
988 if (ce->op == TOKstring) | 1140 if (ce->op == TOKstring) |
989 { /* It is for a string literal, so the | 1141 { /* It is for a string literal, so the |
990 * length will be a const. | 1142 * length will be a const. |
1028 { | 1180 { |
1029 delete tab; | 1181 delete tab; |
1030 } | 1182 } |
1031 | 1183 |
1032 Dsymbol *DsymbolTable::lookup(Identifier *ident) | 1184 Dsymbol *DsymbolTable::lookup(Identifier *ident) |
1033 { StringValue *sv; | 1185 { |
1034 | |
1035 #ifdef DEBUG | 1186 #ifdef DEBUG |
1036 assert(ident); | 1187 assert(ident); |
1037 assert(tab); | 1188 assert(tab); |
1038 #endif | 1189 #endif |
1039 sv = tab->lookup((char*)ident->string, ident->len); | 1190 StringValue *sv = tab->lookup((char*)ident->string, ident->len); |
1040 return (Dsymbol *)(sv ? sv->ptrvalue : NULL); | 1191 return (Dsymbol *)(sv ? sv->ptrvalue : NULL); |
1041 } | 1192 } |
1042 | 1193 |
1043 Dsymbol *DsymbolTable::insert(Dsymbol *s) | 1194 Dsymbol *DsymbolTable::insert(Dsymbol *s) |
1044 { StringValue *sv; | 1195 { StringValue *sv; |