comparison dmd2/func.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
178 unsigned stc = storage_class; 178 unsigned stc = storage_class;
179 if (type->isInvariant()) 179 if (type->isInvariant())
180 stc |= STCimmutable; 180 stc |= STCimmutable;
181 if (type->isConst()) 181 if (type->isConst())
182 stc |= STCconst; 182 stc |= STCconst;
183 if (type->isShared()) 183 if (type->isShared() || storage_class & STCsynchronized)
184 stc |= STCshared; 184 stc |= STCshared;
185 switch (stc & STC_TYPECTOR) 185 switch (stc & STC_TYPECTOR)
186 { 186 {
187 case STCimmutable: 187 case STCimmutable:
188 case STCimmutable | STCconst: 188 case STCimmutable | STCconst:
1197 } 1197 }
1198 else if (!hasReturnExp && type->nextOf()->ty != Tvoid) 1198 else if (!hasReturnExp && type->nextOf()->ty != Tvoid)
1199 error("expected to return a value of type %s", type->nextOf()->toChars()); 1199 error("expected to return a value of type %s", type->nextOf()->toChars());
1200 else if (!inlineAsm) 1200 else if (!inlineAsm)
1201 { 1201 {
1202 #if DMDV2
1202 int blockexit = fbody ? fbody->blockExit() : BEfallthru; 1203 int blockexit = fbody ? fbody->blockExit() : BEfallthru;
1203 if (f->isnothrow && blockexit & BEthrow) 1204 if (f->isnothrow && blockexit & BEthrow)
1204 error("'%s' is nothrow yet may throw", toChars()); 1205 error("'%s' is nothrow yet may throw", toChars());
1205 1206
1206 int offend = blockexit & BEfallthru; 1207 int offend = blockexit & BEfallthru;
1207 1208 #endif
1208 if (type->nextOf()->ty == Tvoid) 1209 if (type->nextOf()->ty == Tvoid)
1209 { 1210 {
1210 if (offend && isMain()) 1211 if (offend && isMain())
1211 { // Add a return 0; statement 1212 { // Add a return 0; statement
1212 Statement *s = new ReturnStatement(0, new IntegerExp(0)); 1213 Statement *s = new ReturnStatement(0, new IntegerExp(0));
1215 } 1216 }
1216 else 1217 else
1217 { 1218 {
1218 if (offend) 1219 if (offend)
1219 { Expression *e; 1220 { Expression *e;
1220 1221 #if DMDV1
1221 //warning(loc, "no return exp; or assert(0); at end of function"); 1222 warning(loc, "no return exp; or assert(0); at end of function");
1223 #else
1222 error("no return exp; or assert(0); at end of function"); 1224 error("no return exp; or assert(0); at end of function");
1223 1225 #endif
1224 if (global.params.useAssert && 1226 if (global.params.useAssert &&
1225 !global.params.useInline) 1227 !global.params.useInline)
1226 { /* Add an assert(0, msg); where the missing return 1228 { /* Add an assert(0, msg); where the missing return
1227 * should be. 1229 * should be.
1228 */ 1230 */
1410 } 1412 }
1411 } 1413 }
1412 1414
1413 fbody = new CompoundStatement(0, a); 1415 fbody = new CompoundStatement(0, a);
1414 1416
1415 #if IN_LLVM 1417 #if 0 // This seems to have been added in with dmd 2.032, see below
1416 // wrap body of synchronized functions in a synchronized statement 1418 // wrap body of synchronized functions in a synchronized statement
1417 if (isSynchronized()) 1419 if (isSynchronized())
1418 { 1420 {
1419 ClassDeclaration *cd = parent->isClassDeclaration(); 1421 ClassDeclaration *cd = parent->isClassDeclaration();
1420 if (!cd) 1422 if (!cd)
1448 a = new Statements; 1450 a = new Statements;
1449 a->push(s); 1451 a->push(s);
1450 fbody = new CompoundStatement(0, a); 1452 fbody = new CompoundStatement(0, a);
1451 } 1453 }
1452 #endif 1454 #endif
1453 1455 #if DMDV2
1454 /* Append destructor calls for parameters as finally blocks. 1456 /* Append destructor calls for parameters as finally blocks.
1455 */ 1457 */
1456 if (parameters) 1458 if (parameters)
1457 { for (size_t i = 0; i < parameters->dim; i++) 1459 { for (size_t i = 0; i < parameters->dim; i++)
1458 { 1460 {
1477 else 1479 else
1478 fbody = new TryFinallyStatement(0, fbody, s); 1480 fbody = new TryFinallyStatement(0, fbody, s);
1479 } 1481 }
1480 } 1482 }
1481 } 1483 }
1484 #endif
1485
1486 #if 1
1487 if (isSynchronized())
1488 { /* Wrap the entire function body in a synchronized statement
1489 */
1490 ClassDeclaration *cd = parent->isClassDeclaration();
1491 if (cd)
1492 {
1493 #if TARGET_WINDOS
1494 if (/*config.flags2 & CFG2seh &&*/ // always on for WINDOS
1495 !isStatic() && !fbody->usesEH())
1496 {
1497 /* The back end uses the "jmonitor" hack for syncing;
1498 * no need to do the sync at this level.
1499 */
1500 }
1501 else
1502 #endif
1503 {
1504 Expression *vsync;
1505 if (isStatic())
1506 { // The monitor is in the ClassInfo
1507 vsync = new DotIdExp(loc, new DsymbolExp(loc, cd), Id::classinfo);
1508 }
1509 else
1510 { // 'this' is the monitor
1511 vsync = new VarExp(loc, vthis);
1512 }
1513 fbody = new PeelStatement(fbody); // don't redo semantic()
1514 fbody = new SynchronizedStatement(loc, vsync, fbody);
1515 fbody = fbody->semantic(sc2);
1516 }
1517 }
1518 else
1519 {
1520 error("synchronized function %s must be a member of a class", toChars());
1521 }
1522 }
1523 #endif
1482 } 1524 }
1483 1525
1484 sc2->callSuper = 0; 1526 sc2->callSuper = 0;
1485 sc2->pop(); 1527 sc2->pop();
1486 } 1528 }
1912 } 1954 }
1913 else 1955 else
1914 { 1956 {
1915 OutBuffer buf; 1957 OutBuffer buf;
1916 1958
1959 buf.writeByte('(');
1917 if (arguments) 1960 if (arguments)
1918 { 1961 {
1919 HdrGenState hgs; 1962 HdrGenState hgs;
1920 1963
1921 argExpTypesToCBuffer(&buf, arguments, &hgs); 1964 argExpTypesToCBuffer(&buf, arguments, &hgs);
1922 } 1965 buf.writeByte(')');
1966 if (ethis)
1967 ethis->type->modToBuffer(&buf);
1968 }
1969 else
1970 buf.writeByte(')');
1923 1971
1924 if (m.last == MATCHnomatch) 1972 if (m.last == MATCHnomatch)
1925 { 1973 {
1926 if (flags & 1) // if do not print error messages 1974 if (flags & 1) // if do not print error messages
1927 return NULL; // no match 1975 return NULL; // no match
1928 1976
1929 tf = (TypeFunction *)type; 1977 tf = (TypeFunction *)type;
1930 1978
1979 OutBuffer buf2;
1980 tf->modToBuffer(&buf2);
1981
1931 //printf("tf = %s, args = %s\n", tf->deco, ((Expression *)arguments->data[0])->type->deco); 1982 //printf("tf = %s, args = %s\n", tf->deco, ((Expression *)arguments->data[0])->type->deco);
1932 error(loc, "%s does not match parameter types (%s)", 1983 error(loc, "%s%s is not callable using argument types %s",
1933 Argument::argsTypesToChars(tf->parameters, tf->varargs), 1984 Argument::argsTypesToChars(tf->parameters, tf->varargs),
1985 buf2.toChars(),
1934 buf.toChars()); 1986 buf.toChars());
1935 return m.anyf; // as long as it's not a FuncAliasDeclaration 1987 return m.anyf; // as long as it's not a FuncAliasDeclaration
1936 } 1988 }
1937 else 1989 else
1938 { 1990 {
2200 else 2252 else
2201 fbody = new CompoundStatement(0, fbody, s); 2253 fbody = new CompoundStatement(0, fbody, s);
2202 } 2254 }
2203 } 2255 }
2204 2256
2257 const char *FuncDeclaration::toPrettyChars()
2258 {
2259 if (isMain())
2260 return "D main";
2261 else
2262 return Dsymbol::toPrettyChars();
2263 }
2205 2264
2206 int FuncDeclaration::isMain() 2265 int FuncDeclaration::isMain()
2207 { 2266 {
2208 return ident == Id::main && 2267 return ident == Id::main &&
2209 linkage != LINKc && !isMember() && !isNested(); 2268 linkage != LINKc && !isMember() && !isNested();