Mercurial > projects > ldc
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(); |