comparison dmd/func.c @ 336:aaade6ded589 trunk

[svn r357] Merged DMD 1.033
author lindquist
date Sat, 12 Jul 2008 19:38:31 +0200
parents f7190d9eb70c
children d8234836b40f
comparison
equal deleted inserted replaced
335:17b844102023 336:aaade6ded589
101 void FuncDeclaration::semantic(Scope *sc) 101 void FuncDeclaration::semantic(Scope *sc)
102 { TypeFunction *f; 102 { TypeFunction *f;
103 StructDeclaration *sd; 103 StructDeclaration *sd;
104 ClassDeclaration *cd; 104 ClassDeclaration *cd;
105 InterfaceDeclaration *id; 105 InterfaceDeclaration *id;
106 Dsymbol *pd;
106 107
107 #if 0 108 #if 0
108 printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc->linkage); 109 printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc->linkage);
109 if (isFuncLiteralDeclaration()) 110 if (isFuncLiteralDeclaration())
110 printf("\tFuncLiteralDeclaration()\n"); 111 printf("\tFuncLiteralDeclaration()\n");
204 isInvariantDeclaration() || 205 isInvariantDeclaration() ||
205 isUnitTestDeclaration() || isNewDeclaration() || isDelete()) 206 isUnitTestDeclaration() || isNewDeclaration() || isDelete())
206 error("special function not allowed in interface %s", id->toChars()); 207 error("special function not allowed in interface %s", id->toChars());
207 if (fbody) 208 if (fbody)
208 error("function body is not abstract in interface %s", id->toChars()); 209 error("function body is not abstract in interface %s", id->toChars());
210 }
211
212 /* Template member functions aren't virtual:
213 * interface TestInterface { void tpl(T)(); }
214 * and so won't work in interfaces
215 */
216 if ((pd = toParent()) != NULL &&
217 pd->isTemplateInstance() &&
218 (pd = toParent2()) != NULL &&
219 (id = pd->isInterfaceDeclaration()) != NULL)
220 {
221 error("template member function not allowed in interface %s", id->toChars());
209 } 222 }
210 223
211 cd = parent->isClassDeclaration(); 224 cd = parent->isClassDeclaration();
212 if (cd) 225 if (cd)
213 { int vi; 226 { int vi;
304 { FuncDeclaration *fdv = (FuncDeclaration *)cd->vtbl.data[vi]; 317 { FuncDeclaration *fdv = (FuncDeclaration *)cd->vtbl.data[vi];
305 // This function is covariant with fdv 318 // This function is covariant with fdv
306 if (fdv->isFinal()) 319 if (fdv->isFinal())
307 error("cannot override final function %s", fdv->toPrettyChars()); 320 error("cannot override final function %s", fdv->toPrettyChars());
308 321
309 #if V2 322 #if DMDV2
310 if (!isOverride() && global.params.warnings) 323 if (!isOverride() && global.params.warnings)
311 warning("%s: overrides base class function %s, but is not marked with 'override'", locToChars() fdv->toPrettyChars()); 324 warning("%s: overrides base class function %s, but is not marked with 'override'", locToChars() fdv->toPrettyChars());
312 #endif 325 #endif
313 326
314 if (fdv->toParent() == parent) 327 if (fdv->toParent() == parent)
320 break; 333 break;
321 if (!this->parent->isClassDeclaration() 334 if (!this->parent->isClassDeclaration()
322 #if !BREAKABI 335 #if !BREAKABI
323 && !isDtorDeclaration() 336 && !isDtorDeclaration()
324 #endif 337 #endif
325 #if V2 338 #if DMDV2
326 && !isPostBlitDeclaration() 339 && !isPostBlitDeclaration()
327 #endif 340 #endif
328 ) 341 )
329 error("multiple overrides of same function"); 342 error("multiple overrides of same function");
330 } 343 }
976 type = type->semantic(loc, sc); 989 type = type->semantic(loc, sc);
977 } 990 }
978 f = (TypeFunction *)type; 991 f = (TypeFunction *)type;
979 } 992 }
980 993
981 int offend = fbody ? fbody->fallOffEnd() : TRUE; 994 int offend = fbody ? fbody->blockExit() & BEfallthru : TRUE;
995 //int offend = fbody ? fbody->fallOffEnd() : TRUE;
982 996
983 if (isStaticCtorDeclaration()) 997 if (isStaticCtorDeclaration())
984 { /* It's a static constructor. Ensure that all 998 { /* It's a static constructor. Ensure that all
985 * ctor consts were initialized. 999 * ctor consts were initialized.
986 */ 1000 */
1469 if (t->equals(f->type)) 1483 if (t->equals(f->type))
1470 { p->f = f; 1484 { p->f = f;
1471 return 1; 1485 return 1;
1472 } 1486 }
1473 1487
1474 #if V2 1488 #if DMDV2
1475 /* Allow covariant matches, if it's just a const conversion 1489 /* Allow covariant matches, if it's just a const conversion
1476 * of the return type 1490 * of the return type
1477 */ 1491 */
1478 if (t->ty == Tfunction) 1492 if (t->ty == Tfunction)
1479 { TypeFunction *tf = (TypeFunction *)f->type; 1493 { TypeFunction *tf = (TypeFunction *)f->type;
1775 s = new LabelDsymbol(ident); 1789 s = new LabelDsymbol(ident);
1776 labtab->insert(s); 1790 labtab->insert(s);
1777 } 1791 }
1778 return (LabelDsymbol *)s; 1792 return (LabelDsymbol *)s;
1779 } 1793 }
1794
1780 /**************************************** 1795 /****************************************
1781 * If non-static member function that has a 'this' pointer, 1796 * If non-static member function that has a 'this' pointer,
1782 * return the aggregate it is a member of. 1797 * return the aggregate it is a member of.
1783 * Otherwise, return NULL. 1798 * Otherwise, return NULL.
1784 */ 1799 */
2029 st->insert(fd); 2044 st->insert(fd);
2030 } 2045 }
2031 return fd; 2046 return fd;
2032 } 2047 }
2033 2048
2034 char *FuncDeclaration::kind() 2049 const char *FuncDeclaration::kind()
2035 { 2050 {
2036 return "function"; 2051 return "function";
2037 } 2052 }
2053
2038 /******************************* 2054 /*******************************
2039 * Look at all the variables in this function that are referenced 2055 * Look at all the variables in this function that are referenced
2040 * by nested functions, and determine if a closure needs to be 2056 * by nested functions, and determine if a closure needs to be
2041 * created for them. 2057 * created for them.
2042 */ 2058 */
2043 2059
2044 #if V2 2060 #if DMDV2
2045 int FuncDeclaration::needsClosure() 2061 int FuncDeclaration::needsClosure()
2046 { 2062 {
2047 /* Need a closure for all the closureVars[] if any of the 2063 /* Need a closure for all the closureVars[] if any of the
2048 * closureVars[] are accessed by a 2064 * closureVars[] are accessed by a
2049 * function that escapes the scope of this function. 2065 * function that escapes the scope of this function.
2050 * We take the conservative approach and decide that any function that: 2066 * We take the conservative approach and decide that any function that:
2051 * 1) is a virtual function 2067 * 1) is a virtual function
2052 * 2) has its address taken 2068 * 2) has its address taken
2053 * 3) has a parent that escapes 2069 * 3) has a parent that escapes
2054 * escapes. 2070 *
2071 * Note that since a non-virtual function can be called by
2072 * a virtual one, if that non-virtual function accesses a closure
2073 * var, the closure still has to be taken. Hence, we check for isThis()
2074 * instead of isVirtual(). (thanks to David Friedman)
2055 */ 2075 */
2056 2076
2057 //printf("FuncDeclaration::needsClosure() %s\n", toChars()); 2077 //printf("FuncDeclaration::needsClosure() %s\n", toChars());
2058 for (int i = 0; i < closureVars.dim; i++) 2078 for (int i = 0; i < closureVars.dim; i++)
2059 { VarDeclaration *v = (VarDeclaration *)closureVars.data[i]; 2079 { VarDeclaration *v = (VarDeclaration *)closureVars.data[i];
2063 for (int j = 0; j < v->nestedrefs.dim; j++) 2083 for (int j = 0; j < v->nestedrefs.dim; j++)
2064 { FuncDeclaration *f = (FuncDeclaration *)v->nestedrefs.data[j]; 2084 { FuncDeclaration *f = (FuncDeclaration *)v->nestedrefs.data[j];
2065 assert(f != this); 2085 assert(f != this);
2066 2086
2067 //printf("\t\tf = %s, %d, %d\n", f->toChars(), f->isVirtual(), f->tookAddressOf); 2087 //printf("\t\tf = %s, %d, %d\n", f->toChars(), f->isVirtual(), f->tookAddressOf);
2068 if (f->isVirtual() || f->tookAddressOf) 2088 if (f->isThis() || f->tookAddressOf)
2069 goto Lyes; // assume f escapes this function's scope 2089 goto Lyes; // assume f escapes this function's scope
2070 2090
2071 // Look to see if any parents of f that are below this escape 2091 // Look to see if any parents of f that are below this escape
2072 for (Dsymbol *s = f->parent; s != this; s = s->parent) 2092 for (Dsymbol *s = f->parent; s != this; s = s->parent)
2073 { 2093 {
2074 f = s->isFuncDeclaration(); 2094 f = s->isFuncDeclaration();
2075 if (f && (f->isVirtual() || f->tookAddressOf)) 2095 if (f && (f->isThis() || f->tookAddressOf))
2076 goto Lyes; 2096 goto Lyes;
2077 } 2097 }
2078 } 2098 }
2079 } 2099 }
2080 return 0; 2100 return 0;
2095 { 2115 {
2096 assert(funcalias != this); 2116 assert(funcalias != this);
2097 this->funcalias = funcalias; 2117 this->funcalias = funcalias;
2098 } 2118 }
2099 2119
2100 char *FuncAliasDeclaration::kind() 2120 const char *FuncAliasDeclaration::kind()
2101 { 2121 {
2102 return "function alias"; 2122 return "function alias";
2103 } 2123 }
2104 2124
2105 2125
2140 { 2160 {
2141 //printf("FuncLiteralDeclaration::isNested() '%s'\n", toChars()); 2161 //printf("FuncLiteralDeclaration::isNested() '%s'\n", toChars());
2142 return (tok == TOKdelegate); 2162 return (tok == TOKdelegate);
2143 } 2163 }
2144 2164
2145 char *FuncLiteralDeclaration::kind() 2165 int FuncLiteralDeclaration::isVirtual()
2166 {
2167 return FALSE;
2168 }
2169
2170 const char *FuncLiteralDeclaration::kind()
2146 { 2171 {
2147 // GCC requires the (char*) casts 2172 // GCC requires the (char*) casts
2148 return (tok == TOKdelegate) ? (char*)"delegate" : (char*)"function"; 2173 return (tok == TOKdelegate) ? (char*)"delegate" : (char*)"function";
2149 } 2174 }
2150 2175
2212 tret = Type::tvoid; 2237 tret = Type::tvoid;
2213 } 2238 }
2214 else 2239 else
2215 tret = cd->type; //->referenceTo(); 2240 tret = cd->type; //->referenceTo();
2216 type = new TypeFunction(arguments, tret, varargs, LINKd); 2241 type = new TypeFunction(arguments, tret, varargs, LINKd);
2242 if (!originalType)
2243 originalType = type;
2217 2244
2218 sc->flags |= SCOPEctor; 2245 sc->flags |= SCOPEctor;
2219 type = type->semantic(loc, sc); 2246 type = type->semantic(loc, sc);
2220 sc->flags &= ~SCOPEctor; 2247 sc->flags &= ~SCOPEctor;
2221 2248
2238 // See if it's the default constructor 2265 // See if it's the default constructor
2239 if (cd && varargs == 0 && Argument::dim(arguments) == 0) 2266 if (cd && varargs == 0 && Argument::dim(arguments) == 0)
2240 cd->defaultCtor = this; 2267 cd->defaultCtor = this;
2241 } 2268 }
2242 2269
2243 char *CtorDeclaration::kind() 2270 const char *CtorDeclaration::kind()
2244 { 2271 {
2245 return "constructor"; 2272 return "constructor";
2246 } 2273 }
2247 2274
2248 char *CtorDeclaration::toChars() 2275 char *CtorDeclaration::toChars()
2374 void StaticCtorDeclaration::semantic(Scope *sc) 2401 void StaticCtorDeclaration::semantic(Scope *sc)
2375 { 2402 {
2376 //printf("StaticCtorDeclaration::semantic()\n"); 2403 //printf("StaticCtorDeclaration::semantic()\n");
2377 2404
2378 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 2405 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
2406
2407 /* If the static ctor appears within a template instantiation,
2408 * it could get called multiple times by the module constructors
2409 * for different modules. Thus, protect it with a gate.
2410 */
2411 if (inTemplateInstance())
2412 {
2413 /* Add this prefix to the function:
2414 * static int gate;
2415 * if (++gate != 1) return;
2416 * Note that this is not thread safe; should not have threads
2417 * during static construction.
2418 */
2419 Identifier *id = Lexer::idPool("__gate");
2420 VarDeclaration *v = new VarDeclaration(0, Type::tint32, id, NULL);
2421 v->storage_class = STCstatic;
2422 Statements *sa = new Statements();
2423 Statement *s = new DeclarationStatement(0, v);
2424 sa->push(s);
2425 Expression *e = new IdentifierExp(0, id);
2426 e = new AddAssignExp(0, e, new IntegerExp(1));
2427 e = new EqualExp(TOKnotequal, 0, e, new IntegerExp(1));
2428 s = new IfStatement(0, NULL, e, new ReturnStatement(0, NULL), NULL);
2429 sa->push(s);
2430 if (fbody)
2431 sa->push(fbody);
2432 fbody = new CompoundStatement(0, sa);
2433 }
2379 2434
2380 FuncDeclaration::semantic(sc); 2435 FuncDeclaration::semantic(sc);
2381 2436
2382 // We're going to need ModuleInfo 2437 // We're going to need ModuleInfo
2383 Module *m = getModule(); 2438 Module *m = getModule();
2430 2485
2431 StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc) 2486 StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc)
2432 : FuncDeclaration(loc, endloc, 2487 : FuncDeclaration(loc, endloc,
2433 Identifier::generateId("_staticDtor"), STCstatic, NULL) 2488 Identifier::generateId("_staticDtor"), STCstatic, NULL)
2434 { 2489 {
2490 vgate = NULL;
2435 } 2491 }
2436 2492
2437 Dsymbol *StaticDtorDeclaration::syntaxCopy(Dsymbol *s) 2493 Dsymbol *StaticDtorDeclaration::syntaxCopy(Dsymbol *s)
2438 { 2494 {
2439 StaticDtorDeclaration *sdd; 2495 StaticDtorDeclaration *sdd;
2452 cd = sc->scopesym->isClassDeclaration(); 2508 cd = sc->scopesym->isClassDeclaration();
2453 if (!cd) 2509 if (!cd)
2454 { 2510 {
2455 } 2511 }
2456 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd); 2512 type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
2513
2514 /* If the static ctor appears within a template instantiation,
2515 * it could get called multiple times by the module constructors
2516 * for different modules. Thus, protect it with a gate.
2517 */
2518 if (inTemplateInstance())
2519 {
2520 /* Add this prefix to the function:
2521 * static int gate;
2522 * if (--gate != 0) return;
2523 * Increment gate during constructor execution.
2524 * Note that this is not thread safe; should not have threads
2525 * during static destruction.
2526 */
2527 Identifier *id = Lexer::idPool("__gate");
2528 VarDeclaration *v = new VarDeclaration(0, Type::tint32, id, NULL);
2529 v->storage_class = STCstatic;
2530 Statements *sa = new Statements();
2531 Statement *s = new DeclarationStatement(0, v);
2532 sa->push(s);
2533 Expression *e = new IdentifierExp(0, id);
2534 e = new AddAssignExp(0, e, new IntegerExp(-1));
2535 e = new EqualExp(TOKnotequal, 0, e, new IntegerExp(1));
2536 s = new IfStatement(0, NULL, e, new ReturnStatement(0, NULL), NULL);
2537 sa->push(s);
2538 if (fbody)
2539 sa->push(fbody);
2540 fbody = new CompoundStatement(0, sa);
2541 vgate = v;
2542 }
2457 2543
2458 FuncDeclaration::semantic(sc); 2544 FuncDeclaration::semantic(sc);
2459 2545
2460 // We're going to need ModuleInfo 2546 // We're going to need ModuleInfo
2461 Module *m = getModule(); 2547 Module *m = getModule();
2581 * instances per module. 2667 * instances per module.
2582 */ 2668 */
2583 2669
2584 static Identifier *unitTestId() 2670 static Identifier *unitTestId()
2585 { 2671 {
2586 static int n; 2672 return Lexer::uniqueId("__unittest");
2587 char buffer[10 + sizeof(n)*3 + 1];
2588
2589 sprintf(buffer,"__unittest%d", n);
2590 n++;
2591 return Lexer::idPool(buffer);
2592 } 2673 }
2593 2674
2594 UnitTestDeclaration::UnitTestDeclaration(Loc loc, Loc endloc) 2675 UnitTestDeclaration::UnitTestDeclaration(Loc loc, Loc endloc)
2595 : FuncDeclaration(loc, endloc, unitTestId(), STCundefined, NULL) 2676 : FuncDeclaration(loc, endloc, unitTestId(), STCundefined, NULL)
2596 { 2677 {
2711 } 2792 }
2712 2793
2713 FuncDeclaration::semantic(sc); 2794 FuncDeclaration::semantic(sc);
2714 } 2795 }
2715 2796
2716 char *NewDeclaration::kind() 2797 const char *NewDeclaration::kind()
2717 { 2798 {
2718 return "allocator"; 2799 return "allocator";
2719 } 2800 }
2720 2801
2721 int NewDeclaration::isVirtual() 2802 int NewDeclaration::isVirtual()
2795 } 2876 }
2796 2877
2797 FuncDeclaration::semantic(sc); 2878 FuncDeclaration::semantic(sc);
2798 } 2879 }
2799 2880
2800 char *DeleteDeclaration::kind() 2881 const char *DeleteDeclaration::kind()
2801 { 2882 {
2802 return "deallocator"; 2883 return "deallocator";
2803 } 2884 }
2804 2885
2805 int DeleteDeclaration::isDelete() 2886 int DeleteDeclaration::isDelete()