Changeset 811
- Timestamp:
- 12/22/10 09:01:22 (14 years ago)
- Files:
-
- trunk/src/mars.c (modified) (1 diff)
- trunk/src/template.c (modified) (2 diffs)
- trunk/src/template.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/mars.c
r737 r811 75 75 #else 76 76 #error "fix this" 77 77 #endif 78 78 79 79 #if TARGET_WINDOS 80 80 dll_ext = "dll"; 81 81 #elif TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS 82 82 dll_ext = "so"; 83 83 #elif TARGET_OSX 84 84 dll_ext = "dylib"; 85 85 #else 86 86 #error "fix this" 87 87 #endif 88 88 89 89 copyright = "Copyright (c) 1999-2010 by Digital Mars"; 90 90 written = "written by Walter Bright" 91 91 #if TARGET_NET 92 92 "\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates."; 93 93 #endif 94 94 ; 95 version = "v2.05 1";95 version = "v2.052"; 96 96 global.structalign = 8; 97 97 98 98 memset(¶ms, 0, sizeof(Param)); 99 99 } 100 100 101 101 char *Loc::toChars() 102 102 { 103 103 OutBuffer buf; 104 104 char *p; 105 105 106 106 if (filename) 107 107 { 108 108 buf.printf("%s", filename); 109 109 } 110 110 111 111 if (linnum) 112 112 buf.printf("(%d)", linnum); 113 113 buf.writeByte(0); 114 114 return (char *)buf.extractData(); 115 115 } trunk/src/template.c
r810 r811 1298 1298 } 1299 1299 declareParameter(paramscope, tparam, oded); 1300 1300 dedargs->data[i] = (void *)oded; 1301 1301 } 1302 1302 } 1303 1303 1304 1304 #if DMDV2 1305 1305 if (constraint) 1306 1306 { /* Check to see if constraint is satisfied. 1307 1307 */ 1308 1308 makeParamNamesVisibleInConstraint(paramscope); 1309 1309 Expression *e = constraint->syntaxCopy(); 1310 1310 paramscope->flags |= SCOPEstaticif; 1311 1311 1312 1312 /* Detect recursive attempts to instantiate this template declaration, 1313 1313 * Bugzilla 4072 1314 1314 * void foo(T)(T x) if (is(typeof(foo(x)))) { } 1315 1315 * static assert(!is(typeof(foo(7)))); 1316 1316 * Recursive attempts are regarded as a constraint failure. 1317 1317 */ 1318 /* Previous should also store the scope, as instantiations along a different scope branch1319 * should not conflict1320 */1321 1318 int nmatches = 0; 1322 1319 for (Previous *p = previous; p; p = p->prev) 1323 1320 { 1324 1321 if (arrayObjectMatch(p->dedargs, dedargs, this, sc)) 1325 1322 { 1326 //printf("recursive, no match %p %s\n", this, this->toChars()); 1327 nmatches++; 1323 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars()); 1324 /* It must be a subscope of p->sc, other scope chains are not recursive 1325 * instantiations. 1326 */ 1327 for (Scope *scx = sc; scx; scx = scx->enclosing) 1328 { 1329 if (scx == p->sc) 1330 goto Lnomatch; 1331 } 1328 1332 } 1329 1333 /* BUG: should also check for ref param differences 1330 1334 */ 1331 1335 } 1332 /* Look for 2 matches at least, because sometimes semantic3() gets run causing what appears to1333 * be recursion but isn't.1334 * Template A's constraint instantiates B, B's semantic3() run includes something that has A in its constraint.1335 * Perhaps a better solution is to always defer semantic3() rather than doing it eagerly. The risk1336 * with that is what if semantic3() fails, but our constraint "succeeded"?1337 */1338 if (nmatches >= 2)1339 goto Lnomatch;1340 1336 1341 1337 Previous pr; 1342 1338 pr.prev = previous; 1339 pr.sc = paramscope; 1343 1340 pr.dedargs = dedargs; 1344 1341 previous = ≺ // add this to threaded list 1345 1342 1346 1343 int nerrors = global.errors; 1347 1344 1348 1345 e = e->semantic(paramscope); 1349 1346 1350 1347 previous = pr.prev; // unlink from threaded list 1351 1348 1352 1349 if (nerrors != global.errors) // if any errors from evaluating the constraint, no match 1353 1350 goto Lnomatch; 1354 1351 1355 1352 e = e->optimize(WANTvalue | WANTinterpret); 1356 1353 if (e->isBool(TRUE)) 1357 1354 ; 1358 1355 else if (e->isBool(FALSE)) 1359 1356 goto Lnomatch; 1360 1357 else 1361 1358 { 1362 1359 e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars()); … … 3702 3699 3703 3700 if (s) 3704 3701 ti = (TemplateInstance *)s; 3705 3702 else 3706 3703 ti = new TemplateInstance(loc, name); 3707 3704 3708 3705 ti->tiargs = arraySyntaxCopy(tiargs); 3709 3706 3710 3707 ScopeDsymbol::syntaxCopy(ti); 3711 3708 return ti; 3712 3709 } 3713 3710 3714 3711 3715 3712 void TemplateInstance::semantic(Scope *sc) 3716 3713 { 3717 3714 semantic(sc, NULL); 3718 3715 } 3719 3716 3720 3717 void TemplateInstance::semantic(Scope *sc, Expressions *fargs) 3721 3718 { 3722 //printf("TemplateInstance::semantic('%s', this=%p, gag = %d )\n", toChars(), this, global.gag);3719 //printf("TemplateInstance::semantic('%s', this=%p, gag = %d, sc = %p)\n", toChars(), this, global.gag, sc); 3723 3720 if (global.errors && name != Id::AssociativeArray) 3724 3721 { 3725 3722 //printf("not instantiating %s due to %d errors\n", toChars(), global.errors); 3726 3723 if (!global.gag) 3727 3724 { 3728 3725 /* Trying to soldier on rarely generates useful messages 3729 3726 * at this point. 3730 3727 */ 3731 3728 fatal(); 3732 3729 } 3733 3730 // return; 3734 3731 } 3735 3732 #if LOG 3736 3733 printf("\n+TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); 3737 3734 #endif 3738 3735 if (inst) // if semantic() was already run 3739 3736 { 3740 3737 #if LOG 3741 3738 printf("-TemplateInstance::semantic('%s', this=%p) already run\n", inst->toChars(), inst); 3742 3739 #endif trunk/src/template.h
r809 r811 49 49 struct TemplateDeclaration : ScopeDsymbol 50 50 { 51 51 TemplateParameters *parameters; // array of TemplateParameter's 52 52 53 53 TemplateParameters *origParameters; // originals for Ddoc 54 54 Expression *constraint; 55 55 Array instances; // array of TemplateInstance's 56 56 57 57 TemplateDeclaration *overnext; // next overloaded TemplateDeclaration 58 58 TemplateDeclaration *overroot; // first in overnext list 59 59 60 60 int semanticRun; // 1 semantic() run 61 61 62 62 Dsymbol *onemember; // if !=NULL then one member of this template 63 63 64 64 int literal; // this template declaration is a literal 65 65 int ismixin; // template declaration is only to be used as a mixin 66 66 67 67 struct Previous 68 68 { Previous *prev; 69 Scope *sc; 69 70 Objects *dedargs; 70 71 }; 71 72 Previous *previous; // threaded list of previous instantiation attempts on stack 72 73 73 74 TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, 74 75 Expression *constraint, Dsymbols *decldefs, int ismixin); 75 76 Dsymbol *syntaxCopy(Dsymbol *); 76 77 void semantic(Scope *sc); 77 78 int overloadInsert(Dsymbol *s); 78 79 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 79 80 const char *kind(); 80 81 char *toChars(); 81 82 82 83 void emitComment(Scope *sc); 83 84 void toJsonBuffer(OutBuffer *buf); 84 85 // void toDocBuffer(OutBuffer *buf); 85 86 86 87 MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag); 87 88 MATCH leastAsSpecialized(TemplateDeclaration *td2); 88 89
