Changeset 294
- Timestamp:
- 12/15/09 05:53:21 (15 years ago)
- Files:
-
- branches/dmd-1.x/src/expression.h (modified) (1 diff)
- branches/dmd-1.x/src/staticassert.c (modified) (1 diff)
- branches/dmd-1.x/src/template.c (modified) (5 diffs)
- branches/dmd-1.x/src/template.h (modified) (1 diff)
- trunk/src/staticassert.c (modified) (1 diff)
- trunk/src/template.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmd-1.x/src/expression.h
r253 r294 1223 1223 1224 1224 elem *toElem(IRState *irs); 1225 1225 }; 1226 1226 1227 1227 struct ModExp : BinExp 1228 1228 { 1229 1229 ModExp(Loc loc, Expression *e1, Expression *e2); 1230 1230 Expression *semantic(Scope *sc); 1231 1231 Expression *optimize(int result); 1232 1232 Expression *interpret(InterState *istate); 1233 1233 void buildArrayIdent(OutBuffer *buf, Expressions *arguments); 1234 1234 Expression *buildArrayLoop(Parameters *fparams); 1235 1235 1236 1236 // For operator overloading 1237 1237 Identifier *opId(); 1238 1238 Identifier *opId_r(); 1239 1239 1240 1240 elem *toElem(IRState *irs); 1241 1241 }; 1242 1242 1243 #if DMDV2 1244 struct PowExp : BinExp 1245 { 1246 PowExp(Loc loc, Expression *e1, Expression *e2); 1247 Expression *semantic(Scope *sc); 1248 1249 // For operator overloading 1250 Identifier *opId(); 1251 Identifier *opId_r(); 1252 }; 1253 #endif 1254 1243 1255 struct ShlExp : BinExp 1244 1256 { 1245 1257 ShlExp(Loc loc, Expression *e1, Expression *e2); 1246 1258 Expression *semantic(Scope *sc); 1247 1259 Expression *optimize(int result); 1248 1260 Expression *interpret(InterState *istate); 1249 1261 1250 1262 // For operator overloading 1251 1263 Identifier *opId(); 1252 1264 Identifier *opId_r(); 1253 1265 1254 1266 elem *toElem(IRState *irs); 1255 1267 }; 1256 1268 1257 1269 struct ShrExp : BinExp 1258 1270 { 1259 1271 ShrExp(Loc loc, Expression *e1, Expression *e2); 1260 1272 Expression *semantic(Scope *sc); 1261 1273 Expression *optimize(int result); 1262 1274 Expression *interpret(InterState *istate); branches/dmd-1.x/src/staticassert.c
r189 r294 1 1 2 2 // Copyright (c) 1999-2007 by Digital Mars 3 3 // All Rights Reserved 4 4 // written by Walter Bright 5 5 // http://www.digitalmars.com 6 6 // License for redistribution is by either the Artistic License 7 7 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 8 // See the included readme.txt for details. 9 9 10 10 #include <stdio.h> 11 11 #include <string.h> 12 12 #include <assert.h> 13 13 14 14 #include "dsymbol.h" 15 15 #include "staticassert.h" 16 16 #include "expression.h" 17 17 #include "id.h" 18 18 #include "hdrgen.h" 19 19 #include "scope.h" 20 20 #include "template.h" 21 #include "declaration.h" 21 22 22 23 23 24 /********************************* AttribDeclaration ****************************/ 24 25 25 26 StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg) 26 27 : Dsymbol(Id::empty) 27 28 { 28 29 this->loc = loc; 29 30 this->exp = exp; 30 31 this->msg = msg; 31 32 } 32 33 33 34 Dsymbol *StaticAssert::syntaxCopy(Dsymbol *s) 34 35 { 35 36 StaticAssert *sa; 36 37 37 38 assert(!s); 38 39 sa = new StaticAssert(loc, exp->syntaxCopy(), msg ? msg->syntaxCopy() : NULL); 39 40 return sa; 40 41 } 41 42 42 43 int StaticAssert::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) 43 44 { 44 45 return 0; // we didn't add anything 45 46 } 46 47 47 48 void StaticAssert::semantic(Scope *sc) 48 49 { 49 50 } 50 51 51 #include "scope.h"52 #include "template.h"53 #include "declaration.h"54 55 52 void StaticAssert::semantic2(Scope *sc) 56 53 { 57 54 Expression *e; 58 55 59 56 //printf("StaticAssert::semantic2() %s\n", toChars()); 60 57 e = exp->semantic(sc); 61 58 e = e->optimize(WANTvalue | WANTinterpret); 62 59 if (e->isBool(FALSE)) 63 60 { 64 61 if (msg) 65 62 { HdrGenState hgs; 66 63 OutBuffer buf; 67 64 68 65 msg = msg->semantic(sc); 69 66 msg = msg->optimize(WANTvalue | WANTinterpret); 70 67 hgs.console = 1; 71 68 msg->toCBuffer(&buf, &hgs); 72 69 error("%s", buf.toChars()); 73 70 } 74 71 else 75 72 error("(%s) is false", exp->toChars()); 76 if(sc->tinst)73 if (sc->tinst) 77 74 sc->tinst->printInstantiationTrace(); 78 if (!global.gag) {75 if (!global.gag) 79 76 fatal(); 80 }81 77 } 82 78 else if (!e->isBool(TRUE)) 83 79 { 84 80 error("(%s) is not evaluatable at compile time", exp->toChars()); 85 81 } 86 82 } 87 83 88 84 int StaticAssert::oneMember(Dsymbol **ps) 89 85 { 90 86 //printf("StaticAssert::oneMember())\n"); 91 87 *ps = NULL; 92 88 return TRUE; 93 89 } 94 90 95 91 void StaticAssert::inlineScan() 96 92 { 97 93 } 98 94 99 95 void StaticAssert::toObjFile(int multiobj) 100 96 { branches/dmd-1.x/src/template.c
r276 r294 3438 3438 { Dsymbol *sd = (Dsymbol *)Module::deferred.data[i]; 3439 3439 3440 3440 if (sd->parent == this) 3441 3441 goto Laftersemantic; 3442 3442 } 3443 3443 3444 3444 /* The problem is when to parse the initializer for a variable. 3445 3445 * Perhaps VarDeclaration::semantic() should do it like it does 3446 3446 * for initializers inside a function. 3447 3447 */ 3448 3448 // if (sc->parent->isFuncDeclaration()) 3449 3449 3450 3450 /* BUG 782: this has problems if the classes this depends on 3451 3451 * are forward referenced. Find a way to defer semantic() 3452 3452 * on this template. 3453 3453 */ 3454 3454 semantic2(sc2); 3455 3455 3456 3456 if (sc->func || dosemantic3) 3457 3457 { 3458 semantic3(sc2); 3458 #if WINDOWS_SEH 3459 __try 3460 { 3461 #endif 3462 static int nest; 3463 if (++nest > 300) 3464 { 3465 global.gag = 0; // ensure error message gets printed 3466 error("recursive expansion"); 3467 fatal(); 3468 } 3469 semantic3(sc2); 3470 --nest; 3471 #if WINDOWS_SEH 3472 } 3473 __except (__ehfilter(GetExceptionInformation())) 3474 { 3475 global.gag = 0; // ensure error message gets printed 3476 error("recursive expansion"); 3477 fatal(); 3478 } 3479 #endif 3459 3480 } 3460 3481 3461 3482 Laftersemantic: 3462 3483 sc2->pop(); 3463 3484 3464 3485 scope->pop(); 3465 3486 3466 3487 // Give additional context info if error occurred during instantiation 3467 3488 if (global.errors != errorsave) 3468 3489 { 3469 3490 error("error instantiating"); 3470 if (tinst && !global.gag)3491 if (tinst) 3471 3492 { tinst->printInstantiationTrace(); 3472 3493 fatal(); 3473 3494 } 3474 3495 errors = 1; 3475 3496 if (global.gag) 3476 3497 tempdecl->instances.remove(tempdecl_instance_idx); 3477 3498 } 3478 3499 3479 3500 #if LOG 3480 3501 printf("-TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); 3481 3502 #endif 3482 3503 } 3483 3504 3484 3505 3485 3506 void TemplateInstance::semanticTiargs(Scope *sc) 3486 3507 { 3487 3508 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars()); 3488 3509 if (semantictiargsdone) 3489 3510 return; 3490 3511 semantictiargsdone = 1; … … 3613 3634 * Find template declaration corresponding to template instance. 3614 3635 */ 3615 3636 3616 3637 TemplateDeclaration *TemplateInstance::findTemplateDeclaration(Scope *sc) 3617 3638 { 3618 3639 //printf("TemplateInstance::findTemplateDeclaration() %s\n", toChars()); 3619 3640 if (!tempdecl) 3620 3641 { 3621 3642 /* Given: 3622 3643 * foo!( ... ) 3623 3644 * figure out which TemplateDeclaration foo refers to. 3624 3645 */ 3625 3646 Dsymbol *s; 3626 3647 Dsymbol *scopesym; 3627 3648 Identifier *id; 3628 3649 int i; 3629 3650 3630 3651 id = name; 3631 3652 s = sc->search(loc, id, &scopesym); 3632 3653 if (!s) 3633 { error(" identifier'%s' is not defined", id->toChars());3654 { error("template '%s' is not defined", id->toChars()); 3634 3655 return NULL; 3635 3656 } 3636 3657 #if LOG 3637 3658 printf("It's an instance of '%s' kind '%s'\n", s->toChars(), s->kind()); 3638 3659 if (s->parent) 3639 3660 printf("s->parent = '%s'\n", s->parent->toChars()); 3640 3661 #endif 3641 3662 withsym = scopesym->isWithScopeSymbol(); 3642 3663 3643 3664 /* We might have found an alias within a template when 3644 3665 * we really want the template. 3645 3666 */ 3646 3667 TemplateInstance *ti; 3647 3668 if (s->parent && 3648 3669 (ti = s->parent->isTemplateInstance()) != NULL) 3649 3670 { 3650 3671 if ( 3651 3672 (ti->name == id || 3652 3673 ti->toAlias()->ident == id) 3653 3674 && … … 3919 3940 else 3920 3941 error("cannot use local '%s' as parameter to non-global template %s", d->toChars(), tempdecl->toChars()); 3921 3942 } 3922 3943 } 3923 3944 else if (va) 3924 3945 { 3925 3946 nested |= hasNestedArgs(&va->objects); 3926 3947 } 3927 3948 } 3928 3949 return nested; 3929 3950 } 3930 3951 3931 3952 /**************************************** 3932 3953 * This instance needs an identifier for name mangling purposes. 3933 3954 * Create one by taking the template declaration name and adding 3934 3955 * the type signature for it. 3935 3956 */ 3936 3957 3937 3958 Identifier *TemplateInstance::genIdent() 3938 3959 { OutBuffer buf; 3939 char *id;3940 Objects *args;3941 3960 3942 3961 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); 3943 id = tempdecl->ident->toChars();3962 char *id = tempdecl->ident->toChars(); 3944 3963 buf.printf("__T%zu%s", strlen(id), id); 3945 args = tiargs;3964 Objects *args = tiargs; 3946 3965 for (int i = 0; i < args->dim; i++) 3947 3966 { Object *o = (Object *)args->data[i]; 3948 3967 Type *ta = isType(o); 3949 3968 Expression *ea = isExpression(o); 3950 3969 Dsymbol *sa = isDsymbol(o); 3951 3970 Tuple *va = isTuple(o); 3952 //printf("\to %p ta %p ea %p sa %p va %p\n", o, ta, ea, sa, va);3971 //printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va); 3953 3972 if (ta) 3954 3973 { 3955 3974 buf.writeByte('T'); 3956 3975 if (ta->deco) 3957 3976 buf.writestring(ta->deco); 3958 3977 else 3959 3978 { 3960 3979 #ifdef DEBUG 3961 3980 printf("ta = %d, %s\n", ta->ty, ta->toChars()); 3962 3981 #endif 3963 3982 assert(global.errors); 3964 3983 } 3965 3984 } 3966 3985 else if (ea) 3967 3986 { sinteger_t v; 3968 3987 real_t r; 3969 3988 3970 3989 ea = ea->optimize(WANTvalue | WANTinterpret); 3971 3990 if (ea->op == TOKvar) 3972 3991 { … … 4130 4149 //if (toChars()[0] == 'D') *(char*)0=0; 4131 4150 if (semanticRun >= 3) 4132 4151 return; 4133 4152 semanticRun = 3; 4134 4153 if (!errors && members) 4135 4154 { 4136 4155 sc = tempdecl->scope; 4137 4156 sc = sc->push(argsym); 4138 4157 sc = sc->push(this); 4139 4158 sc->tinst = this; 4140 4159 for (int i = 0; i < members->dim; i++) 4141 4160 { 4142 4161 Dsymbol *s = (Dsymbol *)members->data[i]; 4143 4162 s->semantic3(sc); 4144 4163 } 4145 4164 sc = sc->pop(); 4146 4165 sc->pop(); 4147 4166 } 4148 4167 } 4149 4168 4169 /************************************** 4170 * Given an error instantiating the TemplateInstance, 4171 * give the nested TemplateInstance instantiations that got 4172 * us here. Those are a list threaded into the nested scopes. 4173 */ 4150 4174 void TemplateInstance::printInstantiationTrace() 4151 4175 { 4152 4176 if (global.gag) 4153 4177 return; 4178 4179 const int max_shown = 6; 4180 const char format[] = "%s: instantiated from here: %s\n"; 4181 4182 // determine instantiation depth and number of recursive instantiations 4183 int n_instantiations = 1; 4184 int n_totalrecursions = 0; 4185 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 4186 { 4187 ++n_instantiations; 4188 // If two instantiations use the same declaration, they are recursive. 4189 // (this works even if they are instantiated from different places in the 4190 // same template). 4191 // In principle, we could also check for multiple-template recursion, but it's 4192 // probably not worthwhile. 4193 if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl 4194 && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) 4195 ++n_totalrecursions; 4196 } 4197 4198 // show full trace only if it's short or verbose is on 4199 if (n_instantiations <= max_shown || global.params.verbose) 4200 { 4201 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 4202 { 4203 fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); 4204 } 4205 } 4206 else if (n_instantiations - n_totalrecursions <= max_shown) 4207 { 4208 // By collapsing recursive instantiations into a single line, 4209 // we can stay under the limit. 4210 int recursionDepth=0; 4211 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 4212 { 4213 if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl 4214 && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) 4215 { 4216 ++recursionDepth; 4217 } 4218 else 4219 { 4220 if (recursionDepth) 4221 fprintf(stdmsg, "%s: %d recursive instantiations from here: %s\n", cur->loc.toChars(), recursionDepth+2, cur->toChars()); 4222 else 4223 fprintf(stdmsg,format, cur->loc.toChars(), cur->toChars()); 4224 recursionDepth = 0; 4225 } 4226 } 4227 } 4228 else 4229 { 4230 // Even after collapsing the recursions, the depth is too deep. 4231 // Just display the first few and last few instantiations. 4232 size_t i = 0; 4233 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 4234 { 4235 if (i == max_shown / 2) 4236 fprintf(stdmsg," ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown); 4237 4238 if (i < max_shown / 2 || 4239 i >= n_instantiations - max_shown + max_shown / 2) 4240 fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); 4241 ++i; 4242 } 4243 } 4154 4244 } 4155 4245 4156 4246 void TemplateInstance::toObjFile(int multiobj) 4157 4247 { 4158 4248 #if LOG 4159 4249 printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this); 4160 4250 #endif 4161 4251 if (!errors && members) 4162 4252 { 4163 4253 if (multiobj) 4164 4254 // Append to list of object files to be written later 4165 4255 obj_append(this); 4166 4256 else 4167 4257 { 4168 4258 for (int i = 0; i < members->dim; i++) 4169 4259 { 4170 4260 Dsymbol *s = (Dsymbol *)members->data[i]; 4171 4261 s->toObjFile(multiobj); 4172 4262 } 4173 4263 } … … 4213 4303 } 4214 4304 buf->writeByte(')'); 4215 4305 } 4216 4306 4217 4307 4218 4308 Dsymbol *TemplateInstance::toAlias() 4219 4309 { 4220 4310 #if LOG 4221 4311 printf("TemplateInstance::toAlias()\n"); 4222 4312 #endif 4223 4313 if (!inst) 4224 4314 { error("cannot resolve forward reference"); 4225 4315 errors = 1; 4226 4316 return this; 4227 4317 } 4228 4318 4229 4319 if (inst != this) 4230 4320 return inst->toAlias(); 4231 4321 4232 4322 if (aliasdecl) 4323 { 4233 4324 return aliasdecl->toAlias(); 4325 } 4234 4326 4235 4327 return inst; 4236 4328 } 4237 4329 4238 4330 AliasDeclaration *TemplateInstance::isAliasDeclaration() 4239 4331 { 4240 4332 return aliasdecl; 4241 4333 } 4242 4334 4243 4335 const char *TemplateInstance::kind() 4244 4336 { 4245 4337 return "template instance"; 4246 4338 } 4247 4339 4248 4340 int TemplateInstance::oneMember(Dsymbol **ps) 4249 4341 { 4250 4342 *ps = NULL; 4251 4343 return TRUE; 4252 4344 } 4253 4345 branches/dmd-1.x/src/template.h
r274 r294 68 68 int overloadInsert(Dsymbol *s); 69 69 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 70 70 const char *kind(); 71 71 char *toChars(); 72 72 73 73 void emitComment(Scope *sc); 74 74 void toJsonBuffer(OutBuffer *buf); 75 75 // void toDocBuffer(OutBuffer *buf); 76 76 77 77 MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag); 78 78 MATCH leastAsSpecialized(TemplateDeclaration *td2); 79 79 80 80 MATCH deduceFunctionTemplateMatch(Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, Objects *dedargs); 81 81 FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, int flags = 0); 82 82 void declareParameter(Scope *sc, TemplateParameter *tp, Object *o); 83 83 84 84 TemplateDeclaration *isTemplateDeclaration() { return this; } 85 85 86 86 TemplateTupleParameter *isVariadic(); 87 87 int isOverloadable(); 88 89 void makeParamNamesVisibleInConstraint(Scope *paramscope); 88 90 }; 89 91 90 92 struct TemplateParameter 91 93 { 92 94 /* For type-parameter: 93 95 * template Foo(ident) // specType is set to NULL 94 96 * template Foo(ident : specType) 95 97 * For value-parameter: 96 98 * template Foo(valType ident) // specValue is set to NULL 97 99 * template Foo(valType ident : specValue) 98 100 * For alias-parameter: 99 101 * template Foo(alias ident) 100 102 * For this-parameter: 101 103 * template Foo(this ident) 102 104 */ 103 105 104 106 Loc loc; 105 107 Identifier *ident; 106 108 107 109 Declaration *sparam; trunk/src/staticassert.c
r189 r294 1 1 2 2 // Copyright (c) 1999-2007 by Digital Mars 3 3 // All Rights Reserved 4 4 // written by Walter Bright 5 5 // http://www.digitalmars.com 6 6 // License for redistribution is by either the Artistic License 7 7 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 8 // See the included readme.txt for details. 9 9 10 10 #include <stdio.h> 11 11 #include <string.h> 12 12 #include <assert.h> 13 13 14 14 #include "dsymbol.h" 15 15 #include "staticassert.h" 16 16 #include "expression.h" 17 17 #include "id.h" 18 18 #include "hdrgen.h" 19 19 #include "scope.h" 20 20 #include "template.h" 21 #include "declaration.h" 21 22 22 23 23 24 /********************************* AttribDeclaration ****************************/ 24 25 25 26 StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg) 26 27 : Dsymbol(Id::empty) 27 28 { 28 29 this->loc = loc; 29 30 this->exp = exp; 30 31 this->msg = msg; 31 32 } 32 33 33 34 Dsymbol *StaticAssert::syntaxCopy(Dsymbol *s) 34 35 { 35 36 StaticAssert *sa; 36 37 37 38 assert(!s); 38 39 sa = new StaticAssert(loc, exp->syntaxCopy(), msg ? msg->syntaxCopy() : NULL); 39 40 return sa; 40 41 } 41 42 42 43 int StaticAssert::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) 43 44 { 44 45 return 0; // we didn't add anything 45 46 } 46 47 47 48 void StaticAssert::semantic(Scope *sc) 48 49 { 49 50 } 50 51 51 #include "scope.h"52 #include "template.h"53 #include "declaration.h"54 55 52 void StaticAssert::semantic2(Scope *sc) 56 53 { 57 54 Expression *e; 58 55 59 56 //printf("StaticAssert::semantic2() %s\n", toChars()); 60 57 e = exp->semantic(sc); 61 58 e = e->optimize(WANTvalue | WANTinterpret); 62 59 if (e->isBool(FALSE)) 63 60 { 64 61 if (msg) 65 62 { HdrGenState hgs; 66 63 OutBuffer buf; 67 64 68 65 msg = msg->semantic(sc); 69 66 msg = msg->optimize(WANTvalue | WANTinterpret); 70 67 hgs.console = 1; 71 68 msg->toCBuffer(&buf, &hgs); 72 69 error("%s", buf.toChars()); 73 70 } 74 71 else 75 72 error("(%s) is false", exp->toChars()); 76 if(sc->tinst)73 if (sc->tinst) 77 74 sc->tinst->printInstantiationTrace(); 78 if (!global.gag) {75 if (!global.gag) 79 76 fatal(); 80 }81 77 } 82 78 else if (!e->isBool(TRUE)) 83 79 { 84 80 error("(%s) is not evaluatable at compile time", exp->toChars()); 85 81 } 86 82 } 87 83 88 84 int StaticAssert::oneMember(Dsymbol **ps) 89 85 { 90 86 //printf("StaticAssert::oneMember())\n"); 91 87 *ps = NULL; 92 88 return TRUE; 93 89 } 94 90 95 91 void StaticAssert::inlineScan() 96 92 { 97 93 } 98 94 99 95 void StaticAssert::toObjFile(int multiobj) 100 96 { trunk/src/template.c
r287 r294 3734 3734 #if WINDOWS_SEH 3735 3735 } 3736 3736 __except (__ehfilter(GetExceptionInformation())) 3737 3737 { 3738 3738 global.gag = 0; // ensure error message gets printed 3739 3739 error("recursive expansion"); 3740 3740 fatal(); 3741 3741 } 3742 3742 #endif 3743 3743 } 3744 3744 3745 3745 Laftersemantic: 3746 3746 sc2->pop(); 3747 3747 3748 3748 scope->pop(); 3749 3749 3750 3750 // Give additional context info if error occurred during instantiation 3751 3751 if (global.errors != errorsave) 3752 3752 { 3753 3753 error("error instantiating"); 3754 if (tinst && !global.gag)3754 if (tinst) 3755 3755 { tinst->printInstantiationTrace(); 3756 3756 fatal(); 3757 3757 } 3758 3758 errors = 1; 3759 3759 if (global.gag) 3760 3760 tempdecl->instances.remove(tempdecl_instance_idx); 3761 3761 } 3762 3762 3763 3763 #if LOG 3764 3764 printf("-TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); 3765 3765 #endif 3766 3766 } 3767 3767 3768 3768 3769 3769 void TemplateInstance::semanticTiargs(Scope *sc) 3770 3770 { 3771 3771 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars()); 3772 3772 if (semantictiargsdone) 3773 3773 return; 3774 3774 semantictiargsdone = 1; … … 4457 4457 //if (toChars()[0] == 'D') *(char*)0=0; 4458 4458 if (semanticRun >= 3) 4459 4459 return; 4460 4460 semanticRun = 3; 4461 4461 if (!errors && members) 4462 4462 { 4463 4463 sc = tempdecl->scope; 4464 4464 sc = sc->push(argsym); 4465 4465 sc = sc->push(this); 4466 4466 sc->tinst = this; 4467 4467 for (int i = 0; i < members->dim; i++) 4468 4468 { 4469 4469 Dsymbol *s = (Dsymbol *)members->data[i]; 4470 4470 s->semantic3(sc); 4471 4471 } 4472 4472 sc = sc->pop(); 4473 4473 sc->pop(); 4474 4474 } 4475 4475 } 4476 4476 4477 /************************************** 4478 * Given an error instantiating the TemplateInstance, 4479 * give the nested TemplateInstance instantiations that got 4480 * us here. Those are a list threaded into the nested scopes. 4481 */ 4477 4482 void TemplateInstance::printInstantiationTrace() 4478 4483 { 4479 4484 if (global.gag) 4480 4485 return; 4486 4487 const int max_shown = 6; 4488 const char format[] = "%s: instantiated from here: %s\n"; 4489 4490 // determine instantiation depth and number of recursive instantiations 4491 int n_instantiations = 1; 4492 int n_totalrecursions = 0; 4493 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 4494 { 4495 ++n_instantiations; 4496 // If two instantiations use the same declaration, they are recursive. 4497 // (this works even if they are instantiated from different places in the 4498 // same template). 4499 // In principle, we could also check for multiple-template recursion, but it's 4500 // probably not worthwhile. 4501 if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl 4502 && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) 4503 ++n_totalrecursions; 4504 } 4505 4506 // show full trace only if it's short or verbose is on 4507 if (n_instantiations <= max_shown || global.params.verbose) 4508 { 4509 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 4510 { 4511 fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); 4512 } 4513 } 4514 else if (n_instantiations - n_totalrecursions <= max_shown) 4515 { 4516 // By collapsing recursive instantiations into a single line, 4517 // we can stay under the limit. 4518 int recursionDepth=0; 4519 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 4520 { 4521 if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl 4522 && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) 4523 { 4524 ++recursionDepth; 4525 } 4526 else 4527 { 4528 if (recursionDepth) 4529 fprintf(stdmsg, "%s: %d recursive instantiations from here: %s\n", cur->loc.toChars(), recursionDepth+2, cur->toChars()); 4530 else 4531 fprintf(stdmsg,format, cur->loc.toChars(), cur->toChars()); 4532 recursionDepth = 0; 4533 } 4534 } 4535 } 4536 else 4537 { 4538 // Even after collapsing the recursions, the depth is too deep. 4539 // Just display the first few and last few instantiations. 4540 size_t i = 0; 4541 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 4542 { 4543 if (i == max_shown / 2) 4544 fprintf(stdmsg," ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown); 4545 4546 if (i < max_shown / 2 || 4547 i >= n_instantiations - max_shown + max_shown / 2) 4548 fprintf(stdmsg, format, cur->loc.toChars(), cur->toChars()); 4549 ++i; 4550 } 4551 } 4481 4552 } 4482 4553 4483 4554 void TemplateInstance::toObjFile(int multiobj) 4484 4555 { 4485 4556 #if LOG 4486 4557 printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this); 4487 4558 #endif 4488 4559 if (!errors && members) 4489 4560 { 4490 4561 if (multiobj) 4491 4562 // Append to list of object files to be written later 4492 4563 obj_append(this); 4493 4564 else 4494 4565 { 4495 4566 for (int i = 0; i < members->dim; i++) 4496 4567 { 4497 4568 Dsymbol *s = (Dsymbol *)members->data[i]; 4498 4569 s->toObjFile(multiobj); 4499 4570 } 4500 4571 }
