Mercurial > projects > ldc
comparison dmd2/func.c @ 1526:54b3c1394d62
Merged dmdfe 2.031.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Tue, 07 Jul 2009 02:26:11 +0100 |
parents | f62347c22d81 |
children | e4f7b5d9c68a |
comparison
equal
deleted
inserted
replaced
1525:d28cd7c45267 | 1526:54b3c1394d62 |
---|---|
1 // Compiler implementation of the D programming language | 1 // Compiler implementation of the D programming language |
2 // Copyright (c) 1999-2008 by Digital Mars | 2 // Copyright (c) 1999-2009 by Digital Mars |
3 // All Rights Reserved | 3 // All Rights Reserved |
4 // written by Walter Bright | 4 // written by Walter Bright |
5 // http://www.digitalmars.com | 5 // http://www.digitalmars.com |
6 // License for redistribution is by either the Artistic License | 6 // License for redistribution is by either the Artistic License |
7 // in artistic.txt, or the GNU General Public License in gnu.txt. | 7 // in artistic.txt, or the GNU General Public License in gnu.txt. |
62 inlineStatus = ILSuninitialized; | 62 inlineStatus = ILSuninitialized; |
63 inlineNest = 0; | 63 inlineNest = 0; |
64 inlineAsm = 0; | 64 inlineAsm = 0; |
65 cantInterpret = 0; | 65 cantInterpret = 0; |
66 semanticRun = 0; | 66 semanticRun = 0; |
67 #if DMDV1 | |
68 nestedFrameRef = 0; | |
69 #endif | |
67 fes = NULL; | 70 fes = NULL; |
68 introducing = 0; | 71 introducing = 0; |
69 tintro = NULL; | 72 tintro = NULL; |
70 /* The type given for "infer the return type" is a TypeFunction with | 73 /* The type given for "infer the return type" is a TypeFunction with |
71 * NULL for the return type. | 74 * NULL for the return type. |
72 */ | 75 */ |
73 inferRetType = (type && type->nextOf() == NULL); | 76 inferRetType = (type && type->nextOf() == NULL); |
74 scope = NULL; | |
75 hasReturnExp = 0; | 77 hasReturnExp = 0; |
76 nrvo_can = 1; | 78 nrvo_can = 1; |
77 nrvo_var = NULL; | 79 nrvo_var = NULL; |
78 #if IN_DMD | 80 #if IN_DMD |
79 shidden = NULL; | 81 shidden = NULL; |
80 #endif | 82 #endif |
81 | 83 #if DMDV2 |
82 builtin = BUILTINunknown; | 84 builtin = BUILTINunknown; |
83 tookAddressOf = 0; | 85 tookAddressOf = 0; |
84 | 86 #endif |
85 #if IN_LLVM | 87 #if IN_LLVM |
86 // LDC | 88 // LDC |
87 isArrayOp = false; | 89 isArrayOp = false; |
88 allowInlining = false; | 90 allowInlining = false; |
89 | 91 |
123 f->frequire = frequire ? frequire->syntaxCopy() : NULL; | 125 f->frequire = frequire ? frequire->syntaxCopy() : NULL; |
124 f->fensure = fensure ? fensure->syntaxCopy() : NULL; | 126 f->fensure = fensure ? fensure->syntaxCopy() : NULL; |
125 f->fbody = fbody ? fbody->syntaxCopy() : NULL; | 127 f->fbody = fbody ? fbody->syntaxCopy() : NULL; |
126 assert(!fthrows); // deprecated | 128 assert(!fthrows); // deprecated |
127 | 129 |
128 // LDC | 130 #if IN_LLVM |
129 f->intrinsicName = intrinsicName; | 131 f->intrinsicName = intrinsicName; |
132 #endif | |
130 | 133 |
131 return f; | 134 return f; |
132 } | 135 } |
133 | 136 |
134 | 137 |
164 storage_class |= sc->stc & ~STCref; | 167 storage_class |= sc->stc & ~STCref; |
165 //printf("function storage_class = x%x\n", storage_class); | 168 //printf("function storage_class = x%x\n", storage_class); |
166 | 169 |
167 if (!originalType) | 170 if (!originalType) |
168 originalType = type; | 171 originalType = type; |
169 if (!type->deco && type->nextOf()) | 172 if (!type->deco) |
170 { | 173 { |
171 /* Apply const and invariant storage class | 174 /* Apply const and invariant storage class |
172 * to the function type | 175 * to the function type |
173 */ | 176 */ |
174 type = type->semantic(loc, sc); | 177 type = type->semantic(loc, sc); |
302 if (id) | 305 if (id) |
303 { | 306 { |
304 storage_class |= STCabstract; | 307 storage_class |= STCabstract; |
305 | 308 |
306 if (isCtorDeclaration() || | 309 if (isCtorDeclaration() || |
310 #if DMDV2 | |
307 isPostBlitDeclaration() || | 311 isPostBlitDeclaration() || |
312 #endif | |
308 isDtorDeclaration() || | 313 isDtorDeclaration() || |
309 isInvariantDeclaration() || | 314 isInvariantDeclaration() || |
310 isUnitTestDeclaration() || isNewDeclaration() || isDelete()) | 315 isUnitTestDeclaration() || isNewDeclaration() || isDelete()) |
311 error("special function not allowed in interface %s", id->toChars()); | 316 error("special function not allowed in interface %s", id->toChars()); |
312 if (fbody) | 317 if (fbody) |
876 if (f->parameters) | 881 if (f->parameters) |
877 { | 882 { |
878 for (size_t i = 0; i < f->parameters->dim; i++) | 883 for (size_t i = 0; i < f->parameters->dim; i++) |
879 { Argument *arg = (Argument *)f->parameters->data[i]; | 884 { Argument *arg = (Argument *)f->parameters->data[i]; |
880 | 885 |
886 //printf("[%d] arg->type->ty = %d %s\n", i, arg->type->ty, arg->type->toChars()); | |
881 if (arg->type->ty == Ttuple) | 887 if (arg->type->ty == Ttuple) |
882 { TypeTuple *t = (TypeTuple *)arg->type; | 888 { TypeTuple *t = (TypeTuple *)arg->type; |
883 size_t dim = Argument::dim(t->arguments); | 889 size_t dim = Argument::dim(t->arguments); |
884 for (size_t j = 0; j < dim; j++) | 890 for (size_t j = 0; j < dim; j++) |
885 { Argument *narg = Argument::getNth(t->arguments, j); | 891 { Argument *narg = Argument::getNth(t->arguments, j); |
1006 if (fensure) | 1012 if (fensure) |
1007 loc = fensure->loc; | 1013 loc = fensure->loc; |
1008 | 1014 |
1009 v = new VarDeclaration(loc, type->nextOf(), outId, NULL); | 1015 v = new VarDeclaration(loc, type->nextOf(), outId, NULL); |
1010 v->noauto = 1; | 1016 v->noauto = 1; |
1017 #if DMDV2 | |
1018 if (f->isref) | |
1019 { | |
1020 v->storage_class |= STCref | STCforeach; | |
1021 } | |
1022 #endif | |
1011 sc2->incontract--; | 1023 sc2->incontract--; |
1012 v->semantic(sc2); | 1024 v->semantic(sc2); |
1013 sc2->incontract++; | 1025 sc2->incontract++; |
1014 if (!sc2->insert(v)) | 1026 if (!sc2->insert(v)) |
1015 error("out result %s is already defined", v->toChars()); | 1027 error("out result %s is already defined", v->toChars()); |
1106 | 1118 |
1107 if (inferRetType || f->retStyle() != RETstack) | 1119 if (inferRetType || f->retStyle() != RETstack) |
1108 nrvo_can = 0; | 1120 nrvo_can = 0; |
1109 | 1121 |
1110 fbody = fbody->semantic(sc2); | 1122 fbody = fbody->semantic(sc2); |
1123 if (!fbody) | |
1124 fbody = new CompoundStatement(0, new Statements()); | |
1111 | 1125 |
1112 if (inferRetType) | 1126 if (inferRetType) |
1113 { // If no return type inferred yet, then infer a void | 1127 { // If no return type inferred yet, then infer a void |
1114 if (!type->nextOf()) | 1128 if (!type->nextOf()) |
1115 { | 1129 { |
1183 } | 1197 } |
1184 else if (!hasReturnExp && type->nextOf()->ty != Tvoid) | 1198 else if (!hasReturnExp && type->nextOf()->ty != Tvoid) |
1185 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()); |
1186 else if (!inlineAsm) | 1200 else if (!inlineAsm) |
1187 { | 1201 { |
1188 int blockexit = fbody ? fbody->blockExit() : 0; | 1202 int blockexit = fbody ? fbody->blockExit() : BEfallthru; |
1189 if (f->isnothrow && blockexit & BEthrow) | 1203 if (f->isnothrow && blockexit & BEthrow) |
1190 error("'%s' is nothrow yet may throw", toChars()); | 1204 error("'%s' is nothrow yet may throw", toChars()); |
1191 | 1205 |
1192 int offend = blockexit & BEfallthru; | 1206 int offend = blockexit & BEfallthru; |
1193 | 1207 |
1202 else | 1216 else |
1203 { | 1217 { |
1204 if (offend) | 1218 if (offend) |
1205 { Expression *e; | 1219 { Expression *e; |
1206 | 1220 |
1207 warning(loc, "no return at end of function"); | 1221 //warning(loc, "no return exp; or assert(0); at end of function"); |
1222 error("no return exp; or assert(0); at end of function"); | |
1208 | 1223 |
1209 if (global.params.useAssert && | 1224 if (global.params.useAssert && |
1210 !global.params.useInline) | 1225 !global.params.useInline) |
1211 { /* Add an assert(0, msg); where the missing return | 1226 { /* Add an assert(0, msg); where the missing return |
1212 * should be. | 1227 * should be. |
2167 s = new ExpStatement(0, e); | 2182 s = new ExpStatement(0, e); |
2168 appendState(s); | 2183 appendState(s); |
2169 } | 2184 } |
2170 | 2185 |
2171 void FuncDeclaration::appendState(Statement *s) | 2186 void FuncDeclaration::appendState(Statement *s) |
2172 { CompoundStatement *cs; | 2187 { |
2173 | |
2174 if (!fbody) | 2188 if (!fbody) |
2175 { Statements *a; | 2189 fbody = s; |
2176 | 2190 else |
2177 a = new Statements(); | 2191 { |
2178 fbody = new CompoundStatement(0, a); | 2192 CompoundStatement *cs = fbody->isCompoundStatement(); |
2179 } | 2193 if (cs) |
2180 cs = fbody->isCompoundStatement(); | 2194 { |
2181 cs->statements->push(s); | 2195 if (!cs->statements) |
2196 fbody = s; | |
2197 else | |
2198 cs->statements->push(s); | |
2199 } | |
2200 else | |
2201 fbody = new CompoundStatement(0, fbody, s); | |
2202 } | |
2182 } | 2203 } |
2183 | 2204 |
2184 | 2205 |
2185 int FuncDeclaration::isMain() | 2206 int FuncDeclaration::isMain() |
2186 { | 2207 { |
2633 bodyToCBuffer(buf, hgs); | 2654 bodyToCBuffer(buf, hgs); |
2634 } | 2655 } |
2635 | 2656 |
2636 /********************************* PostBlitDeclaration ****************************/ | 2657 /********************************* PostBlitDeclaration ****************************/ |
2637 | 2658 |
2659 #if DMDV2 | |
2638 PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc) | 2660 PostBlitDeclaration::PostBlitDeclaration(Loc loc, Loc endloc) |
2639 : FuncDeclaration(loc, endloc, Id::_postblit, STCundefined, NULL) | 2661 : FuncDeclaration(loc, endloc, Id::_postblit, STCundefined, NULL) |
2640 { | 2662 { |
2641 } | 2663 } |
2642 | 2664 |
2702 if (hgs->hdrgen) | 2724 if (hgs->hdrgen) |
2703 return; | 2725 return; |
2704 buf->writestring("=this()"); | 2726 buf->writestring("=this()"); |
2705 bodyToCBuffer(buf, hgs); | 2727 bodyToCBuffer(buf, hgs); |
2706 } | 2728 } |
2729 #endif | |
2707 | 2730 |
2708 /********************************* DtorDeclaration ****************************/ | 2731 /********************************* DtorDeclaration ****************************/ |
2709 | 2732 |
2710 DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc) | 2733 DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc) |
2711 : FuncDeclaration(loc, endloc, Id::dtor, STCundefined, NULL) | 2734 : FuncDeclaration(loc, endloc, Id::dtor, STCundefined, NULL) |