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;