1 2 /* Compiler implementation of the D programming language 3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved 4 * written by Walter Bright 5 * http://www.digitalmars.com 6 * Distributed under the Boost Software License, Version 1.0. 7 * http://www.boost.org/LICENSE_1_0.txt 8 * https://github.com/D-Programming-Language/dmd/blob/master/src/template.c 9 */ 10 11 // Handle template implementation 12 13 #include "root/dsystem.h" 14 #include "root/root.h" 15 #include "root/aav.h" 16 #include "root/rmem.h" 17 #include "root/stringtable.h" 18 #include "root/hash.h" 19 20 #include "mangle.h" 21 #include "mtype.h" 22 #include "template.h" 23 #include "init.h" 24 #include "expression.h" 25 #include "scope.h" 26 #include "module.h" 27 #include "aggregate.h" 28 #include "declaration.h" 29 #include "dsymbol.h" 30 #include "mars.h" 31 #include "dsymbol.h" 32 #include "identifier.h" 33 #include "hdrgen.h" 34 #include "id.h" 35 #include "attrib.h" 36 #include "cond.h" 37 #include "tokens.h" 38 39 #define IDX_NOTFOUND (0x12345678) // index is not found 40 41 Type *rawTypeMerge(Type *t1, Type *t2); 42 bool MODimplicitConv(MOD modfrom, MOD modto); 43 MATCH MODmethodConv(MOD modfrom, MOD modto); 44 MOD MODmerge(MOD mod1, MOD mod2); 45 46 static size_t templateParameterLookup(Type *tparam, TemplateParameters *parameters); 47 static int arrayObjectMatch(Objects *oa1, Objects *oa2); 48 static unsigned char deduceWildHelper(Type *t, Type **at, Type *tparam); 49 static MATCH deduceTypeHelper(Type *t, Type **at, Type *tparam); 50 static bool reliesOnTident(Type *t, TemplateParameters *tparams = NULL, size_t iStart = 0); 51 Expression *semantic(Expression *e, Scope *sc); 52 bool evalStaticCondition(Scope *sc, Expression *exp, Expression *e, bool &errors); 53 54 /******************************************** 55 * These functions substitute for dynamic_cast. dynamic_cast does not work 56 * on earlier versions of gcc. 57 */ 58 59 Expression *isExpression(RootObject *o) 60 { 61 //return dynamic_cast<Expression *>(o); 62 if (!o || o->dyncast() != DYNCAST_EXPRESSION) 63 return NULL; 64 return (Expression *)o; 65 } 66 67 Dsymbol *isDsymbol(RootObject *o) 68 { 69 //return dynamic_cast<Dsymbol *>(o); 70 if (!o || o->dyncast() != DYNCAST_DSYMBOL) 71 return NULL; 72 return (Dsymbol *)o; 73 } 74 75 Type *isType(RootObject *o) 76 { 77 //return dynamic_cast<Type *>(o); 78 if (!o || o->dyncast() != DYNCAST_TYPE) 79 return NULL; 80 return (Type *)o; 81 } 82 83 Tuple *isTuple(RootObject *o) 84 { 85 //return dynamic_cast<Tuple *>(o); 86 if (!o || o->dyncast() != DYNCAST_TUPLE) 87 return NULL; 88 return (Tuple *)o; 89 } 90 91 Parameter *isParameter(RootObject *o) 92 { 93 //return dynamic_cast<Parameter *>(o); 94 if (!o || o->dyncast() != DYNCAST_PARAMETER) 95 return NULL; 96 return (Parameter *)o; 97 } 98 99 /************************************** 100 * Is this Object an error? 101 */ 102 bool isError(RootObject *o) 103 { 104 Type *t = isType(o); 105 if (t) 106 return (t->ty == Terror); 107 Expression *e = isExpression(o); 108 if (e) 109 return (e->op == TOKerror || !e->type || e->type->ty == Terror); 110 Tuple *v = isTuple(o); 111 if (v) 112 return arrayObjectIsError(&v->objects); 113 Dsymbol *s = isDsymbol(o); 114 assert(s); 115 if (s->errors) 116 return true; 117 return s->parent ? isError(s->parent) : false; 118 } 119 120 /************************************** 121 * Are any of the Objects an error? 122 */ 123 bool arrayObjectIsError(Objects *args) 124 { 125 for (size_t i = 0; i < args->dim; i++) 126 { 127 RootObject *o = (*args)[i]; 128 if (isError(o)) 129 return true; 130 } 131 return false; 132 } 133 134 /*********************** 135 * Try to get arg as a type. 136 */ 137 138 Type *getType(RootObject *o) 139 { 140 Type *t = isType(o); 141 if (!t) 142 { 143 Expression *e = isExpression(o); 144 if (e) 145 t = e->type; 146 } 147 return t; 148 } 149 150 Dsymbol *getDsymbol(RootObject *oarg) 151 { 152 //printf("getDsymbol()\n"); 153 //printf("e %p s %p t %p v %p\n", isExpression(oarg), isDsymbol(oarg), isType(oarg), isTuple(oarg)); 154 155 Dsymbol *sa; 156 Expression *ea = isExpression(oarg); 157 if (ea) 158 { 159 // Try to convert Expression to symbol 160 if (ea->op == TOKvar) 161 sa = ((VarExp *)ea)->var; 162 else if (ea->op == TOKfunction) 163 { 164 if (((FuncExp *)ea)->td) 165 sa = ((FuncExp *)ea)->td; 166 else 167 sa = ((FuncExp *)ea)->fd; 168 } 169 else if (ea->op == TOKtemplate) 170 sa = ((TemplateExp *)ea)->td; 171 else 172 sa = NULL; 173 } 174 else 175 { 176 // Try to convert Type to symbol 177 Type *ta = isType(oarg); 178 if (ta) 179 sa = ta->toDsymbol(NULL); 180 else 181 sa = isDsymbol(oarg); // if already a symbol 182 } 183 return sa; 184 } 185 186 /*********************** 187 * Try to get value from manifest constant 188 */ 189 190 static Expression *getValue(Expression *e) 191 { 192 if (e && e->op == TOKvar) 193 { 194 VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration(); 195 if (v && v->storage_class & STCmanifest) 196 { 197 e = v->getConstInitializer(); 198 } 199 } 200 return e; 201 } 202 203 static Expression *getValue(Dsymbol *&s) 204 { 205 Expression *e = NULL; 206 if (s) 207 { 208 VarDeclaration *v = s->isVarDeclaration(); 209 if (v && v->storage_class & STCmanifest) 210 { 211 e = v->getConstInitializer(); 212 } 213 } 214 return e; 215 } 216 217 /********************************** 218 * Return true if e could be valid only as a template value parameter. 219 * Return false if it might be an alias or tuple. 220 * (Note that even in this case, it could still turn out to be a value). 221 */ 222 bool definitelyValueParameter(Expression *e) 223 { 224 // None of these can be value parameters 225 if (e->op == TOKtuple || e->op == TOKscope || 226 e->op == TOKtype || e->op == TOKdottype || 227 e->op == TOKtemplate || e->op == TOKdottd || 228 e->op == TOKfunction || e->op == TOKerror || 229 e->op == TOKthis || e->op == TOKsuper) 230 return false; 231 232 if (e->op != TOKdotvar) 233 return true; 234 235 /* Template instantiations involving a DotVar expression are difficult. 236 * In most cases, they should be treated as a value parameter, and interpreted. 237 * But they might also just be a fully qualified name, which should be treated 238 * as an alias. 239 */ 240 241 // x.y.f cannot be a value 242 FuncDeclaration *f = ((DotVarExp *)e)->var->isFuncDeclaration(); 243 if (f) 244 return false; 245 246 while (e->op == TOKdotvar) 247 { 248 e = ((DotVarExp *)e)->e1; 249 } 250 // this.x.y and super.x.y couldn't possibly be valid values. 251 if (e->op == TOKthis || e->op == TOKsuper) 252 return false; 253 254 // e.type.x could be an alias 255 if (e->op == TOKdottype) 256 return false; 257 258 // var.x.y is the only other possible form of alias 259 if (e->op != TOKvar) 260 return true; 261 262 VarDeclaration *v = ((VarExp *)e)->var->isVarDeclaration(); 263 264 // func.x.y is not an alias 265 if (!v) 266 return true; 267 268 // TODO: Should we force CTFE if it is a global constant? 269 270 return false; 271 } 272 273 static Expression *getExpression(RootObject *o) 274 { 275 Dsymbol *s = isDsymbol(o); 276 return s ? getValue(s) : getValue(isExpression(o)); 277 } 278 279 /****************************** 280 * If o1 matches o2, return true. 281 * Else, return false. 282 */ 283 284 static bool match(RootObject *o1, RootObject *o2) 285 { 286 //printf("match() o1 = %p %s (%d), o2 = %p %s (%d)\n", 287 // o1, o1->toChars(), o1->dyncast(), o2, o2->toChars(), o2->dyncast()); 288 289 /* A proper implementation of the various equals() overrides 290 * should make it possible to just do o1->equals(o2), but 291 * we'll do that another day. 292 */ 293 294 /* Manifest constants should be compared by their values, 295 * at least in template arguments. 296 */ 297 298 if (Type *t1 = isType(o1)) 299 { 300 Type *t2 = isType(o2); 301 if (!t2) 302 goto Lnomatch; 303 304 //printf("\tt1 = %s\n", t1->toChars()); 305 //printf("\tt2 = %s\n", t2->toChars()); 306 if (!t1->equals(t2)) 307 goto Lnomatch; 308 309 goto Lmatch; 310 } 311 if (Expression *e1 = getExpression(o1)) 312 { 313 Expression *e2 = getExpression(o2); 314 if (!e2) 315 goto Lnomatch; 316 317 //printf("\te1 = %s %s %s\n", e1->type->toChars(), Token::toChars(e1->op), e1->toChars()); 318 //printf("\te2 = %s %s %s\n", e2->type->toChars(), Token::toChars(e2->op), e2->toChars()); 319 320 // two expressions can be equal although they do not have the same 321 // type; that happens when they have the same value. So check type 322 // as well as expression equality to ensure templates are properly 323 // matched. 324 if (!e1->type->equals(e2->type) || !e1->equals(e2)) 325 goto Lnomatch; 326 327 goto Lmatch; 328 } 329 if (Dsymbol *s1 = isDsymbol(o1)) 330 { 331 Dsymbol *s2 = isDsymbol(o2); 332 if (!s2) 333 goto Lnomatch; 334 335 //printf("\ts1 = %s\n", s1->toChars()); 336 //printf("\ts2 = %s\n", s2->toChars()); 337 if (!s1->equals(s2)) 338 goto Lnomatch; 339 if (s1->parent != s2->parent && !s1->isFuncDeclaration() && !s2->isFuncDeclaration()) 340 goto Lnomatch; 341 342 goto Lmatch; 343 } 344 if (Tuple *u1 = isTuple(o1)) 345 { 346 Tuple *u2 = isTuple(o2); 347 if (!u2) 348 goto Lnomatch; 349 350 //printf("\tu1 = %s\n", u1->toChars()); 351 //printf("\tu2 = %s\n", u2->toChars()); 352 if (!arrayObjectMatch(&u1->objects, &u2->objects)) 353 goto Lnomatch; 354 355 goto Lmatch; 356 } 357 Lmatch: 358 //printf("\t-> match\n"); 359 return true; 360 361 Lnomatch: 362 //printf("\t-> nomatch\n"); 363 return false; 364 } 365 366 367 /************************************ 368 * Match an array of them. 369 */ 370 int arrayObjectMatch(Objects *oa1, Objects *oa2) 371 { 372 if (oa1 == oa2) 373 return 1; 374 if (oa1->dim != oa2->dim) 375 return 0; 376 for (size_t j = 0; j < oa1->dim; j++) 377 { 378 RootObject *o1 = (*oa1)[j]; 379 RootObject *o2 = (*oa2)[j]; 380 if (!match(o1, o2)) 381 { 382 return 0; 383 } 384 } 385 return 1; 386 } 387 388 389 /************************************ 390 * Computes hash of expression. 391 * Handles all Expression classes and MUST match their equals method, 392 * i.e. e1->equals(e2) implies expressionHash(e1) == expressionHash(e2). 393 */ 394 static hash_t expressionHash(Expression *e) 395 { 396 switch (e->op) 397 { 398 case TOKint64: 399 return (size_t) ((IntegerExp *)e)->getInteger(); 400 401 case TOKfloat64: 402 return CTFloat::hash(((RealExp *)e)->value); 403 404 case TOKcomplex80: 405 { 406 ComplexExp *ce = (ComplexExp *)e; 407 return mixHash(CTFloat::hash(ce->toReal()), CTFloat::hash(ce->toImaginary())); 408 } 409 410 case TOKidentifier: 411 return (size_t)(void *) ((IdentifierExp *)e)->ident; 412 413 case TOKnull: 414 return (size_t)(void *) ((NullExp *)e)->type; 415 416 case TOKstring: 417 { 418 StringExp *se = (StringExp *)e; 419 return calcHash((const char *)se->string, se->len * se->sz); 420 } 421 422 case TOKtuple: 423 { 424 TupleExp *te = (TupleExp *)e; 425 size_t hash = 0; 426 hash += te->e0 ? expressionHash(te->e0) : 0; 427 for (size_t i = 0; i < te->exps->dim; i++) 428 { 429 Expression *elem = (*te->exps)[i]; 430 hash = mixHash(hash, expressionHash(elem)); 431 } 432 return hash; 433 } 434 435 case TOKarrayliteral: 436 { 437 ArrayLiteralExp *ae = (ArrayLiteralExp *)e; 438 size_t hash = 0; 439 for (size_t i = 0; i < ae->elements->dim; i++) 440 hash = mixHash(hash, expressionHash(ae->getElement(i))); 441 return hash; 442 } 443 444 case TOKassocarrayliteral: 445 { 446 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e; 447 size_t hash = 0; 448 for (size_t i = 0; i < ae->keys->dim; i++) 449 // reduction needs associative op as keys are unsorted (use XOR) 450 hash ^= mixHash(expressionHash((*ae->keys)[i]), expressionHash((*ae->values)[i])); 451 return hash; 452 } 453 454 case TOKstructliteral: 455 { 456 StructLiteralExp *se = (StructLiteralExp *)e; 457 size_t hash = 0; 458 for (size_t i = 0; i < se->elements->dim; i++) 459 { 460 Expression *elem = (*se->elements)[i]; 461 hash = mixHash(hash, elem ? expressionHash(elem) : 0); 462 } 463 return hash; 464 } 465 466 case TOKvar: 467 return (size_t)(void *) ((VarExp *)e)->var; 468 469 case TOKfunction: 470 return (size_t)(void *) ((FuncExp *)e)->fd; 471 472 default: 473 // no custom equals for this expression 474 // equals based on identity 475 return (size_t)(void *) e; 476 } 477 } 478 479 480 /************************************ 481 * Return hash of Objects. 482 */ 483 static hash_t arrayObjectHash(Objects *oa1) 484 { 485 hash_t hash = 0; 486 for (size_t j = 0; j < oa1->dim; j++) 487 { 488 /* Must follow the logic of match() 489 */ 490 RootObject *o1 = (*oa1)[j]; 491 if (Type *t1 = isType(o1)) 492 hash = mixHash(hash, (size_t)t1->deco); 493 else if (Expression *e1 = getExpression(o1)) 494 hash = mixHash(hash, expressionHash(e1)); 495 else if (Dsymbol *s1 = isDsymbol(o1)) 496 { 497 FuncAliasDeclaration *fa1 = s1->isFuncAliasDeclaration(); 498 if (fa1) 499 s1 = fa1->toAliasFunc(); 500 hash = mixHash(hash, mixHash((size_t)(void *)s1->getIdent(), (size_t)(void *)s1->parent)); 501 } 502 else if (Tuple *u1 = isTuple(o1)) 503 hash = mixHash(hash, arrayObjectHash(&u1->objects)); 504 } 505 return hash; 506 } 507 508 RootObject *objectSyntaxCopy(RootObject *o) 509 { 510 if (!o) 511 return NULL; 512 if (Type *t = isType(o)) 513 return t->syntaxCopy(); 514 if (Expression *e = isExpression(o)) 515 return e->syntaxCopy(); 516 return o; 517 } 518 519 520 /* ======================== TemplateDeclaration ============================= */ 521 522 TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, 523 TemplateParameters *parameters, Expression *constraint, Dsymbols *decldefs, bool ismixin, bool literal) 524 : ScopeDsymbol(id) 525 { 526 this->loc = loc; 527 this->parameters = parameters; 528 this->origParameters = parameters; 529 this->constraint = constraint; 530 this->members = decldefs; 531 this->overnext = NULL; 532 this->overroot = NULL; 533 this->funcroot = NULL; 534 this->onemember = NULL; 535 this->literal = literal; 536 this->ismixin = ismixin; 537 this->isstatic = true; 538 this->previous = NULL; 539 this->protection = Prot(PROTundefined); 540 this->instances = NULL; 541 542 // Compute in advance for Ddoc's use 543 // Bugzilla 11153: ident could be NULL if parsing fails. 544 if (members && ident) 545 { 546 Dsymbol *s; 547 if (Dsymbol::oneMembers(members, &s, ident) && s) 548 { 549 onemember = s; 550 s->parent = this; 551 } 552 } 553 } 554 555 Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *) 556 { 557 //printf("TemplateDeclaration::syntaxCopy()\n"); 558 TemplateParameters *p = NULL; 559 if (parameters) 560 { 561 p = new TemplateParameters(); 562 p->setDim(parameters->dim); 563 for (size_t i = 0; i < p->dim; i++) 564 (*p)[i] = (*parameters)[i]->syntaxCopy(); 565 } 566 return new TemplateDeclaration(loc, ident, p, 567 constraint ? constraint->syntaxCopy() : NULL, 568 Dsymbol::arraySyntaxCopy(members), ismixin, literal); 569 } 570 571 void TemplateDeclaration::semantic(Scope *sc) 572 { 573 if (semanticRun != PASSinit) 574 return; // semantic() already run 575 576 // Remember templates defined in module object that we need to know about 577 if (sc->_module && sc->_module->ident == Id::object) 578 { 579 if (ident == Id::RTInfo) 580 Type::rtinfo = this; 581 } 582 583 /* Remember Scope for later instantiations, but make 584 * a copy since attributes can change. 585 */ 586 if (!this->_scope) 587 { 588 this->_scope = sc->copy(); 589 this->_scope->setNoFree(); 590 } 591 592 semanticRun = PASSsemantic; 593 594 parent = sc->parent; 595 protection = sc->protection; 596 isstatic = toParent()->isModule() || (_scope->stc & STCstatic); 597 598 if (!isstatic) 599 { 600 if (AggregateDeclaration *ad = parent->pastMixin()->isAggregateDeclaration()) 601 ad->makeNested(); 602 } 603 604 // Set up scope for parameters 605 ScopeDsymbol *paramsym = new ScopeDsymbol(); 606 paramsym->parent = parent; 607 Scope *paramscope = sc->push(paramsym); 608 paramscope->stc = 0; 609 610 if (global.params.doDocComments) 611 { 612 origParameters = new TemplateParameters(); 613 origParameters->setDim(parameters->dim); 614 for (size_t i = 0; i < parameters->dim; i++) 615 { 616 TemplateParameter *tp = (*parameters)[i]; 617 (*origParameters)[i] = tp->syntaxCopy(); 618 } 619 } 620 621 for (size_t i = 0; i < parameters->dim; i++) 622 { 623 TemplateParameter *tp = (*parameters)[i]; 624 625 if (!tp->declareParameter(paramscope)) 626 { 627 error(tp->loc, "parameter '%s' multiply defined", tp->ident->toChars()); 628 errors = true; 629 } 630 if (!tp->semantic(paramscope, parameters)) 631 { 632 errors = true; 633 } 634 if (i + 1 != parameters->dim && tp->isTemplateTupleParameter()) 635 { 636 error("template tuple parameter must be last one"); 637 errors = true; 638 } 639 } 640 641 /* Calculate TemplateParameter::dependent 642 */ 643 TemplateParameters tparams; 644 tparams.setDim(1); 645 for (size_t i = 0; i < parameters->dim; i++) 646 { 647 TemplateParameter *tp = (*parameters)[i]; 648 tparams[0] = tp; 649 650 for (size_t j = 0; j < parameters->dim; j++) 651 { 652 // Skip cases like: X(T : T) 653 if (i == j) 654 continue; 655 656 if (TemplateTypeParameter *ttp = (*parameters)[j]->isTemplateTypeParameter()) 657 { 658 if (reliesOnTident(ttp->specType, &tparams)) 659 tp->dependent = true; 660 } 661 else if (TemplateAliasParameter *tap = (*parameters)[j]->isTemplateAliasParameter()) 662 { 663 if (reliesOnTident(tap->specType, &tparams) || 664 reliesOnTident(isType(tap->specAlias), &tparams)) 665 { 666 tp->dependent = true; 667 } 668 } 669 } 670 } 671 672 paramscope->pop(); 673 674 // Compute again 675 onemember = NULL; 676 if (members) 677 { 678 Dsymbol *s; 679 if (Dsymbol::oneMembers(members, &s, ident) && s) 680 { 681 onemember = s; 682 s->parent = this; 683 } 684 } 685 686 /* BUG: should check: 687 * o no virtual functions or non-static data members of classes 688 */ 689 semanticRun = PASSsemanticdone; 690 } 691 692 const char *TemplateDeclaration::kind() const 693 { 694 return (onemember && onemember->isAggregateDeclaration()) 695 ? onemember->kind() 696 : "template"; 697 } 698 699 /********************************** 700 * Overload existing TemplateDeclaration 'this' with the new one 's'. 701 * Return true if successful; i.e. no conflict. 702 */ 703 704 bool TemplateDeclaration::overloadInsert(Dsymbol *s) 705 { 706 FuncDeclaration *fd = s->isFuncDeclaration(); 707 if (fd) 708 { 709 if (funcroot) 710 return funcroot->overloadInsert(fd); 711 funcroot = fd; 712 return funcroot->overloadInsert(this); 713 } 714 715 TemplateDeclaration *td = s->isTemplateDeclaration(); 716 if (!td) 717 return false; 718 719 TemplateDeclaration *pthis = this; 720 TemplateDeclaration **ptd; 721 for (ptd = &pthis; *ptd; ptd = &(*ptd)->overnext) 722 { 723 } 724 725 td->overroot = this; 726 *ptd = td; 727 return true; 728 } 729 730 /**************************** 731 * Check to see if constraint is satisfied. 732 */ 733 bool TemplateDeclaration::evaluateConstraint( 734 TemplateInstance *ti, Scope *sc, Scope *paramscope, 735 Objects *dedargs, FuncDeclaration *fd) 736 { 737 /* Detect recursive attempts to instantiate this template declaration, 738 * Bugzilla 4072 739 * void foo(T)(T x) if (is(typeof(foo(x)))) { } 740 * static assert(!is(typeof(foo(7)))); 741 * Recursive attempts are regarded as a constraint failure. 742 */ 743 /* There's a chicken-and-egg problem here. We don't know yet if this template 744 * instantiation will be a local one (enclosing is set), and we won't know until 745 * after selecting the correct template. Thus, function we're nesting inside 746 * is not on the sc scope chain, and this can cause errors in FuncDeclaration::getLevel(). 747 * Workaround the problem by setting a flag to relax the checking on frame errors. 748 */ 749 750 for (TemplatePrevious *p = previous; p; p = p->prev) 751 { 752 if (arrayObjectMatch(p->dedargs, dedargs)) 753 { 754 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars()); 755 /* It must be a subscope of p->sc, other scope chains are not recursive 756 * instantiations. 757 */ 758 for (Scope *scx = sc; scx; scx = scx->enclosing) 759 { 760 if (scx == p->sc) 761 return false; 762 } 763 } 764 /* BUG: should also check for ref param differences 765 */ 766 } 767 768 TemplatePrevious pr; 769 pr.prev = previous; 770 pr.sc = paramscope; 771 pr.dedargs = dedargs; 772 previous = ≺ // add this to threaded list 773 774 Scope *scx = paramscope->push(ti); 775 scx->parent = ti; 776 scx->tinst = NULL; 777 scx->minst = NULL; 778 779 assert(!ti->symtab); 780 if (fd) 781 { 782 /* Declare all the function parameters as variables and add them to the scope 783 * Making parameters is similar to FuncDeclaration::semantic3 784 */ 785 TypeFunction *tf = (TypeFunction *)fd->type; 786 assert(tf->ty == Tfunction); 787 788 scx->parent = fd; 789 790 Parameters *fparameters = tf->parameters; 791 int fvarargs = tf->varargs; 792 793 size_t nfparams = Parameter::dim(fparameters); 794 for (size_t i = 0; i < nfparams; i++) 795 { 796 Parameter *fparam = Parameter::getNth(fparameters, i); 797 fparam->storageClass &= (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor); 798 fparam->storageClass |= STCparameter; 799 if (fvarargs == 2 && i + 1 == nfparams) 800 fparam->storageClass |= STCvariadic; 801 } 802 for (size_t i = 0; i < fparameters->dim; i++) 803 { 804 Parameter *fparam = (*fparameters)[i]; 805 if (!fparam->ident) 806 continue; // don't add it, if it has no name 807 VarDeclaration *v = new VarDeclaration(loc, fparam->type, fparam->ident, NULL); 808 v->storage_class = fparam->storageClass; 809 v->semantic(scx); 810 if (!ti->symtab) 811 ti->symtab = new DsymbolTable(); 812 if (!scx->insert(v)) 813 error("parameter %s.%s is already defined", toChars(), v->toChars()); 814 else 815 v->parent = fd; 816 } 817 if (isstatic) 818 fd->storage_class |= STCstatic; 819 820 fd->vthis = fd->declareThis(scx, fd->isThis()); 821 } 822 823 Expression *e = constraint->syntaxCopy(); 824 825 assert(ti->inst == NULL); 826 ti->inst = ti; // temporary instantiation to enable genIdent() 827 828 scx->flags |= SCOPEconstraint; 829 bool errors = false; 830 bool result = evalStaticCondition(scx, constraint, e, errors); 831 ti->inst = NULL; 832 ti->symtab = NULL; 833 scx = scx->pop(); 834 previous = pr.prev; // unlink from threaded list 835 if (errors) 836 return false; 837 return result; 838 } 839 840 /*************************************** 841 * Given that ti is an instance of this TemplateDeclaration, 842 * deduce the types of the parameters to this, and store 843 * those deduced types in dedtypes[]. 844 * Input: 845 * flag 1: don't do semantic() because of dummy types 846 * 2: don't change types in matchArg() 847 * Output: 848 * dedtypes deduced arguments 849 * Return match level. 850 */ 851 852 MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti, 853 Objects *dedtypes, Expressions *fargs, int flag) 854 { 855 MATCH m; 856 size_t dedtypes_dim = dedtypes->dim; 857 858 dedtypes->zero(); 859 860 if (errors) 861 return MATCHnomatch; 862 863 size_t parameters_dim = parameters->dim; 864 int variadic = isVariadic() != NULL; 865 866 // If more arguments than parameters, no match 867 if (ti->tiargs->dim > parameters_dim && !variadic) 868 { 869 return MATCHnomatch; 870 } 871 872 assert(dedtypes_dim == parameters_dim); 873 assert(dedtypes_dim >= ti->tiargs->dim || variadic); 874 875 assert(_scope); 876 877 // Set up scope for template parameters 878 ScopeDsymbol *paramsym = new ScopeDsymbol(); 879 paramsym->parent = _scope->parent; 880 Scope *paramscope = _scope->push(paramsym); 881 paramscope->tinst = ti; 882 paramscope->minst = sc->minst; 883 paramscope->callsc = sc; 884 paramscope->stc = 0; 885 886 // Attempt type deduction 887 m = MATCHexact; 888 for (size_t i = 0; i < dedtypes_dim; i++) 889 { 890 MATCH m2; 891 TemplateParameter *tp = (*parameters)[i]; 892 Declaration *sparam; 893 894 //printf("\targument [%d]\n", i); 895 m2 = tp->matchArg(ti->loc, paramscope, ti->tiargs, i, parameters, dedtypes, &sparam); 896 //printf("\tm2 = %d\n", m2); 897 898 if (m2 == MATCHnomatch) 899 { 900 goto Lnomatch; 901 } 902 903 if (m2 < m) 904 m = m2; 905 906 if (!flag) 907 sparam->semantic(paramscope); 908 if (!paramscope->insert(sparam)) // TODO: This check can make more early 909 goto Lnomatch; // in TemplateDeclaration::semantic, and 910 // then we don't need to make sparam if flags == 0 911 } 912 913 if (!flag) 914 { 915 /* Any parameter left without a type gets the type of 916 * its corresponding arg 917 */ 918 for (size_t i = 0; i < dedtypes_dim; i++) 919 { 920 if (!(*dedtypes)[i]) 921 { 922 assert(i < ti->tiargs->dim); 923 (*dedtypes)[i] = (Type *)(*ti->tiargs)[i]; 924 } 925 } 926 } 927 928 if (m > MATCHnomatch && constraint && !flag) 929 { 930 if (ti->hasNestedArgs(ti->tiargs, this->isstatic)) // TODO: should gag error 931 ti->parent = ti->enclosing; 932 else 933 ti->parent = this->parent; 934 935 // Similar to doHeaderInstantiation 936 FuncDeclaration *fd = onemember ? onemember->isFuncDeclaration() : NULL; 937 if (fd) 938 { 939 assert(fd->type->ty == Tfunction); 940 TypeFunction *tf = (TypeFunction *)fd->type->syntaxCopy(); 941 942 fd = new FuncDeclaration(fd->loc, fd->endloc, fd->ident, fd->storage_class, tf); 943 fd->parent = ti; 944 fd->inferRetType = true; 945 946 // Shouldn't run semantic on default arguments and return type. 947 for (size_t i = 0; i < tf->parameters->dim; i++) 948 (*tf->parameters)[i]->defaultArg = NULL; 949 tf->next = NULL; 950 951 // Resolve parameter types and 'auto ref's. 952 tf->fargs = fargs; 953 unsigned olderrors = global.startGagging(); 954 fd->type = tf->semantic(loc, paramscope); 955 if (global.endGagging(olderrors)) 956 { 957 assert(fd->type->ty != Tfunction); 958 goto Lnomatch; 959 } 960 assert(fd->type->ty == Tfunction); 961 fd->originalType = fd->type; // for mangling 962 } 963 964 // TODO: dedtypes => ti->tiargs ? 965 if (!evaluateConstraint(ti, sc, paramscope, dedtypes, fd)) 966 goto Lnomatch; 967 } 968 969 goto Lret; 970 971 Lnomatch: 972 m = MATCHnomatch; 973 974 Lret: 975 paramscope->pop(); 976 return m; 977 } 978 979 /******************************************** 980 * Determine partial specialization order of 'this' vs td2. 981 * Returns: 982 * match this is at least as specialized as td2 983 * 0 td2 is more specialized than this 984 */ 985 986 MATCH TemplateDeclaration::leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs) 987 { 988 /* This works by taking the template parameters to this template 989 * declaration and feeding them to td2 as if it were a template 990 * instance. 991 * If it works, then this template is at least as specialized 992 * as td2. 993 */ 994 995 TemplateInstance ti(Loc(), ident); // create dummy template instance 996 // Set type arguments to dummy template instance to be types 997 // generated from the parameters to this template declaration 998 ti.tiargs = new Objects(); 999 ti.tiargs->reserve(parameters->dim); 1000 for (size_t i = 0; i < parameters->dim; i++) 1001 { 1002 TemplateParameter *tp = (*parameters)[i]; 1003 if (tp->dependent) 1004 break; 1005 RootObject *p = (RootObject *)tp->dummyArg(); 1006 if (!p) 1007 break; 1008 1009 ti.tiargs->push(p); 1010 } 1011 1012 // Temporary Array to hold deduced types 1013 Objects dedtypes; 1014 dedtypes.setDim(td2->parameters->dim); 1015 1016 // Attempt a type deduction 1017 MATCH m = td2->matchWithInstance(sc, &ti, &dedtypes, fargs, 1); 1018 if (m > MATCHnomatch) 1019 { 1020 /* A non-variadic template is more specialized than a 1021 * variadic one. 1022 */ 1023 TemplateTupleParameter *tp = isVariadic(); 1024 if (tp && !tp->dependent && !td2->isVariadic()) 1025 goto L1; 1026 1027 return m; 1028 } 1029 L1: 1030 return MATCHnomatch; 1031 } 1032 1033 static Expression *emptyArrayElement = NULL; 1034 1035 class TypeDeduced : public Type 1036 { 1037 public: 1038 Type *tded; 1039 Expressions argexps; // corresponding expressions 1040 Types tparams; // tparams[i]->mod 1041 1042 TypeDeduced(Type *tt, Expression *e, Type *tparam) 1043 : Type(Tnone) 1044 { 1045 tded = tt; 1046 argexps.push(e); 1047 tparams.push(tparam); 1048 } 1049 1050 virtual ~TypeDeduced() 1051 { 1052 } 1053 1054 void update(Expression *e, Type *tparam) 1055 { 1056 argexps.push(e); 1057 tparams.push(tparam); 1058 } 1059 void update(Type *tt, Expression *e, Type *tparam) 1060 { 1061 tded = tt; 1062 argexps.push(e); 1063 tparams.push(tparam); 1064 } 1065 MATCH matchAll(Type *tt) 1066 { 1067 MATCH match = MATCHexact; 1068 for (size_t j = 0; j < argexps.dim; j++) 1069 { 1070 Expression *e = argexps[j]; 1071 assert(e); 1072 if (e == emptyArrayElement) 1073 continue; 1074 1075 Type *t = tt->addMod(tparams[j]->mod)->substWildTo(MODconst); 1076 1077 MATCH m = e->implicitConvTo(t); 1078 if (match > m) 1079 match = m; 1080 if (match <= MATCHnomatch) 1081 break; 1082 } 1083 return match; 1084 } 1085 }; 1086 1087 /************************************************* 1088 * Match function arguments against a specific template function. 1089 * Input: 1090 * ti 1091 * sc instantiation scope 1092 * fd 1093 * tthis 'this' argument if !NULL 1094 * fargs arguments to function 1095 * Output: 1096 * fd Partially instantiated function declaration 1097 * ti->tdtypes Expression/Type deduced template arguments 1098 * Returns: 1099 * match level 1100 * bit 0-3 Match template parameters by inferred template arguments 1101 * bit 4-7 Match template parameters by initial template arguments 1102 */ 1103 1104 MATCH TemplateDeclaration::deduceFunctionTemplateMatch( 1105 TemplateInstance *ti, Scope *sc, 1106 FuncDeclaration *&fd, Type *tthis, Expressions *fargs) 1107 { 1108 size_t nfparams; 1109 size_t nfargs; 1110 size_t ntargs; // array size of tiargs 1111 size_t fptupindex = IDX_NOTFOUND; 1112 MATCH match = MATCHexact; 1113 MATCH matchTiargs = MATCHexact; 1114 Parameters *fparameters; // function parameter list 1115 int fvarargs; // function varargs 1116 unsigned wildmatch = 0; 1117 size_t inferStart = 0; 1118 1119 Loc instLoc = ti->loc; 1120 Objects *tiargs = ti->tiargs; 1121 Objects *dedargs = new Objects(); 1122 Objects* dedtypes = &ti->tdtypes; // for T:T*, the dedargs is the T*, dedtypes is the T 1123 1124 assert(_scope); 1125 1126 dedargs->setDim(parameters->dim); 1127 dedargs->zero(); 1128 1129 dedtypes->setDim(parameters->dim); 1130 dedtypes->zero(); 1131 1132 if (errors || fd->errors) 1133 return MATCHnomatch; 1134 1135 // Set up scope for parameters 1136 ScopeDsymbol *paramsym = new ScopeDsymbol(); 1137 paramsym->parent = _scope->parent; // should use hasnestedArgs and enclosing? 1138 Scope *paramscope = _scope->push(paramsym); 1139 paramscope->tinst = ti; 1140 paramscope->minst = sc->minst; 1141 paramscope->callsc = sc; 1142 paramscope->stc = 0; 1143 1144 TemplateTupleParameter *tp = isVariadic(); 1145 Tuple *declaredTuple = NULL; 1146 1147 ntargs = 0; 1148 if (tiargs) 1149 { 1150 // Set initial template arguments 1151 ntargs = tiargs->dim; 1152 size_t n = parameters->dim; 1153 if (tp) 1154 n--; 1155 if (ntargs > n) 1156 { 1157 if (!tp) 1158 goto Lnomatch; 1159 1160 /* The extra initial template arguments 1161 * now form the tuple argument. 1162 */ 1163 Tuple *t = new Tuple(); 1164 assert(parameters->dim); 1165 (*dedargs)[parameters->dim - 1] = t; 1166 1167 t->objects.setDim(ntargs - n); 1168 for (size_t i = 0; i < t->objects.dim; i++) 1169 { 1170 t->objects[i] = (*tiargs)[n + i]; 1171 } 1172 declareParameter(paramscope, tp, t); 1173 declaredTuple = t; 1174 } 1175 else 1176 n = ntargs; 1177 1178 memcpy(dedargs->tdata(), tiargs->tdata(), n * sizeof(*dedargs->tdata())); 1179 1180 for (size_t i = 0; i < n; i++) 1181 { 1182 assert(i < parameters->dim); 1183 Declaration *sparam = NULL; 1184 MATCH m = (*parameters)[i]->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, &sparam); 1185 //printf("\tdeduceType m = %d\n", m); 1186 if (m <= MATCHnomatch) 1187 goto Lnomatch; 1188 if (m < matchTiargs) 1189 matchTiargs = m; 1190 1191 sparam->semantic(paramscope); 1192 if (!paramscope->insert(sparam)) 1193 goto Lnomatch; 1194 } 1195 if (n < parameters->dim && !declaredTuple) 1196 { 1197 inferStart = n; 1198 } 1199 else 1200 inferStart = parameters->dim; 1201 //printf("tiargs matchTiargs = %d\n", matchTiargs); 1202 } 1203 1204 fparameters = fd->getParameters(&fvarargs); 1205 nfparams = Parameter::dim(fparameters); // number of function parameters 1206 nfargs = fargs ? fargs->dim : 0; // number of function arguments 1207 1208 /* Check for match of function arguments with variadic template 1209 * parameter, such as: 1210 * 1211 * void foo(T, A...)(T t, A a); 1212 * void main() { foo(1,2,3); } 1213 */ 1214 if (tp) // if variadic 1215 { 1216 // TemplateTupleParameter always makes most lesser matching. 1217 matchTiargs = MATCHconvert; 1218 1219 if (nfparams == 0 && nfargs != 0) // if no function parameters 1220 { 1221 if (!declaredTuple) 1222 { 1223 Tuple *t = new Tuple(); 1224 //printf("t = %p\n", t); 1225 (*dedargs)[parameters->dim - 1] = t; 1226 declareParameter(paramscope, tp, t); 1227 declaredTuple = t; 1228 } 1229 } 1230 else 1231 { 1232 /* Figure out which of the function parameters matches 1233 * the tuple template parameter. Do this by matching 1234 * type identifiers. 1235 * Set the index of this function parameter to fptupindex. 1236 */ 1237 for (fptupindex = 0; fptupindex < nfparams; fptupindex++) 1238 { 1239 Parameter *fparam = (*fparameters)[fptupindex]; 1240 if (fparam->type->ty != Tident) 1241 continue; 1242 TypeIdentifier *tid = (TypeIdentifier *)fparam->type; 1243 if (!tp->ident->equals(tid->ident) || tid->idents.dim) 1244 continue; 1245 1246 if (fvarargs) // variadic function doesn't 1247 goto Lnomatch; // go with variadic template 1248 1249 goto L1; 1250 } 1251 fptupindex = IDX_NOTFOUND; 1252 L1: 1253 ; 1254 } 1255 } 1256 1257 if (toParent()->isModule() || (_scope->stc & STCstatic)) 1258 tthis = NULL; 1259 if (tthis) 1260 { 1261 bool hasttp = false; 1262 1263 // Match 'tthis' to any TemplateThisParameter's 1264 for (size_t i = 0; i < parameters->dim; i++) 1265 { 1266 TemplateThisParameter *ttp = (*parameters)[i]->isTemplateThisParameter(); 1267 if (ttp) 1268 { 1269 hasttp = true; 1270 1271 Type *t = new TypeIdentifier(Loc(), ttp->ident); 1272 MATCH m = deduceType(tthis, paramscope, t, parameters, dedtypes); 1273 if (m <= MATCHnomatch) 1274 goto Lnomatch; 1275 if (m < match) 1276 match = m; // pick worst match 1277 } 1278 } 1279 1280 // Match attributes of tthis against attributes of fd 1281 if (fd->type && !fd->isCtorDeclaration()) 1282 { 1283 StorageClass stc = _scope->stc | fd->storage_class2; 1284 // Propagate parent storage class (see bug 5504) 1285 Dsymbol *p = parent; 1286 while (p->isTemplateDeclaration() || p->isTemplateInstance()) 1287 p = p->parent; 1288 AggregateDeclaration *ad = p->isAggregateDeclaration(); 1289 if (ad) 1290 stc |= ad->storage_class; 1291 1292 unsigned char mod = fd->type->mod; 1293 if (stc & STCimmutable) 1294 mod = MODimmutable; 1295 else 1296 { 1297 if (stc & (STCshared | STCsynchronized)) 1298 mod |= MODshared; 1299 if (stc & STCconst) 1300 mod |= MODconst; 1301 if (stc & STCwild) 1302 mod |= MODwild; 1303 } 1304 1305 unsigned char thismod = tthis->mod; 1306 if (hasttp) 1307 mod = MODmerge(thismod, mod); 1308 MATCH m = MODmethodConv(thismod, mod); 1309 if (m <= MATCHnomatch) 1310 goto Lnomatch; 1311 if (m < match) 1312 match = m; 1313 } 1314 } 1315 1316 // Loop through the function parameters 1317 { 1318 //printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple->objects.dim : 0); 1319 //printf("\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple->toChars() : NULL); 1320 size_t argi = 0; 1321 size_t nfargs2 = nfargs; // nfargs + supplied defaultArgs 1322 for (size_t parami = 0; parami < nfparams; parami++) 1323 { 1324 Parameter *fparam = Parameter::getNth(fparameters, parami); 1325 1326 // Apply function parameter storage classes to parameter types 1327 Type *prmtype = fparam->type->addStorageClass(fparam->storageClass); 1328 1329 Expression *farg; 1330 1331 /* See function parameters which wound up 1332 * as part of a template tuple parameter. 1333 */ 1334 if (fptupindex != IDX_NOTFOUND && parami == fptupindex) 1335 { 1336 assert(prmtype->ty == Tident); 1337 TypeIdentifier *tid = (TypeIdentifier *)prmtype; 1338 if (!declaredTuple) 1339 { 1340 /* The types of the function arguments 1341 * now form the tuple argument. 1342 */ 1343 declaredTuple = new Tuple(); 1344 (*dedargs)[parameters->dim - 1] = declaredTuple; 1345 1346 /* Count function parameters following a tuple parameter. 1347 * void foo(U, T...)(int y, T, U, int) {} // rem == 2 (U, int) 1348 */ 1349 size_t rem = 0; 1350 for (size_t j = parami + 1; j < nfparams; j++) 1351 { 1352 Parameter *p = Parameter::getNth(fparameters, j); 1353 if (!reliesOnTident(p->type, parameters, inferStart)) 1354 { 1355 Type *pt = p->type->syntaxCopy()->semantic(fd->loc, paramscope); 1356 rem += pt->ty == Ttuple ? ((TypeTuple *)pt)->arguments->dim : 1; 1357 } 1358 else 1359 { 1360 ++rem; 1361 } 1362 } 1363 1364 if (nfargs2 - argi < rem) 1365 goto Lnomatch; 1366 declaredTuple->objects.setDim(nfargs2 - argi - rem); 1367 for (size_t i = 0; i < declaredTuple->objects.dim; i++) 1368 { 1369 farg = (*fargs)[argi + i]; 1370 1371 // Check invalid arguments to detect errors early. 1372 if (farg->op == TOKerror || farg->type->ty == Terror) 1373 goto Lnomatch; 1374 1375 if (!(fparam->storageClass & STClazy) && farg->type->ty == Tvoid) 1376 goto Lnomatch; 1377 1378 Type *tt; 1379 MATCH m; 1380 if (unsigned char wm = deduceWildHelper(farg->type, &tt, tid)) 1381 { 1382 wildmatch |= wm; 1383 m = MATCHconst; 1384 } 1385 else 1386 { 1387 m = deduceTypeHelper(farg->type, &tt, tid); 1388 } 1389 if (m <= MATCHnomatch) 1390 goto Lnomatch; 1391 if (m < match) 1392 match = m; 1393 1394 /* Remove top const for dynamic array types and pointer types 1395 */ 1396 if ((tt->ty == Tarray || tt->ty == Tpointer) && 1397 !tt->isMutable() && 1398 (!(fparam->storageClass & STCref) || 1399 ((fparam->storageClass & STCauto) && !farg->isLvalue()))) 1400 { 1401 tt = tt->mutableOf(); 1402 } 1403 declaredTuple->objects[i] = tt; 1404 } 1405 declareParameter(paramscope, tp, declaredTuple); 1406 } 1407 else 1408 { 1409 // Bugzilla 6810: If declared tuple is not a type tuple, 1410 // it cannot be function parameter types. 1411 for (size_t i = 0; i < declaredTuple->objects.dim; i++) 1412 { 1413 if (!isType(declaredTuple->objects[i])) 1414 goto Lnomatch; 1415 } 1416 } 1417 assert(declaredTuple); 1418 argi += declaredTuple->objects.dim; 1419 continue; 1420 } 1421 1422 // If parameter type doesn't depend on inferred template parameters, 1423 // semantic it to get actual type. 1424 if (!reliesOnTident(prmtype, parameters, inferStart)) 1425 { 1426 // should copy prmtype to avoid affecting semantic result 1427 prmtype = prmtype->syntaxCopy()->semantic(fd->loc, paramscope); 1428 1429 if (prmtype->ty == Ttuple) 1430 { 1431 TypeTuple *tt = (TypeTuple *)prmtype; 1432 size_t tt_dim = tt->arguments->dim; 1433 for (size_t j = 0; j < tt_dim; j++, ++argi) 1434 { 1435 Parameter *p = (*tt->arguments)[j]; 1436 if (j == tt_dim - 1 && fvarargs == 2 && parami + 1 == nfparams && argi < nfargs) 1437 { 1438 prmtype = p->type; 1439 goto Lvarargs; 1440 } 1441 if (argi >= nfargs) 1442 { 1443 if (p->defaultArg) 1444 continue; 1445 goto Lnomatch; 1446 } 1447 farg = (*fargs)[argi]; 1448 if (!farg->implicitConvTo(p->type)) 1449 goto Lnomatch; 1450 } 1451 continue; 1452 } 1453 } 1454 1455 if (argi >= nfargs) // if not enough arguments 1456 { 1457 if (!fparam->defaultArg) 1458 goto Lvarargs; 1459 1460 /* Bugzilla 2803: Before the starting of type deduction from the function 1461 * default arguments, set the already deduced parameters into paramscope. 1462 * It's necessary to avoid breaking existing acceptable code. Cases: 1463 * 1464 * 1. Already deduced template parameters can appear in fparam->defaultArg: 1465 * auto foo(A, B)(A a, B b = A.stringof); 1466 * foo(1); 1467 * // at fparam == 'B b = A.string', A is equivalent with the deduced type 'int' 1468 * 1469 * 2. If prmtype depends on default-specified template parameter, the 1470 * default type should be preferred. 1471 * auto foo(N = size_t, R)(R r, N start = 0) 1472 * foo([1,2,3]); 1473 * // at fparam `N start = 0`, N should be 'size_t' before 1474 * // the deduction result from fparam->defaultArg. 1475 */ 1476 if (argi == nfargs) 1477 { 1478 for (size_t i = 0; i < dedtypes->dim; i++) 1479 { 1480 Type *at = isType((*dedtypes)[i]); 1481 if (at && at->ty == Tnone) 1482 { 1483 TypeDeduced *xt = (TypeDeduced *)at; 1484 (*dedtypes)[i] = xt->tded; // 'unbox' 1485 delete xt; 1486 } 1487 } 1488 for (size_t i = ntargs; i < dedargs->dim; i++) 1489 { 1490 TemplateParameter *tparam = (*parameters)[i]; 1491 1492 RootObject *oarg = (*dedargs)[i]; 1493 RootObject *oded = (*dedtypes)[i]; 1494 if (!oarg) 1495 { 1496 if (oded) 1497 { 1498 if (tparam->specialization() || !tparam->isTemplateTypeParameter()) 1499 { 1500 /* The specialization can work as long as afterwards 1501 * the oded == oarg 1502 */ 1503 (*dedargs)[i] = oded; 1504 MATCH m2 = tparam->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, NULL); 1505 //printf("m2 = %d\n", m2); 1506 if (m2 <= MATCHnomatch) 1507 goto Lnomatch; 1508 if (m2 < matchTiargs) 1509 matchTiargs = m2; // pick worst match 1510 if (!(*dedtypes)[i]->equals(oded)) 1511 error("specialization not allowed for deduced parameter %s", tparam->ident->toChars()); 1512 } 1513 else 1514 { 1515 if (MATCHconvert < matchTiargs) 1516 matchTiargs = MATCHconvert; 1517 } 1518 (*dedargs)[i] = declareParameter(paramscope, tparam, oded); 1519 } 1520 else 1521 { 1522 oded = tparam->defaultArg(instLoc, paramscope); 1523 if (oded) 1524 (*dedargs)[i] = declareParameter(paramscope, tparam, oded); 1525 } 1526 } 1527 } 1528 } 1529 nfargs2 = argi + 1; 1530 1531 /* If prmtype does not depend on any template parameters: 1532 * 1533 * auto foo(T)(T v, double x = 0); 1534 * foo("str"); 1535 * // at fparam == 'double x = 0' 1536 * 1537 * or, if all template parameters in the prmtype are already deduced: 1538 * 1539 * auto foo(R)(R range, ElementType!R sum = 0); 1540 * foo([1,2,3]); 1541 * // at fparam == 'ElementType!R sum = 0' 1542 * 1543 * Deducing prmtype from fparam->defaultArg is not necessary. 1544 */ 1545 if (prmtype->deco || 1546 prmtype->syntaxCopy()->trySemantic(loc, paramscope)) 1547 { 1548 ++argi; 1549 continue; 1550 } 1551 1552 // Deduce prmtype from the defaultArg. 1553 farg = fparam->defaultArg->syntaxCopy(); 1554 farg = ::semantic(farg, paramscope); 1555 farg = resolveProperties(paramscope, farg); 1556 } 1557 else 1558 { 1559 farg = (*fargs)[argi]; 1560 } 1561 { 1562 // Check invalid arguments to detect errors early. 1563 if (farg->op == TOKerror || farg->type->ty == Terror) 1564 goto Lnomatch; 1565 1566 Type *att = NULL; 1567 Lretry: 1568 Type *argtype = farg->type; 1569 1570 if (!(fparam->storageClass & STClazy) && argtype->ty == Tvoid && farg->op != TOKfunction) 1571 goto Lnomatch; 1572 1573 // Bugzilla 12876: optimize arugument to allow CT-known length matching 1574 farg = farg->optimize(WANTvalue, (fparam->storageClass & (STCref | STCout)) != 0); 1575 //printf("farg = %s %s\n", farg->type->toChars(), farg->toChars()); 1576 1577 RootObject *oarg = farg; 1578 if ((fparam->storageClass & STCref) && 1579 (!(fparam->storageClass & STCauto) || farg->isLvalue())) 1580 { 1581 /* Allow expressions that have CT-known boundaries and type [] to match with [dim] 1582 */ 1583 Type *taai; 1584 if (argtype->ty == Tarray && 1585 (prmtype->ty == Tsarray || 1586 (prmtype->ty == Taarray && (taai = ((TypeAArray *)prmtype)->index)->ty == Tident && 1587 ((TypeIdentifier *)taai)->idents.dim == 0))) 1588 { 1589 if (farg->op == TOKstring) 1590 { 1591 StringExp *se = (StringExp *)farg; 1592 argtype = se->type->nextOf()->sarrayOf(se->len); 1593 } 1594 else if (farg->op == TOKarrayliteral) 1595 { 1596 ArrayLiteralExp *ae = (ArrayLiteralExp *)farg; 1597 argtype = ae->type->nextOf()->sarrayOf(ae->elements->dim); 1598 } 1599 else if (farg->op == TOKslice) 1600 { 1601 SliceExp *se = (SliceExp *)farg; 1602 if (Type *tsa = toStaticArrayType(se)) 1603 argtype = tsa; 1604 } 1605 } 1606 1607 oarg = argtype; 1608 } 1609 else if ((fparam->storageClass & STCout) == 0 && 1610 (argtype->ty == Tarray || argtype->ty == Tpointer) && 1611 templateParameterLookup(prmtype, parameters) != IDX_NOTFOUND && 1612 ((TypeIdentifier *)prmtype)->idents.dim == 0) 1613 { 1614 /* The farg passing to the prmtype always make a copy. Therefore, 1615 * we can shrink the set of the deduced type arguments for prmtype 1616 * by adjusting top-qualifier of the argtype. 1617 * 1618 * prmtype argtype ta 1619 * T <- const(E)[] const(E)[] 1620 * T <- const(E[]) const(E)[] 1621 * qualifier(T) <- const(E)[] const(E[]) 1622 * qualifier(T) <- const(E[]) const(E[]) 1623 */ 1624 Type *ta = argtype->castMod(prmtype->mod ? argtype->nextOf()->mod : 0); 1625 if (ta != argtype) 1626 { 1627 Expression *ea = farg->copy(); 1628 ea->type = ta; 1629 oarg = ea; 1630 } 1631 } 1632 1633 if (fvarargs == 2 && parami + 1 == nfparams && argi + 1 < nfargs) 1634 goto Lvarargs; 1635 1636 unsigned wm = 0; 1637 MATCH m = deduceType(oarg, paramscope, prmtype, parameters, dedtypes, &wm, inferStart); 1638 //printf("\tL%d deduceType m = %d, wm = x%x, wildmatch = x%x\n", __LINE__, m, wm, wildmatch); 1639 wildmatch |= wm; 1640 1641 /* If no match, see if the argument can be matched by using 1642 * implicit conversions. 1643 */ 1644 if (m == MATCHnomatch && prmtype->deco) 1645 m = farg->implicitConvTo(prmtype); 1646 1647 if (m == MATCHnomatch) 1648 { 1649 AggregateDeclaration *ad = isAggregate(farg->type); 1650 if (ad && ad->aliasthis && argtype != att) 1651 { 1652 if (!att && argtype->checkAliasThisRec()) // Bugzilla 12537 1653 att = argtype; 1654 1655 /* If a semantic error occurs while doing alias this, 1656 * eg purity(bug 7295), just regard it as not a match. 1657 */ 1658 if (Expression *e = resolveAliasThis(sc, farg, true)) 1659 { 1660 farg = e; 1661 goto Lretry; 1662 } 1663 } 1664 } 1665 1666 if (m > MATCHnomatch && (fparam->storageClass & (STCref | STCauto)) == STCref) 1667 { 1668 if (!farg->isLvalue()) 1669 { 1670 if ((farg->op == TOKstring || farg->op == TOKslice) && 1671 (prmtype->ty == Tsarray || prmtype->ty == Taarray)) 1672 { 1673 // Allow conversion from T[lwr .. upr] to ref T[upr-lwr] 1674 } 1675 else 1676 goto Lnomatch; 1677 } 1678 } 1679 if (m > MATCHnomatch && (fparam->storageClass & STCout)) 1680 { 1681 if (!farg->isLvalue()) 1682 goto Lnomatch; 1683 if (!farg->type->isMutable()) // Bugzilla 11916 1684 goto Lnomatch; 1685 } 1686 if (m == MATCHnomatch && (fparam->storageClass & STClazy) && prmtype->ty == Tvoid && 1687 farg->type->ty != Tvoid) 1688 m = MATCHconvert; 1689 1690 if (m != MATCHnomatch) 1691 { 1692 if (m < match) 1693 match = m; // pick worst match 1694 argi++; 1695 continue; 1696 } 1697 } 1698 1699 Lvarargs: 1700 /* The following code for variadic arguments closely 1701 * matches TypeFunction::callMatch() 1702 */ 1703 if (!(fvarargs == 2 && parami + 1 == nfparams)) 1704 goto Lnomatch; 1705 1706 /* Check for match with function parameter T... 1707 */ 1708 Type *tb = prmtype->toBasetype(); 1709 switch (tb->ty) 1710 { 1711 // 6764 fix - TypeAArray may be TypeSArray have not yet run semantic(). 1712 case Tsarray: 1713 case Taarray: 1714 // Perhaps we can do better with this, see TypeFunction::callMatch() 1715 if (tb->ty == Tsarray) 1716 { 1717 TypeSArray *tsa = (TypeSArray *)tb; 1718 dinteger_t sz = tsa->dim->toInteger(); 1719 if (sz != nfargs - argi) 1720 goto Lnomatch; 1721 } 1722 else if (tb->ty == Taarray) 1723 { 1724 TypeAArray *taa = (TypeAArray *)tb; 1725 Expression *dim = new IntegerExp(instLoc, nfargs - argi, Type::tsize_t); 1726 1727 size_t i = templateParameterLookup(taa->index, parameters); 1728 if (i == IDX_NOTFOUND) 1729 { 1730 Expression *e; 1731 Type *t; 1732 Dsymbol *s; 1733 Scope *sco; 1734 1735 unsigned errors = global.startGagging(); 1736 /* ref: https://issues.dlang.org/show_bug.cgi?id=11118 1737 * The parameter isn't part of the template 1738 * ones, let's try to find it in the 1739 * instantiation scope 'sc' and the one 1740 * belonging to the template itself. */ 1741 sco = sc; 1742 taa->index->resolve(instLoc, sco, &e, &t, &s); 1743 if (!e) 1744 { 1745 sco = paramscope; 1746 taa->index->resolve(instLoc, sco, &e, &t, &s); 1747 } 1748 global.endGagging(errors); 1749 1750 if (!e) 1751 { 1752 goto Lnomatch; 1753 } 1754 1755 e = e->ctfeInterpret(); 1756 e = e->implicitCastTo(sco, Type::tsize_t); 1757 e = e->optimize(WANTvalue); 1758 if (!dim->equals(e)) 1759 goto Lnomatch; 1760 } 1761 else 1762 { 1763 // This code matches code in TypeInstance::deduceType() 1764 TemplateParameter *tprm = (*parameters)[i]; 1765 TemplateValueParameter *tvp = tprm->isTemplateValueParameter(); 1766 if (!tvp) 1767 goto Lnomatch; 1768 Expression *e = (Expression *)(*dedtypes)[i]; 1769 if (e) 1770 { 1771 if (!dim->equals(e)) 1772 goto Lnomatch; 1773 } 1774 else 1775 { 1776 Type *vt = tvp->valType->semantic(Loc(), sc); 1777 MATCH m = (MATCH)dim->implicitConvTo(vt); 1778 if (m <= MATCHnomatch) 1779 goto Lnomatch; 1780 (*dedtypes)[i] = dim; 1781 } 1782 } 1783 } 1784 /* fall through */ 1785 case Tarray: 1786 { 1787 TypeArray *ta = (TypeArray *)tb; 1788 Type *tret = fparam->isLazyArray(); 1789 for (; argi < nfargs; argi++) 1790 { 1791 Expression *arg = (*fargs)[argi]; 1792 assert(arg); 1793 1794 MATCH m; 1795 /* If lazy array of delegates, 1796 * convert arg(s) to delegate(s) 1797 */ 1798 if (tret) 1799 { 1800 if (ta->next->equals(arg->type)) 1801 { 1802 m = MATCHexact; 1803 } 1804 else 1805 { 1806 m = arg->implicitConvTo(tret); 1807 if (m == MATCHnomatch) 1808 { 1809 if (tret->toBasetype()->ty == Tvoid) 1810 m = MATCHconvert; 1811 } 1812 } 1813 } 1814 else 1815 { 1816 unsigned wm = 0; 1817 m = deduceType(arg, paramscope, ta->next, parameters, dedtypes, &wm, inferStart); 1818 wildmatch |= wm; 1819 } 1820 if (m == MATCHnomatch) 1821 goto Lnomatch; 1822 if (m < match) 1823 match = m; 1824 } 1825 goto Lmatch; 1826 } 1827 case Tclass: 1828 case Tident: 1829 goto Lmatch; 1830 1831 default: 1832 goto Lnomatch; 1833 } 1834 ++argi; 1835 } 1836 //printf("-> argi = %d, nfargs = %d, nfargs2 = %d\n", argi, nfargs, nfargs2); 1837 if (argi != nfargs2 && !fvarargs) 1838 goto Lnomatch; 1839 } 1840 1841 Lmatch: 1842 1843 for (size_t i = 0; i < dedtypes->dim; i++) 1844 { 1845 Type *at = isType((*dedtypes)[i]); 1846 if (at) 1847 { 1848 if (at->ty == Tnone) 1849 { 1850 TypeDeduced *xt = (TypeDeduced *)at; 1851 at = xt->tded; // 'unbox' 1852 delete xt; 1853 } 1854 (*dedtypes)[i] = at->merge2(); 1855 } 1856 } 1857 for (size_t i = ntargs; i < dedargs->dim; i++) 1858 { 1859 TemplateParameter *tparam = (*parameters)[i]; 1860 //printf("tparam[%d] = %s\n", i, tparam->ident->toChars()); 1861 /* For T:T*, the dedargs is the T*, dedtypes is the T 1862 * But for function templates, we really need them to match 1863 */ 1864 RootObject *oarg = (*dedargs)[i]; 1865 RootObject *oded = (*dedtypes)[i]; 1866 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded); 1867 //if (oarg) printf("oarg: %s\n", oarg->toChars()); 1868 //if (oded) printf("oded: %s\n", oded->toChars()); 1869 if (!oarg) 1870 { 1871 if (oded) 1872 { 1873 if (tparam->specialization() || !tparam->isTemplateTypeParameter()) 1874 { 1875 /* The specialization can work as long as afterwards 1876 * the oded == oarg 1877 */ 1878 (*dedargs)[i] = oded; 1879 MATCH m2 = tparam->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, NULL); 1880 //printf("m2 = %d\n", m2); 1881 if (m2 <= MATCHnomatch) 1882 goto Lnomatch; 1883 if (m2 < matchTiargs) 1884 matchTiargs = m2; // pick worst match 1885 if (!(*dedtypes)[i]->equals(oded)) 1886 error("specialization not allowed for deduced parameter %s", tparam->ident->toChars()); 1887 } 1888 else 1889 { 1890 if (MATCHconvert < matchTiargs) 1891 matchTiargs = MATCHconvert; 1892 } 1893 } 1894 else 1895 { 1896 oded = tparam->defaultArg(instLoc, paramscope); 1897 if (!oded) 1898 { 1899 // if tuple parameter and 1900 // tuple parameter was not in function parameter list and 1901 // we're one or more arguments short (i.e. no tuple argument) 1902 if (tparam == tp && 1903 fptupindex == IDX_NOTFOUND && 1904 ntargs <= dedargs->dim - 1) 1905 { 1906 // make tuple argument an empty tuple 1907 oded = (RootObject *)new Tuple(); 1908 } 1909 else 1910 goto Lnomatch; 1911 } 1912 if (isError(oded)) 1913 goto Lerror; 1914 ntargs++; 1915 1916 /* At the template parameter T, the picked default template argument 1917 * X!int should be matched to T in order to deduce dependent 1918 * template parameter A. 1919 * auto foo(T : X!A = X!int, A...)() { ... } 1920 * foo(); // T <-- X!int, A <-- (int) 1921 */ 1922 if (tparam->specialization()) 1923 { 1924 (*dedargs)[i] = oded; 1925 MATCH m2 = tparam->matchArg(instLoc, paramscope, dedargs, i, parameters, dedtypes, NULL); 1926 //printf("m2 = %d\n", m2); 1927 if (m2 <= MATCHnomatch) 1928 goto Lnomatch; 1929 if (m2 < matchTiargs) 1930 matchTiargs = m2; // pick worst match 1931 if (!(*dedtypes)[i]->equals(oded)) 1932 error("specialization not allowed for deduced parameter %s", tparam->ident->toChars()); 1933 } 1934 } 1935 oded = declareParameter(paramscope, tparam, oded); 1936 (*dedargs)[i] = oded; 1937 } 1938 } 1939 1940 /* Bugzilla 7469: As same as the code for 7469 in findBestMatch, 1941 * expand a Tuple in dedargs to normalize template arguments. 1942 */ 1943 if (size_t d = dedargs->dim) 1944 { 1945 if (Tuple *va = isTuple((*dedargs)[d - 1])) 1946 { 1947 if (va->objects.dim) 1948 { 1949 dedargs->setDim(d - 1); 1950 dedargs->insert(d - 1, &va->objects); 1951 } 1952 } 1953 } 1954 ti->tiargs = dedargs; // update to the normalized template arguments. 1955 1956 // Partially instantiate function for constraint and fd->leastAsSpecialized() 1957 { 1958 assert(paramsym); 1959 Scope *sc2 = _scope; 1960 sc2 = sc2->push(paramsym); 1961 sc2 = sc2->push(ti); 1962 sc2->parent = ti; 1963 sc2->tinst = ti; 1964 sc2->minst = sc->minst; 1965 1966 fd = doHeaderInstantiation(ti, sc2, fd, tthis, fargs); 1967 1968 sc2 = sc2->pop(); 1969 sc2 = sc2->pop(); 1970 1971 if (!fd) 1972 goto Lnomatch; 1973 } 1974 1975 if (constraint) 1976 { 1977 if (!evaluateConstraint(ti, sc, paramscope, dedargs, fd)) 1978 goto Lnomatch; 1979 } 1980 1981 paramscope->pop(); 1982 //printf("\tmatch %d\n", match); 1983 return (MATCH)(match | (matchTiargs<<4)); 1984 1985 Lnomatch: 1986 paramscope->pop(); 1987 //printf("\tnomatch\n"); 1988 return MATCHnomatch; 1989 1990 Lerror: // todo: for the future improvement 1991 paramscope->pop(); 1992 //printf("\terror\n"); 1993 return MATCHnomatch; 1994 } 1995 1996 /************************************************** 1997 * Declare template parameter tp with value o, and install it in the scope sc. 1998 */ 1999 2000 RootObject *TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o) 2001 { 2002 //printf("TemplateDeclaration::declareParameter('%s', o = %p)\n", tp->ident->toChars(), o); 2003 2004 Type *ta = isType(o); 2005 Expression *ea = isExpression(o); 2006 Dsymbol *sa = isDsymbol(o); 2007 Tuple *va = isTuple(o); 2008 2009 Declaration *d; 2010 VarDeclaration *v = NULL; 2011 2012 if (ea && ea->op == TOKtype) 2013 ta = ea->type; 2014 else if (ea && ea->op == TOKscope) 2015 sa = ((ScopeExp *)ea)->sds; 2016 else if (ea && (ea->op == TOKthis || ea->op == TOKsuper)) 2017 sa = ((ThisExp *)ea)->var; 2018 else if (ea && ea->op == TOKfunction) 2019 { 2020 if (((FuncExp *)ea)->td) 2021 sa = ((FuncExp *)ea)->td; 2022 else 2023 sa = ((FuncExp *)ea)->fd; 2024 } 2025 2026 if (ta) 2027 { 2028 //printf("type %s\n", ta->toChars()); 2029 d = new AliasDeclaration(Loc(), tp->ident, ta); 2030 } 2031 else if (sa) 2032 { 2033 //printf("Alias %s %s;\n", sa->ident->toChars(), tp->ident->toChars()); 2034 d = new AliasDeclaration(Loc(), tp->ident, sa); 2035 } 2036 else if (ea) 2037 { 2038 // tdtypes.data[i] always matches ea here 2039 Initializer *init = new ExpInitializer(loc, ea); 2040 TemplateValueParameter *tvp = tp->isTemplateValueParameter(); 2041 2042 Type *t = tvp ? tvp->valType : NULL; 2043 2044 v = new VarDeclaration(loc, t, tp->ident, init); 2045 v->storage_class = STCmanifest | STCtemplateparameter; 2046 d = v; 2047 } 2048 else if (va) 2049 { 2050 //printf("\ttuple\n"); 2051 d = new TupleDeclaration(loc, tp->ident, &va->objects); 2052 } 2053 else 2054 { 2055 assert(0); 2056 } 2057 2058 d->storage_class |= STCtemplateparameter; 2059 if (ta) 2060 { 2061 Type *t = ta; 2062 // consistent with Type::checkDeprecated() 2063 while (t->ty != Tenum) 2064 { 2065 if (!t->nextOf()) break; 2066 t = ((TypeNext *)t)->next; 2067 } 2068 if (Dsymbol *s = t->toDsymbol(sc)) 2069 { 2070 if (s->isDeprecated()) 2071 d->storage_class |= STCdeprecated; 2072 } 2073 } 2074 else if (sa) 2075 { 2076 if (sa->isDeprecated()) 2077 d->storage_class |= STCdeprecated; 2078 } 2079 2080 if (!sc->insert(d)) 2081 error("declaration %s is already defined", tp->ident->toChars()); 2082 d->semantic(sc); 2083 2084 /* So the caller's o gets updated with the result of semantic() being run on o 2085 */ 2086 if (v) 2087 o = initializerToExpression(v->_init); 2088 return o; 2089 } 2090 2091 /************************************** 2092 * Determine if TemplateDeclaration is variadic. 2093 */ 2094 2095 TemplateTupleParameter *isVariadic(TemplateParameters *parameters) 2096 { 2097 size_t dim = parameters->dim; 2098 TemplateTupleParameter *tp = NULL; 2099 2100 if (dim) 2101 tp = ((*parameters)[dim - 1])->isTemplateTupleParameter(); 2102 return tp; 2103 } 2104 2105 TemplateTupleParameter *TemplateDeclaration::isVariadic() 2106 { 2107 return ::isVariadic(parameters); 2108 } 2109 2110 /*********************************** 2111 * We can overload templates. 2112 */ 2113 2114 bool TemplateDeclaration::isOverloadable() 2115 { 2116 return true; 2117 } 2118 2119 /************************************************* 2120 * Given function arguments, figure out which template function 2121 * to expand, and return matching result. 2122 * Input: 2123 * m matching result 2124 * dstart the root of overloaded function templates 2125 * loc instantiation location 2126 * sc instantiation scope 2127 * tiargs initial list of template arguments 2128 * tthis if !NULL, the 'this' pointer argument 2129 * fargs arguments to function 2130 */ 2131 2132 void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc, 2133 Objects *tiargs, Type *tthis, Expressions *fargs) 2134 { 2135 struct ParamDeduce 2136 { 2137 // context 2138 Loc loc; 2139 Scope *sc; 2140 Type *tthis; 2141 Objects *tiargs; 2142 Expressions *fargs; 2143 // result 2144 Match *m; 2145 int property; // 0: unintialized 2146 // 1: seen @property 2147 // 2: not @property 2148 size_t ov_index; 2149 TemplateDeclaration *td_best; 2150 TemplateInstance *ti_best; 2151 MATCH ta_last; 2152 Type *tthis_best; 2153 2154 static int fp(void *param, Dsymbol *s) 2155 { 2156 if (s->errors) 2157 return 0; 2158 if (FuncDeclaration *fd = s->isFuncDeclaration()) 2159 return ((ParamDeduce *)param)->applyFunction(fd); 2160 if (TemplateDeclaration *td = s->isTemplateDeclaration()) 2161 return ((ParamDeduce *)param)->applyTemplate(td); 2162 return 0; 2163 } 2164 2165 int applyFunction(FuncDeclaration *fd) 2166 { 2167 // skip duplicates 2168 if (fd == m->lastf) 2169 return 0; 2170 // explicitly specified tiargs never match to non template function 2171 if (tiargs && tiargs->dim > 0) 2172 return 0; 2173 2174 // constructors need a valid scope in order to detect semantic errors 2175 if (!fd->isCtorDeclaration() && 2176 fd->semanticRun < PASSsemanticdone) 2177 { 2178 Ungag ungag = fd->ungagSpeculative(); 2179 fd->semantic(NULL); 2180 } 2181 if (fd->semanticRun < PASSsemanticdone) 2182 { 2183 ::error(loc, "forward reference to template %s", fd->toChars()); 2184 return 1; 2185 } 2186 //printf("fd = %s %s, fargs = %s\n", fd->toChars(), fd->type->toChars(), fargs->toChars()); 2187 m->anyf = fd; 2188 TypeFunction *tf = (TypeFunction *)fd->type; 2189 2190 int prop = (tf->isproperty) ? 1 : 2; 2191 if (property == 0) 2192 property = prop; 2193 else if (property != prop) 2194 error(fd->loc, "cannot overload both property and non-property functions"); 2195 2196 /* For constructors, qualifier check will be opposite direction. 2197 * Qualified constructor always makes qualified object, then will be checked 2198 * that it is implicitly convertible to tthis. 2199 */ 2200 Type *tthis_fd = fd->needThis() ? tthis : NULL; 2201 bool isCtorCall = tthis_fd && fd->isCtorDeclaration(); 2202 if (isCtorCall) 2203 { 2204 //printf("%s tf->mod = x%x tthis_fd->mod = x%x %d\n", tf->toChars(), 2205 // tf->mod, tthis_fd->mod, fd->isolateReturn()); 2206 if (MODimplicitConv(tf->mod, tthis_fd->mod) || 2207 (tf->isWild() && tf->isShared() == tthis_fd->isShared()) || 2208 fd->isolateReturn()) 2209 { 2210 /* && tf->isShared() == tthis_fd->isShared()*/ 2211 // Uniquely constructed object can ignore shared qualifier. 2212 // TODO: Is this appropriate? 2213 tthis_fd = NULL; 2214 } 2215 else 2216 return 0; // MATCHnomatch 2217 } 2218 MATCH mfa = tf->callMatch(tthis_fd, fargs); 2219 //printf("test1: mfa = %d\n", mfa); 2220 if (mfa > MATCHnomatch) 2221 { 2222 if (mfa > m->last) goto LfIsBetter; 2223 if (mfa < m->last) goto LlastIsBetter; 2224 2225 /* See if one of the matches overrides the other. 2226 */ 2227 assert(m->lastf); 2228 if (m->lastf->overrides(fd)) goto LlastIsBetter; 2229 if (fd->overrides(m->lastf)) goto LfIsBetter; 2230 2231 /* Try to disambiguate using template-style partial ordering rules. 2232 * In essence, if f() and g() are ambiguous, if f() can call g(), 2233 * but g() cannot call f(), then pick f(). 2234 * This is because f() is "more specialized." 2235 */ 2236 { 2237 MATCH c1 = fd->leastAsSpecialized(m->lastf); 2238 MATCH c2 = m->lastf->leastAsSpecialized(fd); 2239 //printf("c1 = %d, c2 = %d\n", c1, c2); 2240 if (c1 > c2) goto LfIsBetter; 2241 if (c1 < c2) goto LlastIsBetter; 2242 } 2243 2244 /* The 'overrides' check above does covariant checking only 2245 * for virtual member functions. It should do it for all functions, 2246 * but in order to not risk breaking code we put it after 2247 * the 'leastAsSpecialized' check. 2248 * In the future try moving it before. 2249 * I.e. a not-the-same-but-covariant match is preferred, 2250 * as it is more restrictive. 2251 */ 2252 if (!m->lastf->type->equals(fd->type)) 2253 { 2254 //printf("cov: %d %d\n", m->lastf->type->covariant(fd->type), fd->type->covariant(m->lastf->type)); 2255 if (m->lastf->type->covariant(fd->type) == 1) goto LlastIsBetter; 2256 if (fd->type->covariant(m->lastf->type) == 1) goto LfIsBetter; 2257 } 2258 2259 /* If the two functions are the same function, like: 2260 * int foo(int); 2261 * int foo(int x) { ... } 2262 * then pick the one with the body. 2263 */ 2264 if (tf->equals(m->lastf->type) && 2265 fd->storage_class == m->lastf->storage_class && 2266 fd->parent == m->lastf->parent && 2267 fd->protection == m->lastf->protection && 2268 fd->linkage == m->lastf->linkage) 2269 { 2270 if ( fd->fbody && !m->lastf->fbody) goto LfIsBetter; 2271 if (!fd->fbody && m->lastf->fbody) goto LlastIsBetter; 2272 } 2273 2274 // Bugzilla 14450: Prefer exact qualified constructor for the creating object type 2275 if (isCtorCall && tf->mod != m->lastf->type->mod) 2276 { 2277 if (tthis->mod == tf->mod) goto LfIsBetter; 2278 if (tthis->mod == m->lastf->type->mod) goto LlastIsBetter; 2279 } 2280 2281 m->nextf = fd; 2282 m->count++; 2283 return 0; 2284 2285 LlastIsBetter: 2286 return 0; 2287 2288 LfIsBetter: 2289 td_best = NULL; 2290 ti_best = NULL; 2291 ta_last = MATCHexact; 2292 m->last = mfa; 2293 m->lastf = fd; 2294 tthis_best = tthis_fd; 2295 ov_index = 0; 2296 m->count = 1; 2297 return 0; 2298 } 2299 return 0; 2300 } 2301 2302 int applyTemplate(TemplateDeclaration *td) 2303 { 2304 //printf("applyTemplate()\n"); 2305 // skip duplicates 2306 if (td == td_best) 2307 return 0; 2308 2309 if (!sc) 2310 sc = td->_scope; // workaround for Type::aliasthisOf 2311 2312 if (td->semanticRun == PASSinit && td->_scope) 2313 { 2314 // Try to fix forward reference. Ungag errors while doing so. 2315 Ungag ungag = td->ungagSpeculative(); 2316 td->semantic(td->_scope); 2317 } 2318 if (td->semanticRun == PASSinit) 2319 { 2320 ::error(loc, "forward reference to template %s", td->toChars()); 2321 Lerror: 2322 m->lastf = NULL; 2323 m->count = 0; 2324 m->last = MATCHnomatch; 2325 return 1; 2326 } 2327 //printf("td = %s\n", td->toChars()); 2328 2329 FuncDeclaration *f; 2330 f = td->onemember ? td->onemember->isFuncDeclaration() : NULL; 2331 if (!f) 2332 { 2333 if (!tiargs) 2334 tiargs = new Objects(); 2335 TemplateInstance *ti = new TemplateInstance(loc, td, tiargs); 2336 Objects dedtypes; 2337 dedtypes.setDim(td->parameters->dim); 2338 assert(td->semanticRun != PASSinit); 2339 MATCH mta = td->matchWithInstance(sc, ti, &dedtypes, fargs, 0); 2340 //printf("matchWithInstance = %d\n", mta); 2341 if (mta <= MATCHnomatch || mta < ta_last) // no match or less match 2342 return 0; 2343 2344 ti->semantic(sc, fargs); 2345 if (!ti->inst) // if template failed to expand 2346 return 0; 2347 2348 Dsymbol *s = ti->inst->toAlias(); 2349 FuncDeclaration *fd; 2350 if (TemplateDeclaration *tdx = s->isTemplateDeclaration()) 2351 { 2352 Objects dedtypesX; // empty tiargs 2353 2354 // Bugzilla 11553: Check for recursive instantiation of tdx. 2355 for (TemplatePrevious *p = tdx->previous; p; p = p->prev) 2356 { 2357 if (arrayObjectMatch(p->dedargs, &dedtypesX)) 2358 { 2359 //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars()); 2360 /* It must be a subscope of p->sc, other scope chains are not recursive 2361 * instantiations. 2362 */ 2363 for (Scope *scx = sc; scx; scx = scx->enclosing) 2364 { 2365 if (scx == p->sc) 2366 { 2367 error(loc, "recursive template expansion while looking for %s.%s", ti->toChars(), tdx->toChars()); 2368 goto Lerror; 2369 } 2370 } 2371 } 2372 /* BUG: should also check for ref param differences 2373 */ 2374 } 2375 2376 TemplatePrevious pr; 2377 pr.prev = tdx->previous; 2378 pr.sc = sc; 2379 pr.dedargs = &dedtypesX; 2380 tdx->previous = ≺ // add this to threaded list 2381 2382 fd = resolveFuncCall(loc, sc, s, NULL, tthis, fargs, 1); 2383 2384 tdx->previous = pr.prev; // unlink from threaded list 2385 } 2386 else if (s->isFuncDeclaration()) 2387 { 2388 fd = resolveFuncCall(loc, sc, s, NULL, tthis, fargs, 1); 2389 } 2390 else 2391 goto Lerror; 2392 2393 if (!fd) 2394 return 0; 2395 2396 if (fd->type->ty != Tfunction) 2397 { 2398 m->lastf = fd; // to propagate "error match" 2399 m->count = 1; 2400 m->last = MATCHnomatch; 2401 return 1; 2402 } 2403 2404 Type *tthis_fd = fd->needThis() && !fd->isCtorDeclaration() ? tthis : NULL; 2405 2406 TypeFunction *tf = (TypeFunction *)fd->type; 2407 MATCH mfa = tf->callMatch(tthis_fd, fargs); 2408 if (mfa < m->last) 2409 return 0; 2410 2411 if (mta < ta_last) goto Ltd_best2; 2412 if (mta > ta_last) goto Ltd2; 2413 2414 if (mfa < m->last) goto Ltd_best2; 2415 if (mfa > m->last) goto Ltd2; 2416 2417 //printf("Lambig2\n"); 2418 m->nextf = fd; 2419 m->count++; 2420 return 0; 2421 2422 Ltd_best2: 2423 return 0; 2424 2425 Ltd2: 2426 // td is the new best match 2427 assert(td->_scope); 2428 td_best = td; 2429 ti_best = NULL; 2430 property = 0; // (backward compatibility) 2431 ta_last = mta; 2432 m->last = mfa; 2433 m->lastf = fd; 2434 tthis_best = tthis_fd; 2435 ov_index = 0; 2436 m->nextf = NULL; 2437 m->count = 1; 2438 return 0; 2439 } 2440 2441 //printf("td = %s\n", td->toChars()); 2442 for (size_t ovi = 0; f; f = f->overnext0, ovi++) 2443 { 2444 if (f->type->ty != Tfunction || f->errors) 2445 goto Lerror; 2446 2447 /* This is a 'dummy' instance to evaluate constraint properly. 2448 */ 2449 TemplateInstance *ti = new TemplateInstance(loc, td, tiargs); 2450 ti->parent = td->parent; // Maybe calculating valid 'enclosing' is unnecessary. 2451 2452 FuncDeclaration *fd = f; 2453 int x = td->deduceFunctionTemplateMatch(ti, sc, fd, tthis, fargs); 2454 MATCH mta = (MATCH)(x >> 4); 2455 MATCH mfa = (MATCH)(x & 0xF); 2456 //printf("match:t/f = %d/%d\n", mta, mfa); 2457 if (!fd || mfa == MATCHnomatch) 2458 continue; 2459 2460 Type *tthis_fd = fd->needThis() ? tthis : NULL; 2461 2462 bool isCtorCall = tthis_fd && fd->isCtorDeclaration(); 2463 if (isCtorCall) 2464 { 2465 // Constructor call requires additional check. 2466 2467 TypeFunction *tf = (TypeFunction *)fd->type; 2468 assert(tf->next); 2469 if (MODimplicitConv(tf->mod, tthis_fd->mod) || 2470 (tf->isWild() && tf->isShared() == tthis_fd->isShared()) || 2471 fd->isolateReturn()) 2472 { 2473 tthis_fd = NULL; 2474 } 2475 else 2476 continue; // MATCHnomatch 2477 } 2478 2479 if (mta < ta_last) goto Ltd_best; 2480 if (mta > ta_last) goto Ltd; 2481 2482 if (mfa < m->last) goto Ltd_best; 2483 if (mfa > m->last) goto Ltd; 2484 2485 if (td_best) 2486 { 2487 // Disambiguate by picking the most specialized TemplateDeclaration 2488 MATCH c1 = td->leastAsSpecialized(sc, td_best, fargs); 2489 MATCH c2 = td_best->leastAsSpecialized(sc, td, fargs); 2490 //printf("1: c1 = %d, c2 = %d\n", c1, c2); 2491 if (c1 > c2) goto Ltd; 2492 if (c1 < c2) goto Ltd_best; 2493 } 2494 assert(fd && m->lastf); 2495 { 2496 // Disambiguate by tf->callMatch 2497 TypeFunction *tf1 = (TypeFunction *)fd->type; 2498 assert(tf1->ty == Tfunction); 2499 TypeFunction *tf2 = (TypeFunction *)m->lastf->type; 2500 assert(tf2->ty == Tfunction); 2501 MATCH c1 = tf1->callMatch(tthis_fd, fargs); 2502 MATCH c2 = tf2->callMatch(tthis_best, fargs); 2503 //printf("2: c1 = %d, c2 = %d\n", c1, c2); 2504 if (c1 > c2) goto Ltd; 2505 if (c1 < c2) goto Ltd_best; 2506 } 2507 { 2508 // Disambiguate by picking the most specialized FunctionDeclaration 2509 MATCH c1 = fd->leastAsSpecialized(m->lastf); 2510 MATCH c2 = m->lastf->leastAsSpecialized(fd); 2511 //printf("3: c1 = %d, c2 = %d\n", c1, c2); 2512 if (c1 > c2) goto Ltd; 2513 if (c1 < c2) goto Ltd_best; 2514 } 2515 2516 // Bugzilla 14450: Prefer exact qualified constructor for the creating object type 2517 if (isCtorCall && fd->type->mod != m->lastf->type->mod) 2518 { 2519 if (tthis->mod == fd->type->mod) goto Ltd; 2520 if (tthis->mod == m->lastf->type->mod) goto Ltd_best; 2521 } 2522 2523 m->nextf = fd; 2524 m->count++; 2525 continue; 2526 2527 Ltd_best: // td_best is the best match so far 2528 //printf("Ltd_best\n"); 2529 continue; 2530 2531 Ltd: // td is the new best match 2532 //printf("Ltd\n"); 2533 assert(td->_scope); 2534 td_best = td; 2535 ti_best = ti; 2536 property = 0; // (backward compatibility) 2537 ta_last = mta; 2538 m->last = mfa; 2539 m->lastf = fd; 2540 tthis_best = tthis_fd; 2541 ov_index = ovi; 2542 m->nextf = NULL; 2543 m->count = 1; 2544 continue; 2545 } 2546 return 0; 2547 } 2548 }; 2549 ParamDeduce p; 2550 // context 2551 p.loc = loc; 2552 p.sc = sc; 2553 p.tthis = tthis; 2554 p.tiargs = tiargs; 2555 p.fargs = fargs; 2556 2557 // result 2558 p.m = m; 2559 p.property = 0; 2560 p.ov_index = 0; 2561 p.td_best = NULL; 2562 p.ti_best = NULL; 2563 p.ta_last = m->last != MATCHnomatch ? MATCHexact : MATCHnomatch; 2564 p.tthis_best = NULL; 2565 2566 TemplateDeclaration *td = dstart->isTemplateDeclaration(); 2567 if (td && td->funcroot) 2568 dstart = td->funcroot; 2569 2570 overloadApply(dstart, &p, &ParamDeduce::fp); 2571 2572 //printf("td_best = %p, m->lastf = %p\n", p.td_best, m->lastf); 2573 if (p.td_best && p.ti_best && m->count == 1) 2574 { 2575 // Matches to template function 2576 assert(p.td_best->onemember && p.td_best->onemember->isFuncDeclaration()); 2577 2578 /* The best match is td_best with arguments tdargs. 2579 * Now instantiate the template. 2580 */ 2581 assert(p.td_best->_scope); 2582 if (!sc) 2583 sc = p.td_best->_scope; // workaround for Type::aliasthisOf 2584 2585 TemplateInstance *ti = new TemplateInstance(loc, p.td_best, p.ti_best->tiargs); 2586 ti->semantic(sc, fargs); 2587 2588 m->lastf = ti->toAlias()->isFuncDeclaration(); 2589 if (!m->lastf) 2590 goto Lnomatch; 2591 if (ti->errors) 2592 { 2593 Lerror: 2594 m->count = 1; 2595 assert(m->lastf); 2596 m->last = MATCHnomatch; 2597 return; 2598 } 2599 2600 // look forward instantiated overload function 2601 // Dsymbol::oneMembers is alredy called in TemplateInstance::semantic. 2602 // it has filled overnext0d 2603 while (p.ov_index--) 2604 { 2605 m->lastf = m->lastf->overnext0; 2606 assert(m->lastf); 2607 } 2608 2609 p.tthis_best = m->lastf->needThis() && !m->lastf->isCtorDeclaration() ? tthis : NULL; 2610 2611 TypeFunction *tf = (TypeFunction *)m->lastf->type; 2612 if (tf->ty == Terror) 2613 goto Lerror; 2614 assert(tf->ty == Tfunction); 2615 if (!tf->callMatch(p.tthis_best, fargs)) 2616 goto Lnomatch; 2617 2618 /* As Bugzilla 3682 shows, a template instance can be matched while instantiating 2619 * that same template. Thus, the function type can be incomplete. Complete it. 2620 * 2621 * Bugzilla 9208: For auto function, completion should be deferred to the end of 2622 * its semantic3. Should not complete it in here. 2623 */ 2624 if (tf->next && !m->lastf->inferRetType) 2625 { 2626 m->lastf->type = tf->semantic(loc, sc); 2627 } 2628 } 2629 else if (m->lastf) 2630 { 2631 // Matches to non template function, 2632 // or found matches were ambiguous. 2633 assert(m->count >= 1); 2634 } 2635 else 2636 { 2637 Lnomatch: 2638 m->count = 0; 2639 m->lastf = NULL; 2640 m->last = MATCHnomatch; 2641 } 2642 } 2643 2644 /************************************************* 2645 * Limited function template instantiation for using fd->leastAsSpecialized() 2646 */ 2647 FuncDeclaration *TemplateDeclaration::doHeaderInstantiation( 2648 TemplateInstance *ti, Scope *sc2, 2649 FuncDeclaration *fd, Type *tthis, Expressions *fargs) 2650 { 2651 assert(fd); 2652 2653 // function body and contracts are not need 2654 if (fd->isCtorDeclaration()) 2655 fd = new CtorDeclaration(fd->loc, fd->endloc, fd->storage_class, fd->type->syntaxCopy()); 2656 else 2657 fd = new FuncDeclaration(fd->loc, fd->endloc, fd->ident, fd->storage_class, fd->type->syntaxCopy()); 2658 fd->parent = ti; 2659 2660 assert(fd->type->ty == Tfunction); 2661 TypeFunction *tf = (TypeFunction *)fd->type; 2662 tf->fargs = fargs; 2663 2664 if (tthis) 2665 { 2666 // Match 'tthis' to any TemplateThisParameter's 2667 bool hasttp = false; 2668 for (size_t i = 0; i < parameters->dim; i++) 2669 { 2670 TemplateParameter *tp = (*parameters)[i]; 2671 TemplateThisParameter *ttp = tp->isTemplateThisParameter(); 2672 if (ttp) 2673 hasttp = true; 2674 } 2675 if (hasttp) 2676 { 2677 tf = (TypeFunction *)tf->addSTC(ModToStc(tthis->mod)); 2678 assert(!tf->deco); 2679 } 2680 } 2681 2682 Scope *scx = sc2->push(); 2683 2684 // Shouldn't run semantic on default arguments and return type. 2685 for (size_t i = 0; i < tf->parameters->dim; i++) 2686 (*tf->parameters)[i]->defaultArg = NULL; 2687 if (fd->isCtorDeclaration()) 2688 { 2689 // For constructors, emitting return type is necessary for 2690 // isolateReturn() in functionResolve. 2691 scx->flags |= SCOPEctor; 2692 2693 Dsymbol *parent = toParent2(); 2694 Type *tret; 2695 AggregateDeclaration *ad = parent->isAggregateDeclaration(); 2696 if (!ad || parent->isUnionDeclaration()) 2697 { 2698 tret = Type::tvoid; 2699 } 2700 else 2701 { 2702 tret = ad->handleType(); 2703 assert(tret); 2704 tret = tret->addStorageClass(fd->storage_class | scx->stc); 2705 tret = tret->addMod(tf->mod); 2706 } 2707 tf->next = tret; 2708 if (ad && ad->isStructDeclaration()) 2709 tf->isref = 1; 2710 //printf("tf = %s\n", tf->toChars()); 2711 } 2712 else 2713 tf->next = NULL; 2714 fd->type = tf; 2715 fd->type = fd->type->addSTC(scx->stc); 2716 fd->type = fd->type->semantic(fd->loc, scx); 2717 scx = scx->pop(); 2718 2719 if (fd->type->ty != Tfunction) 2720 return NULL; 2721 2722 fd->originalType = fd->type; // for mangling 2723 //printf("\t[%s] fd->type = %s, mod = %x, ", loc.toChars(), fd->type->toChars(), fd->type->mod); 2724 //printf("fd->needThis() = %d\n", fd->needThis()); 2725 2726 return fd; 2727 } 2728 2729 bool TemplateDeclaration::hasStaticCtorOrDtor() 2730 { 2731 return false; // don't scan uninstantiated templates 2732 } 2733 2734 const char *TemplateDeclaration::toChars() 2735 { 2736 if (literal) 2737 return Dsymbol::toChars(); 2738 2739 OutBuffer buf; 2740 HdrGenState hgs; 2741 2742 buf.writestring(ident->toChars()); 2743 buf.writeByte('('); 2744 for (size_t i = 0; i < parameters->dim; i++) 2745 { 2746 TemplateParameter *tp = (*parameters)[i]; 2747 if (i) 2748 buf.writestring(", "); 2749 ::toCBuffer(tp, &buf, &hgs); 2750 } 2751 buf.writeByte(')'); 2752 2753 if (onemember) 2754 { 2755 FuncDeclaration *fd = onemember->isFuncDeclaration(); 2756 if (fd && fd->type) 2757 { 2758 TypeFunction *tf = (TypeFunction *)fd->type; 2759 buf.writestring(parametersTypeToChars(tf->parameters, tf->varargs)); 2760 } 2761 } 2762 2763 if (constraint) 2764 { 2765 buf.writestring(" if ("); 2766 ::toCBuffer(constraint, &buf, &hgs); 2767 buf.writeByte(')'); 2768 } 2769 return buf.extractString(); 2770 } 2771 2772 Prot TemplateDeclaration::prot() 2773 { 2774 return protection; 2775 } 2776 2777 /**************************************************** 2778 * Given a new instance tithis of this TemplateDeclaration, 2779 * see if there already exists an instance. 2780 * If so, return that existing instance. 2781 */ 2782 2783 TemplateInstance *TemplateDeclaration::findExistingInstance(TemplateInstance *tithis, Expressions *fargs) 2784 { 2785 //printf("findExistingInstance(%p)\n", tithis); 2786 tithis->fargs = fargs; 2787 TemplateInstances *tinstances = (TemplateInstances *)dmd_aaGetRvalue((AA *)instances, (void *)tithis->toHash()); 2788 if (tinstances) 2789 { 2790 for (size_t i = 0; i < tinstances->dim; i++) 2791 { 2792 TemplateInstance *ti = (*tinstances)[i]; 2793 if (tithis->compare(ti) == 0) 2794 return ti; 2795 } 2796 } 2797 return NULL; 2798 } 2799 2800 /******************************************** 2801 * Add instance ti to TemplateDeclaration's table of instances. 2802 * Return a handle we can use to later remove it if it fails instantiation. 2803 */ 2804 2805 TemplateInstance *TemplateDeclaration::addInstance(TemplateInstance *ti) 2806 { 2807 //printf("addInstance() %p %p\n", instances, ti); 2808 TemplateInstances **ptinstances = (TemplateInstances **)dmd_aaGet((AA **)&instances, (void *)ti->toHash()); 2809 if (!*ptinstances) 2810 *ptinstances = new TemplateInstances(); 2811 (*ptinstances)->push(ti); 2812 return ti; 2813 } 2814 2815 /******************************************* 2816 * Remove TemplateInstance from table of instances. 2817 * Input: 2818 * handle returned by addInstance() 2819 */ 2820 2821 void TemplateDeclaration::removeInstance(TemplateInstance *handle) 2822 { 2823 //printf("removeInstance()\n"); 2824 TemplateInstances *tinstances = (TemplateInstances *)dmd_aaGetRvalue((AA *)instances, (void *)handle->toHash()); 2825 if (tinstances) 2826 { 2827 for (size_t i = 0; i < tinstances->dim; i++) 2828 { 2829 TemplateInstance *ti = (*tinstances)[i]; 2830 if (handle == ti) 2831 { 2832 tinstances->remove(i); 2833 break; 2834 } 2835 } 2836 } 2837 } 2838 2839 /* ======================== Type ============================================ */ 2840 2841 /**** 2842 * Given an identifier, figure out which TemplateParameter it is. 2843 * Return IDX_NOTFOUND if not found. 2844 */ 2845 2846 static size_t templateIdentifierLookup(Identifier *id, TemplateParameters *parameters) 2847 { 2848 for (size_t i = 0; i < parameters->dim; i++) 2849 { 2850 TemplateParameter *tp = (*parameters)[i]; 2851 if (tp->ident->equals(id)) 2852 return i; 2853 } 2854 return IDX_NOTFOUND; 2855 } 2856 2857 size_t templateParameterLookup(Type *tparam, TemplateParameters *parameters) 2858 { 2859 if (tparam->ty == Tident) 2860 { 2861 TypeIdentifier *tident = (TypeIdentifier *)tparam; 2862 //printf("\ttident = '%s'\n", tident->toChars()); 2863 return templateIdentifierLookup(tident->ident, parameters); 2864 } 2865 return IDX_NOTFOUND; 2866 } 2867 2868 unsigned char deduceWildHelper(Type *t, Type **at, Type *tparam) 2869 { 2870 if ((tparam->mod & MODwild) == 0) 2871 return 0; 2872 2873 *at = NULL; 2874 2875 #define X(U,T) ((U) << 4) | (T) 2876 switch (X(tparam->mod, t->mod)) 2877 { 2878 case X(MODwild, 0): 2879 case X(MODwild, MODconst): 2880 case X(MODwild, MODshared): 2881 case X(MODwild, MODshared | MODconst): 2882 case X(MODwild, MODimmutable): 2883 case X(MODwildconst, 0): 2884 case X(MODwildconst, MODconst): 2885 case X(MODwildconst, MODshared): 2886 case X(MODwildconst, MODshared | MODconst): 2887 case X(MODwildconst, MODimmutable): 2888 case X(MODshared | MODwild, MODshared): 2889 case X(MODshared | MODwild, MODshared | MODconst): 2890 case X(MODshared | MODwild, MODimmutable): 2891 case X(MODshared | MODwildconst, MODshared): 2892 case X(MODshared | MODwildconst, MODshared | MODconst): 2893 case X(MODshared | MODwildconst, MODimmutable): 2894 { 2895 unsigned char wm = (t->mod & ~MODshared); 2896 if (wm == 0) 2897 wm = MODmutable; 2898 unsigned char m = (t->mod & (MODconst | MODimmutable)) | (tparam->mod & t->mod & MODshared); 2899 *at = t->unqualify(m); 2900 return wm; 2901 } 2902 2903 case X(MODwild, MODwild): 2904 case X(MODwild, MODwildconst): 2905 case X(MODwild, MODshared | MODwild): 2906 case X(MODwild, MODshared | MODwildconst): 2907 case X(MODwildconst, MODwild): 2908 case X(MODwildconst, MODwildconst): 2909 case X(MODwildconst, MODshared | MODwild): 2910 case X(MODwildconst, MODshared | MODwildconst): 2911 case X(MODshared | MODwild, MODshared | MODwild): 2912 case X(MODshared | MODwild, MODshared | MODwildconst): 2913 case X(MODshared | MODwildconst, MODshared | MODwild): 2914 case X(MODshared | MODwildconst, MODshared | MODwildconst): 2915 { 2916 *at = t->unqualify(tparam->mod & t->mod); 2917 return MODwild; 2918 } 2919 2920 default: 2921 return 0; 2922 } 2923 #undef X 2924 } 2925 2926 MATCH deduceTypeHelper(Type *t, Type **at, Type *tparam) 2927 { 2928 // 9*9 == 81 cases 2929 2930 #define X(U,T) ((U) << 4) | (T) 2931 switch (X(tparam->mod, t->mod)) 2932 { 2933 case X(0, 0): 2934 case X(0, MODconst): 2935 case X(0, MODwild): 2936 case X(0, MODwildconst): 2937 case X(0, MODshared): 2938 case X(0, MODshared | MODconst): 2939 case X(0, MODshared | MODwild): 2940 case X(0, MODshared | MODwildconst): 2941 case X(0, MODimmutable): 2942 // foo(U) T => T 2943 // foo(U) const(T) => const(T) 2944 // foo(U) inout(T) => inout(T) 2945 // foo(U) inout(const(T)) => inout(const(T)) 2946 // foo(U) shared(T) => shared(T) 2947 // foo(U) shared(const(T)) => shared(const(T)) 2948 // foo(U) shared(inout(T)) => shared(inout(T)) 2949 // foo(U) shared(inout(const(T))) => shared(inout(const(T))) 2950 // foo(U) immutable(T) => immutable(T) 2951 { 2952 *at = t; 2953 return MATCHexact; 2954 } 2955 2956 case X(MODconst, MODconst): 2957 case X(MODwild, MODwild): 2958 case X(MODwildconst, MODwildconst): 2959 case X(MODshared, MODshared): 2960 case X(MODshared | MODconst, MODshared | MODconst): 2961 case X(MODshared | MODwild, MODshared | MODwild): 2962 case X(MODshared | MODwildconst, MODshared | MODwildconst): 2963 case X(MODimmutable, MODimmutable): 2964 // foo(const(U)) const(T) => T 2965 // foo(inout(U)) inout(T) => T 2966 // foo(inout(const(U))) inout(const(T)) => T 2967 // foo(shared(U)) shared(T) => T 2968 // foo(shared(const(U))) shared(const(T)) => T 2969 // foo(shared(inout(U))) shared(inout(T)) => T 2970 // foo(shared(inout(const(U)))) shared(inout(const(T))) => T 2971 // foo(immutable(U)) immutable(T) => T 2972 { 2973 *at = t->mutableOf()->unSharedOf(); 2974 return MATCHexact; 2975 } 2976 2977 case X(MODconst, 0): 2978 case X(MODconst, MODwild): 2979 case X(MODconst, MODwildconst): 2980 case X(MODconst, MODshared | MODconst): 2981 case X(MODconst, MODshared | MODwild): 2982 case X(MODconst, MODshared | MODwildconst): 2983 case X(MODconst, MODimmutable): 2984 case X(MODwild, MODshared | MODwild): 2985 case X(MODwildconst, MODshared | MODwildconst): 2986 case X(MODshared | MODconst, MODimmutable): 2987 // foo(const(U)) T => T 2988 // foo(const(U)) inout(T) => T 2989 // foo(const(U)) inout(const(T)) => T 2990 // foo(const(U)) shared(const(T)) => shared(T) 2991 // foo(const(U)) shared(inout(T)) => shared(T) 2992 // foo(const(U)) shared(inout(const(T))) => shared(T) 2993 // foo(const(U)) immutable(T) => T 2994 // foo(inout(U)) shared(inout(T)) => shared(T) 2995 // foo(inout(const(U))) shared(inout(const(T))) => shared(T) 2996 // foo(shared(const(U))) immutable(T) => T 2997 { 2998 *at = t->mutableOf(); 2999 return MATCHconst; 3000 } 3001 3002 case X(MODconst, MODshared): 3003 // foo(const(U)) shared(T) => shared(T) 3004 { 3005 *at = t; 3006 return MATCHconst; 3007 } 3008 3009 case X(MODshared, MODshared | MODconst): 3010 case X(MODshared, MODshared | MODwild): 3011 case X(MODshared, MODshared | MODwildconst): 3012 case X(MODshared | MODconst, MODshared): 3013 // foo(shared(U)) shared(const(T)) => const(T) 3014 // foo(shared(U)) shared(inout(T)) => inout(T) 3015 // foo(shared(U)) shared(inout(const(T))) => inout(const(T)) 3016 // foo(shared(const(U))) shared(T) => T 3017 { 3018 *at = t->unSharedOf(); 3019 return MATCHconst; 3020 } 3021 3022 case X(MODwildconst, MODimmutable): 3023 case X(MODshared | MODconst, MODshared | MODwildconst): 3024 case X(MODshared | MODwildconst, MODimmutable): 3025 case X(MODshared | MODwildconst, MODshared | MODwild): 3026 // foo(inout(const(U))) immutable(T) => T 3027 // foo(shared(const(U))) shared(inout(const(T))) => T 3028 // foo(shared(inout(const(U)))) immutable(T) => T 3029 // foo(shared(inout(const(U)))) shared(inout(T)) => T 3030 { 3031 *at = t->unSharedOf()->mutableOf(); 3032 return MATCHconst; 3033 } 3034 3035 case X(MODshared | MODconst, MODshared | MODwild): 3036 // foo(shared(const(U))) shared(inout(T)) => T 3037 { 3038 *at = t->unSharedOf()->mutableOf(); 3039 return MATCHconst; 3040 } 3041 3042 case X(MODwild, 0): 3043 case X(MODwild, MODconst): 3044 case X(MODwild, MODwildconst): 3045 case X(MODwild, MODimmutable): 3046 case X(MODwild, MODshared): 3047 case X(MODwild, MODshared | MODconst): 3048 case X(MODwild, MODshared | MODwildconst): 3049 case X(MODwildconst, 0): 3050 case X(MODwildconst, MODconst): 3051 case X(MODwildconst, MODwild): 3052 case X(MODwildconst, MODshared): 3053 case X(MODwildconst, MODshared | MODconst): 3054 case X(MODwildconst, MODshared | MODwild): 3055 case X(MODshared, 0): 3056 case X(MODshared, MODconst): 3057 case X(MODshared, MODwild): 3058 case X(MODshared, MODwildconst): 3059 case X(MODshared, MODimmutable): 3060 case X(MODshared | MODconst, 0): 3061 case X(MODshared | MODconst, MODconst): 3062 case X(MODshared | MODconst, MODwild): 3063 case X(MODshared | MODconst, MODwildconst): 3064 case X(MODshared | MODwild, 0): 3065 case X(MODshared | MODwild, MODconst): 3066 case X(MODshared | MODwild, MODwild): 3067 case X(MODshared | MODwild, MODwildconst): 3068 case X(MODshared | MODwild, MODimmutable): 3069 case X(MODshared | MODwild, MODshared): 3070 case X(MODshared | MODwild, MODshared | MODconst): 3071 case X(MODshared | MODwild, MODshared | MODwildconst): 3072 case X(MODshared | MODwildconst, 0): 3073 case X(MODshared | MODwildconst, MODconst): 3074 case X(MODshared | MODwildconst, MODwild): 3075 case X(MODshared | MODwildconst, MODwildconst): 3076 case X(MODshared | MODwildconst, MODshared): 3077 case X(MODshared | MODwildconst, MODshared | MODconst): 3078 case X(MODimmutable, 0): 3079 case X(MODimmutable, MODconst): 3080 case X(MODimmutable, MODwild): 3081 case X(MODimmutable, MODwildconst): 3082 case X(MODimmutable, MODshared): 3083 case X(MODimmutable, MODshared | MODconst): 3084 case X(MODimmutable, MODshared | MODwild): 3085 case X(MODimmutable, MODshared | MODwildconst): 3086 // foo(inout(U)) T => nomatch 3087 // foo(inout(U)) const(T) => nomatch 3088 // foo(inout(U)) inout(const(T)) => nomatch 3089 // foo(inout(U)) immutable(T) => nomatch 3090 // foo(inout(U)) shared(T) => nomatch 3091 // foo(inout(U)) shared(const(T)) => nomatch 3092 // foo(inout(U)) shared(inout(const(T))) => nomatch 3093 // foo(inout(const(U))) T => nomatch 3094 // foo(inout(const(U))) const(T) => nomatch 3095 // foo(inout(const(U))) inout(T) => nomatch 3096 // foo(inout(const(U))) shared(T) => nomatch 3097 // foo(inout(const(U))) shared(const(T)) => nomatch 3098 // foo(inout(const(U))) shared(inout(T)) => nomatch 3099 // foo(shared(U)) T => nomatch 3100 // foo(shared(U)) const(T) => nomatch 3101 // foo(shared(U)) inout(T) => nomatch 3102 // foo(shared(U)) inout(const(T)) => nomatch 3103 // foo(shared(U)) immutable(T) => nomatch 3104 // foo(shared(const(U))) T => nomatch 3105 // foo(shared(const(U))) const(T) => nomatch 3106 // foo(shared(const(U))) inout(T) => nomatch 3107 // foo(shared(const(U))) inout(const(T)) => nomatch 3108 // foo(shared(inout(U))) T => nomatch 3109 // foo(shared(inout(U))) const(T) => nomatch 3110 // foo(shared(inout(U))) inout(T) => nomatch 3111 // foo(shared(inout(U))) inout(const(T)) => nomatch 3112 // foo(shared(inout(U))) immutable(T) => nomatch 3113 // foo(shared(inout(U))) shared(T) => nomatch 3114 // foo(shared(inout(U))) shared(const(T)) => nomatch 3115 // foo(shared(inout(U))) shared(inout(const(T))) => nomatch 3116 // foo(shared(inout(const(U)))) T => nomatch 3117 // foo(shared(inout(const(U)))) const(T) => nomatch 3118 // foo(shared(inout(const(U)))) inout(T) => nomatch 3119 // foo(shared(inout(const(U)))) inout(const(T)) => nomatch 3120 // foo(shared(inout(const(U)))) shared(T) => nomatch 3121 // foo(shared(inout(const(U)))) shared(const(T)) => nomatch 3122 // foo(immutable(U)) T => nomatch 3123 // foo(immutable(U)) const(T) => nomatch 3124 // foo(immutable(U)) inout(T) => nomatch 3125 // foo(immutable(U)) inout(const(T)) => nomatch 3126 // foo(immutable(U)) shared(T) => nomatch 3127 // foo(immutable(U)) shared(const(T)) => nomatch 3128 // foo(immutable(U)) shared(inout(T)) => nomatch 3129 // foo(immutable(U)) shared(inout(const(T))) => nomatch 3130 return MATCHnomatch; 3131 3132 default: 3133 assert(0); 3134 return MATCHnomatch; // silence compiler warning about missing return 3135 } 3136 #undef X 3137 } 3138 3139 /* These form the heart of template argument deduction. 3140 * Given 'this' being the type argument to the template instance, 3141 * it is matched against the template declaration parameter specialization 3142 * 'tparam' to determine the type to be used for the parameter. 3143 * Example: 3144 * template Foo(T:T*) // template declaration 3145 * Foo!(int*) // template instantiation 3146 * Input: 3147 * this = int* 3148 * tparam = T* 3149 * parameters = [ T:T* ] // Array of TemplateParameter's 3150 * Output: 3151 * dedtypes = [ int ] // Array of Expression/Type's 3152 */ 3153 MATCH deduceType(RootObject *o, Scope *sc, Type *tparam, TemplateParameters *parameters, 3154 Objects *dedtypes, unsigned *wm, size_t inferStart) 3155 { 3156 class DeduceType : public Visitor 3157 { 3158 public: 3159 Scope *sc; 3160 Type *tparam; 3161 TemplateParameters *parameters; 3162 Objects *dedtypes; 3163 unsigned *wm; 3164 size_t inferStart; 3165 MATCH result; 3166 3167 DeduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm, size_t inferStart) 3168 : sc(sc), tparam(tparam), parameters(parameters), dedtypes(dedtypes), wm(wm), inferStart(inferStart) 3169 { 3170 result = MATCHnomatch; 3171 } 3172 3173 void visit(Type *t) 3174 { 3175 if (!tparam) 3176 goto Lnomatch; 3177 3178 if (t == tparam) 3179 goto Lexact; 3180 3181 if (tparam->ty == Tident) 3182 { 3183 // Determine which parameter tparam is 3184 size_t i = templateParameterLookup(tparam, parameters); 3185 if (i == IDX_NOTFOUND) 3186 { 3187 if (!sc) 3188 goto Lnomatch; 3189 3190 /* Need a loc to go with the semantic routine. 3191 */ 3192 Loc loc; 3193 if (parameters->dim) 3194 { 3195 TemplateParameter *tp = (*parameters)[0]; 3196 loc = tp->loc; 3197 } 3198 3199 /* BUG: what if tparam is a template instance, that 3200 * has as an argument another Tident? 3201 */ 3202 tparam = tparam->semantic(loc, sc); 3203 assert(tparam->ty != Tident); 3204 result = deduceType(t, sc, tparam, parameters, dedtypes, wm); 3205 return; 3206 } 3207 3208 TemplateParameter *tp = (*parameters)[i]; 3209 3210 TypeIdentifier *tident = (TypeIdentifier *)tparam; 3211 if (tident->idents.dim > 0) 3212 { 3213 //printf("matching %s to %s\n", tparam->toChars(), t->toChars()); 3214 Dsymbol *s = t->toDsymbol(sc); 3215 for (size_t j = tident->idents.dim; j-- > 0; ) 3216 { 3217 RootObject *id = tident->idents[j]; 3218 if (id->dyncast() == DYNCAST_IDENTIFIER) 3219 { 3220 if (!s || !s->parent) 3221 goto Lnomatch; 3222 Dsymbol *s2 = s->parent->search(Loc(), (Identifier *)id); 3223 if (!s2) 3224 goto Lnomatch; 3225 s2 = s2->toAlias(); 3226 //printf("[%d] s = %s %s, s2 = %s %s\n", j, s->kind(), s->toChars(), s2->kind(), s2->toChars()); 3227 if (s != s2) 3228 { 3229 if (Type *tx = s2->getType()) 3230 { 3231 if (s != tx->toDsymbol(sc)) 3232 goto Lnomatch; 3233 } 3234 else 3235 goto Lnomatch; 3236 } 3237 s = s->parent; 3238 } 3239 else 3240 goto Lnomatch; 3241 } 3242 //printf("[e] s = %s\n", s?s->toChars():"(null)"); 3243 if (tp->isTemplateTypeParameter()) 3244 { 3245 Type *tt = s->getType(); 3246 if (!tt) 3247 goto Lnomatch; 3248 Type *at = (Type *)(*dedtypes)[i]; 3249 if (at && at->ty == Tnone) 3250 at = ((TypeDeduced *)at)->tded; 3251 if (!at || tt->equals(at)) 3252 { 3253 (*dedtypes)[i] = tt; 3254 goto Lexact; 3255 } 3256 } 3257 if (tp->isTemplateAliasParameter()) 3258 { 3259 Dsymbol *s2 = (Dsymbol *)(*dedtypes)[i]; 3260 if (!s2 || s == s2) 3261 { 3262 (*dedtypes)[i] = s; 3263 goto Lexact; 3264 } 3265 } 3266 goto Lnomatch; 3267 } 3268 3269 // Found the corresponding parameter tp 3270 if (!tp->isTemplateTypeParameter()) 3271 goto Lnomatch; 3272 3273 Type *at = (Type *)(*dedtypes)[i]; 3274 Type *tt; 3275 if (unsigned char wx = wm ? deduceWildHelper(t, &tt, tparam) : 0) 3276 { 3277 // type vs (none) 3278 if (!at) 3279 { 3280 (*dedtypes)[i] = tt; 3281 *wm |= wx; 3282 result = MATCHconst; 3283 return; 3284 } 3285 3286 // type vs expressions 3287 if (at->ty == Tnone) 3288 { 3289 TypeDeduced *xt = (TypeDeduced *)at; 3290 result = xt->matchAll(tt); 3291 if (result > MATCHnomatch) 3292 { 3293 (*dedtypes)[i] = tt; 3294 if (result > MATCHconst) 3295 result = MATCHconst; // limit level for inout matches 3296 delete xt; 3297 } 3298 return; 3299 } 3300 3301 // type vs type 3302 if (tt->equals(at)) 3303 { 3304 (*dedtypes)[i] = tt; // Prefer current type match 3305 goto Lconst; 3306 } 3307 if (tt->implicitConvTo(at->constOf())) 3308 { 3309 (*dedtypes)[i] = at->constOf()->mutableOf(); 3310 *wm |= MODconst; 3311 goto Lconst; 3312 } 3313 if (at->implicitConvTo(tt->constOf())) 3314 { 3315 (*dedtypes)[i] = tt->constOf()->mutableOf(); 3316 *wm |= MODconst; 3317 goto Lconst; 3318 } 3319 goto Lnomatch; 3320 } 3321 else if (MATCH m = deduceTypeHelper(t, &tt, tparam)) 3322 { 3323 // type vs (none) 3324 if (!at) 3325 { 3326 (*dedtypes)[i] = tt; 3327 result = m; 3328 return; 3329 } 3330 3331 // type vs expressions 3332 if (at->ty == Tnone) 3333 { 3334 TypeDeduced *xt = (TypeDeduced *)at; 3335 result = xt->matchAll(tt); 3336 if (result > MATCHnomatch) 3337 { 3338 (*dedtypes)[i] = tt; 3339 delete xt; 3340 } 3341 return; 3342 } 3343 3344 // type vs type 3345 if (tt->equals(at)) 3346 { 3347 goto Lexact; 3348 } 3349 if (tt->ty == Tclass && at->ty == Tclass) 3350 { 3351 result = tt->implicitConvTo(at); 3352 return; 3353 } 3354 if (tt->ty == Tsarray && at->ty == Tarray && 3355 tt->nextOf()->implicitConvTo(at->nextOf()) >= MATCHconst) 3356 { 3357 goto Lexact; 3358 } 3359 } 3360 goto Lnomatch; 3361 } 3362 3363 if (tparam->ty == Ttypeof) 3364 { 3365 /* Need a loc to go with the semantic routine. 3366 */ 3367 Loc loc; 3368 if (parameters->dim) 3369 { 3370 TemplateParameter *tp = (*parameters)[0]; 3371 loc = tp->loc; 3372 } 3373 3374 tparam = tparam->semantic(loc, sc); 3375 } 3376 if (t->ty != tparam->ty) 3377 { 3378 if (Dsymbol *sym = t->toDsymbol(sc)) 3379 { 3380 if (sym->isforwardRef() && !tparam->deco) 3381 goto Lnomatch; 3382 } 3383 3384 MATCH m = t->implicitConvTo(tparam); 3385 if (m == MATCHnomatch) 3386 { 3387 if (t->ty == Tclass) 3388 { 3389 TypeClass *tc = (TypeClass *)t; 3390 if (tc->sym->aliasthis && !(tc->att & RECtracingDT)) 3391 { 3392 tc->att = (AliasThisRec)(tc->att | RECtracingDT); 3393 m = deduceType(t->aliasthisOf(), sc, tparam, parameters, dedtypes, wm); 3394 tc->att = (AliasThisRec)(tc->att & ~RECtracingDT); 3395 } 3396 } 3397 else if (t->ty == Tstruct) 3398 { 3399 TypeStruct *ts = (TypeStruct *)t; 3400 if (ts->sym->aliasthis && !(ts->att & RECtracingDT)) 3401 { 3402 ts->att = (AliasThisRec)(ts->att | RECtracingDT); 3403 m = deduceType(t->aliasthisOf(), sc, tparam, parameters, dedtypes, wm); 3404 ts->att = (AliasThisRec)(ts->att & ~RECtracingDT); 3405 } 3406 } 3407 } 3408 result = m; 3409 return; 3410 } 3411 3412 if (t->nextOf()) 3413 { 3414 if (tparam->deco && !tparam->hasWild()) 3415 { 3416 result = t->implicitConvTo(tparam); 3417 return; 3418 } 3419 3420 Type *tpn = tparam->nextOf(); 3421 if (wm && t->ty == Taarray && tparam->isWild()) 3422 { 3423 // Bugzilla 12403: In IFTI, stop inout matching on transitive part of AA types. 3424 tpn = tpn->substWildTo(MODmutable); 3425 } 3426 3427 result = deduceType(t->nextOf(), sc, tpn, parameters, dedtypes, wm); 3428 return; 3429 } 3430 3431 Lexact: 3432 result = MATCHexact; 3433 return; 3434 3435 Lnomatch: 3436 result = MATCHnomatch; 3437 return; 3438 3439 Lconst: 3440 result = MATCHconst; 3441 } 3442 3443 void visit(TypeVector *t) 3444 { 3445 if (tparam->ty == Tvector) 3446 { 3447 TypeVector *tp = (TypeVector *)tparam; 3448 result = deduceType(t->basetype, sc, tp->basetype, parameters, dedtypes, wm); 3449 return; 3450 } 3451 visit((Type *)t); 3452 } 3453 3454 void visit(TypeDArray *t) 3455 { 3456 visit((Type *)t); 3457 } 3458 3459 void visit(TypeSArray *t) 3460 { 3461 // Extra check that array dimensions must match 3462 if (tparam) 3463 { 3464 if (tparam->ty == Tarray) 3465 { 3466 MATCH m = deduceType(t->next, sc, tparam->nextOf(), parameters, dedtypes, wm); 3467 result = (m >= MATCHconst) ? MATCHconvert : MATCHnomatch; 3468 return; 3469 } 3470 3471 TemplateParameter *tp = NULL; 3472 Expression *edim = NULL; 3473 size_t i; 3474 if (tparam->ty == Tsarray) 3475 { 3476 TypeSArray *tsa = (TypeSArray *)tparam; 3477 if (tsa->dim->op == TOKvar && 3478 ((VarExp *)tsa->dim)->var->storage_class & STCtemplateparameter) 3479 { 3480 Identifier *id = ((VarExp *)tsa->dim)->var->ident; 3481 i = templateIdentifierLookup(id, parameters); 3482 assert(i != IDX_NOTFOUND); 3483 tp = (*parameters)[i]; 3484 } 3485 else 3486 edim = tsa->dim; 3487 } 3488 else if (tparam->ty == Taarray) 3489 { 3490 TypeAArray *taa = (TypeAArray *)tparam; 3491 i = templateParameterLookup(taa->index, parameters); 3492 if (i != IDX_NOTFOUND) 3493 tp = (*parameters)[i]; 3494 else 3495 { 3496 Expression *e; 3497 Type *tx; 3498 Dsymbol *s; 3499 taa->index->resolve(Loc(), sc, &e, &tx, &s); 3500 edim = s ? getValue(s) : getValue(e); 3501 } 3502 } 3503 if ((tp && tp->matchArg(sc, t->dim, i, parameters, dedtypes, NULL)) || 3504 (edim && edim->toInteger() == t->dim->toInteger())) 3505 { 3506 result = deduceType(t->next, sc, tparam->nextOf(), parameters, dedtypes, wm); 3507 return; 3508 } 3509 } 3510 visit((Type *)t); 3511 return; 3512 3513 result = MATCHnomatch; 3514 } 3515 3516 void visit(TypeAArray *t) 3517 { 3518 // Extra check that index type must match 3519 if (tparam && tparam->ty == Taarray) 3520 { 3521 TypeAArray *tp = (TypeAArray *)tparam; 3522 if (!deduceType(t->index, sc, tp->index, parameters, dedtypes)) 3523 { 3524 result = MATCHnomatch; 3525 return; 3526 } 3527 } 3528 visit((Type *)t); 3529 } 3530 3531 void visit(TypeFunction *t) 3532 { 3533 //printf("TypeFunction::deduceType()\n"); 3534 //printf("\tthis = %d, ", t->ty); t->print(); 3535 //printf("\ttparam = %d, ", tparam->ty); tparam->print(); 3536 3537 // Extra check that function characteristics must match 3538 if (tparam && tparam->ty == Tfunction) 3539 { 3540 TypeFunction *tp = (TypeFunction *)tparam; 3541 if (t->varargs != tp->varargs || 3542 t->linkage != tp->linkage) 3543 { 3544 result = MATCHnomatch; 3545 return; 3546 } 3547 3548 size_t nfargs = Parameter::dim(t->parameters); 3549 size_t nfparams = Parameter::dim(tp->parameters); 3550 3551 // bug 2579 fix: Apply function parameter storage classes to parameter types 3552 for (size_t i = 0; i < nfparams; i++) 3553 { 3554 Parameter *fparam = Parameter::getNth(tp->parameters, i); 3555 fparam->type = fparam->type->addStorageClass(fparam->storageClass); 3556 fparam->storageClass &= ~(STC_TYPECTOR | STCin); 3557 } 3558 //printf("\t-> this = %d, ", t->ty); t->print(); 3559 //printf("\t-> tparam = %d, ", tparam->ty); tparam->print(); 3560 3561 /* See if tuple match 3562 */ 3563 if (nfparams > 0 && nfargs >= nfparams - 1) 3564 { 3565 /* See if 'A' of the template parameter matches 'A' 3566 * of the type of the last function parameter. 3567 */ 3568 Parameter *fparam = Parameter::getNth(tp->parameters, nfparams - 1); 3569 assert(fparam); 3570 assert(fparam->type); 3571 if (fparam->type->ty != Tident) 3572 goto L1; 3573 TypeIdentifier *tid = (TypeIdentifier *)fparam->type; 3574 if (tid->idents.dim) 3575 goto L1; 3576 3577 /* Look through parameters to find tuple matching tid->ident 3578 */ 3579 size_t tupi = 0; 3580 for (; 1; tupi++) 3581 { 3582 if (tupi == parameters->dim) 3583 goto L1; 3584 TemplateParameter *tx = (*parameters)[tupi]; 3585 TemplateTupleParameter *tup = tx->isTemplateTupleParameter(); 3586 if (tup && tup->ident->equals(tid->ident)) 3587 break; 3588 } 3589 3590 /* The types of the function arguments [nfparams - 1 .. nfargs] 3591 * now form the tuple argument. 3592 */ 3593 size_t tuple_dim = nfargs - (nfparams - 1); 3594 3595 /* See if existing tuple, and whether it matches or not 3596 */ 3597 RootObject *o = (*dedtypes)[tupi]; 3598 if (o) 3599 { 3600 // Existing deduced argument must be a tuple, and must match 3601 Tuple *tup = isTuple(o); 3602 if (!tup || tup->objects.dim != tuple_dim) 3603 { 3604 result = MATCHnomatch; 3605 return; 3606 } 3607 for (size_t i = 0; i < tuple_dim; i++) 3608 { 3609 Parameter *arg = Parameter::getNth(t->parameters, nfparams - 1 + i); 3610 if (!arg->type->equals(tup->objects[i])) 3611 { 3612 result = MATCHnomatch; 3613 return; 3614 } 3615 } 3616 } 3617 else 3618 { 3619 // Create new tuple 3620 Tuple *tup = new Tuple(); 3621 tup->objects.setDim(tuple_dim); 3622 for (size_t i = 0; i < tuple_dim; i++) 3623 { 3624 Parameter *arg = Parameter::getNth(t->parameters, nfparams - 1 + i); 3625 tup->objects[i] = arg->type; 3626 } 3627 (*dedtypes)[tupi] = tup; 3628 } 3629 nfparams--; // don't consider the last parameter for type deduction 3630 goto L2; 3631 } 3632 3633 L1: 3634 if (nfargs != nfparams) 3635 { 3636 result = MATCHnomatch; 3637 return; 3638 } 3639 L2: 3640 for (size_t i = 0; i < nfparams; i++) 3641 { 3642 Parameter *a = Parameter::getNth(t->parameters, i); 3643 Parameter *ap = Parameter::getNth(tp->parameters, i); 3644 3645 if (!a->isCovariant(t->isref, ap) || 3646 !deduceType(a->type, sc, ap->type, parameters, dedtypes)) 3647 { 3648 result = MATCHnomatch; 3649 return; 3650 } 3651 } 3652 } 3653 visit((Type *)t); 3654 } 3655 3656 void visit(TypeIdentifier *t) 3657 { 3658 // Extra check 3659 if (tparam && tparam->ty == Tident) 3660 { 3661 TypeIdentifier *tp = (TypeIdentifier *)tparam; 3662 3663 for (size_t i = 0; i < t->idents.dim; i++) 3664 { 3665 RootObject *id1 = t->idents[i]; 3666 RootObject *id2 = tp->idents[i]; 3667 3668 if (!id1->equals(id2)) 3669 { 3670 result = MATCHnomatch; 3671 return; 3672 } 3673 } 3674 } 3675 visit((Type *)t); 3676 } 3677 3678 void visit(TypeInstance *t) 3679 { 3680 // Extra check 3681 if (tparam && tparam->ty == Tinstance && t->tempinst->tempdecl) 3682 { 3683 TemplateDeclaration *tempdecl = t->tempinst->tempdecl->isTemplateDeclaration(); 3684 assert(tempdecl); 3685 3686 TypeInstance *tp = (TypeInstance *)tparam; 3687 3688 //printf("tempinst->tempdecl = %p\n", tempdecl); 3689 //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl); 3690 if (!tp->tempinst->tempdecl) 3691 { 3692 //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars()); 3693 3694 /* Handle case of: 3695 * template Foo(T : sa!(T), alias sa) 3696 */ 3697 size_t i = templateIdentifierLookup(tp->tempinst->name, parameters); 3698 if (i == IDX_NOTFOUND) 3699 { 3700 /* Didn't find it as a parameter identifier. Try looking 3701 * it up and seeing if is an alias. See Bugzilla 1454 3702 */ 3703 TypeIdentifier *tid = new TypeIdentifier(tp->loc, tp->tempinst->name); 3704 Type *tx; 3705 Expression *e; 3706 Dsymbol *s; 3707 tid->resolve(tp->loc, sc, &e, &tx, &s); 3708 if (tx) 3709 { 3710 s = tx->toDsymbol(sc); 3711 if (TemplateInstance *ti = s ? s->parent->isTemplateInstance() : NULL) 3712 { 3713 // Bugzilla 14290: Try to match with ti->tempecl, 3714 // only when ti is an enclosing instance. 3715 Dsymbol *p = sc->parent; 3716 while (p && p != ti) 3717 p = p->parent; 3718 if (p) 3719 s = ti->tempdecl; 3720 } 3721 } 3722 if (s) 3723 { 3724 s = s->toAlias(); 3725 TemplateDeclaration *td = s->isTemplateDeclaration(); 3726 if (td) 3727 { 3728 if (td->overroot) 3729 td = td->overroot; 3730 for (; td; td = td->overnext) 3731 { 3732 if (td == tempdecl) 3733 goto L2; 3734 } 3735 } 3736 } 3737 goto Lnomatch; 3738 } 3739 TemplateParameter *tpx = (*parameters)[i]; 3740 if (!tpx->matchArg(sc, tempdecl, i, parameters, dedtypes, NULL)) 3741 goto Lnomatch; 3742 } 3743 else if (tempdecl != tp->tempinst->tempdecl) 3744 goto Lnomatch; 3745 3746 L2: 3747 3748 for (size_t i = 0; 1; i++) 3749 { 3750 //printf("\ttest: tempinst->tiargs[%d]\n", i); 3751 RootObject *o1 = NULL; 3752 if (i < t->tempinst->tiargs->dim) 3753 o1 = (*t->tempinst->tiargs)[i]; 3754 else if (i < t->tempinst->tdtypes.dim && i < tp->tempinst->tiargs->dim) 3755 { 3756 // Pick up default arg 3757 o1 = t->tempinst->tdtypes[i]; 3758 } 3759 else if (i >= tp->tempinst->tiargs->dim) 3760 break; 3761 3762 if (i >= tp->tempinst->tiargs->dim) 3763 { 3764 size_t dim = tempdecl->parameters->dim - (tempdecl->isVariadic() ? 1 : 0); 3765 while (i < dim && ((*tempdecl->parameters)[i]->dependent || 3766 (*tempdecl->parameters)[i]->hasDefaultArg())) 3767 { 3768 i++; 3769 } 3770 if (i >= dim) 3771 break; // match if all remained parameters are dependent 3772 goto Lnomatch; 3773 } 3774 3775 RootObject *o2 = (*tp->tempinst->tiargs)[i]; 3776 Type *t2 = isType(o2); 3777 3778 size_t j = (t2 && t2->ty == Tident && i == tp->tempinst->tiargs->dim - 1) 3779 ? templateParameterLookup(t2, parameters) : IDX_NOTFOUND; 3780 if (j != IDX_NOTFOUND && j == parameters->dim - 1 && 3781 (*parameters)[j]->isTemplateTupleParameter()) 3782 { 3783 /* Given: 3784 * struct A(B...) {} 3785 * alias A!(int, float) X; 3786 * static if (is(X Y == A!(Z), Z...)) {} 3787 * deduce that Z is a tuple(int, float) 3788 */ 3789 3790 /* Create tuple from remaining args 3791 */ 3792 Tuple *vt = new Tuple(); 3793 size_t vtdim = (tempdecl->isVariadic() 3794 ? t->tempinst->tiargs->dim : t->tempinst->tdtypes.dim) - i; 3795 vt->objects.setDim(vtdim); 3796 for (size_t k = 0; k < vtdim; k++) 3797 { 3798 RootObject *o; 3799 if (k < t->tempinst->tiargs->dim) 3800 o = (*t->tempinst->tiargs)[i + k]; 3801 else // Pick up default arg 3802 o = t->tempinst->tdtypes[i + k]; 3803 vt->objects[k] = o; 3804 } 3805 3806 Tuple *v = (Tuple *)(*dedtypes)[j]; 3807 if (v) 3808 { 3809 if (!match(v, vt)) 3810 goto Lnomatch; 3811 } 3812 else 3813 (*dedtypes)[j] = vt; 3814 break; 3815 } 3816 else if (!o1) 3817 break; 3818 3819 Type *t1 = isType(o1); 3820 Dsymbol *s1 = isDsymbol(o1); 3821 Dsymbol *s2 = isDsymbol(o2); 3822 Expression *e1 = s1 ? getValue(s1) : getValue(isExpression(o1)); 3823 Expression *e2 = isExpression(o2); 3824 3825 if (t1 && t2) 3826 { 3827 if (!deduceType(t1, sc, t2, parameters, dedtypes)) 3828 goto Lnomatch; 3829 } 3830 else if (e1 && e2) 3831 { 3832 Le: 3833 e1 = e1->ctfeInterpret(); 3834 3835 /* If it is one of the template parameters for this template, 3836 * we should not attempt to interpret it. It already has a value. 3837 */ 3838 if (e2->op == TOKvar && 3839 (((VarExp *)e2)->var->storage_class & STCtemplateparameter)) 3840 { 3841 /* 3842 * (T:Number!(e2), int e2) 3843 */ 3844 j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters); 3845 if (j != IDX_NOTFOUND) 3846 goto L1; 3847 // The template parameter was not from this template 3848 // (it may be from a parent template, for example) 3849 } 3850 3851 e2 = ::semantic(e2, sc); // Bugzilla 13417 3852 e2 = e2->ctfeInterpret(); 3853 3854 //printf("e1 = %s, type = %s %d\n", e1->toChars(), e1->type->toChars(), e1->type->ty); 3855 //printf("e2 = %s, type = %s %d\n", e2->toChars(), e2->type->toChars(), e2->type->ty); 3856 if (!e1->equals(e2)) 3857 { 3858 if (!e2->implicitConvTo(e1->type)) 3859 goto Lnomatch; 3860 3861 e2 = e2->implicitCastTo(sc, e1->type); 3862 e2 = e2->ctfeInterpret(); 3863 if (!e1->equals(e2)) 3864 goto Lnomatch; 3865 } 3866 } 3867 else if (e1 && t2 && t2->ty == Tident) 3868 { 3869 j = templateParameterLookup(t2, parameters); 3870 L1: 3871 if (j == IDX_NOTFOUND) 3872 { 3873 t2->resolve(((TypeIdentifier *)t2)->loc, sc, &e2, &t2, &s2); 3874 if (e2) 3875 goto Le; 3876 goto Lnomatch; 3877 } 3878 if (!(*parameters)[j]->matchArg(sc, e1, j, parameters, dedtypes, NULL)) 3879 goto Lnomatch; 3880 } 3881 else if (s1 && s2) 3882 { 3883 Ls: 3884 if (!s1->equals(s2)) 3885 goto Lnomatch; 3886 } 3887 else if (s1 && t2 && t2->ty == Tident) 3888 { 3889 j = templateParameterLookup(t2, parameters); 3890 if (j == IDX_NOTFOUND) 3891 { 3892 t2->resolve(((TypeIdentifier *)t2)->loc, sc, &e2, &t2, &s2); 3893 if (s2) 3894 goto Ls; 3895 goto Lnomatch; 3896 } 3897 if (!(*parameters)[j]->matchArg(sc, s1, j, parameters, dedtypes, NULL)) 3898 goto Lnomatch; 3899 } 3900 else 3901 goto Lnomatch; 3902 } 3903 } 3904 visit((Type *)t); 3905 return; 3906 3907 Lnomatch: 3908 //printf("no match\n"); 3909 result = MATCHnomatch; 3910 } 3911 3912 void visit(TypeStruct *t) 3913 { 3914 /* If this struct is a template struct, and we're matching 3915 * it against a template instance, convert the struct type 3916 * to a template instance, too, and try again. 3917 */ 3918 TemplateInstance *ti = t->sym->parent->isTemplateInstance(); 3919 3920 if (tparam && tparam->ty == Tinstance) 3921 { 3922 if (ti && ti->toAlias() == t->sym) 3923 { 3924 TypeInstance *tx = new TypeInstance(Loc(), ti); 3925 result = deduceType(tx, sc, tparam, parameters, dedtypes, wm); 3926 return; 3927 } 3928 3929 /* Match things like: 3930 * S!(T).foo 3931 */ 3932 TypeInstance *tpi = (TypeInstance *)tparam; 3933 if (tpi->idents.dim) 3934 { 3935 RootObject *id = tpi->idents[tpi->idents.dim - 1]; 3936 if (id->dyncast() == DYNCAST_IDENTIFIER && t->sym->ident->equals((Identifier *)id)) 3937 { 3938 Type *tparent = t->sym->parent->getType(); 3939 if (tparent) 3940 { 3941 /* Slice off the .foo in S!(T).foo 3942 */ 3943 tpi->idents.dim--; 3944 result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm); 3945 tpi->idents.dim++; 3946 return; 3947 } 3948 } 3949 } 3950 } 3951 3952 // Extra check 3953 if (tparam && tparam->ty == Tstruct) 3954 { 3955 TypeStruct *tp = (TypeStruct *)tparam; 3956 3957 //printf("\t%d\n", (MATCH) t->implicitConvTo(tp)); 3958 if (wm && t->deduceWild(tparam, false)) 3959 { 3960 result = MATCHconst; 3961 return; 3962 } 3963 result = t->implicitConvTo(tp); 3964 return; 3965 } 3966 visit((Type *)t); 3967 } 3968 3969 void visit(TypeEnum *t) 3970 { 3971 // Extra check 3972 if (tparam && tparam->ty == Tenum) 3973 { 3974 TypeEnum *tp = (TypeEnum *)tparam; 3975 if (t->sym == tp->sym) 3976 visit((Type *)t); 3977 else 3978 result = MATCHnomatch; 3979 return; 3980 } 3981 Type *tb = t->toBasetype(); 3982 if (tb->ty == tparam->ty || 3983 (tb->ty == Tsarray && tparam->ty == Taarray)) 3984 { 3985 result = deduceType(tb, sc, tparam, parameters, dedtypes, wm); 3986 return; 3987 } 3988 visit((Type *)t); 3989 } 3990 3991 /* Helper for TypeClass::deduceType(). 3992 * Classes can match with implicit conversion to a base class or interface. 3993 * This is complicated, because there may be more than one base class which 3994 * matches. In such cases, one or more parameters remain ambiguous. 3995 * For example, 3996 * 3997 * interface I(X, Y) {} 3998 * class C : I(uint, double), I(char, double) {} 3999 * C x; 4000 * foo(T, U)( I!(T, U) x) 4001 * 4002 * deduces that U is double, but T remains ambiguous (could be char or uint). 4003 * 4004 * Given a baseclass b, and initial deduced types 'dedtypes', this function 4005 * tries to match tparam with b, and also tries all base interfaces of b. 4006 * If a match occurs, numBaseClassMatches is incremented, and the new deduced 4007 * types are ANDed with the current 'best' estimate for dedtypes. 4008 */ 4009 static void deduceBaseClassParameters(BaseClass *b, 4010 Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, 4011 Objects *best, int &numBaseClassMatches) 4012 { 4013 TemplateInstance *parti = b->sym ? b->sym->parent->isTemplateInstance() : NULL; 4014 if (parti) 4015 { 4016 // Make a temporary copy of dedtypes so we don't destroy it 4017 Objects *tmpdedtypes = new Objects(); 4018 tmpdedtypes->setDim(dedtypes->dim); 4019 memcpy(tmpdedtypes->tdata(), dedtypes->tdata(), dedtypes->dim * sizeof(void *)); 4020 4021 TypeInstance *t = new TypeInstance(Loc(), parti); 4022 MATCH m = deduceType(t, sc, tparam, parameters, tmpdedtypes); 4023 if (m > MATCHnomatch) 4024 { 4025 // If this is the first ever match, it becomes our best estimate 4026 if (numBaseClassMatches==0) 4027 memcpy(best->tdata(), tmpdedtypes->tdata(), tmpdedtypes->dim * sizeof(void *)); 4028 else for (size_t k = 0; k < tmpdedtypes->dim; ++k) 4029 { 4030 // If we've found more than one possible type for a parameter, 4031 // mark it as unknown. 4032 if ((*tmpdedtypes)[k] != (*best)[k]) 4033 (*best)[k] = (*dedtypes)[k]; 4034 } 4035 ++numBaseClassMatches; 4036 } 4037 } 4038 // Now recursively test the inherited interfaces 4039 for (size_t j = 0; j < b->baseInterfaces.length; ++j) 4040 { 4041 BaseClass *bi = &b->baseInterfaces.ptr[j]; 4042 deduceBaseClassParameters(bi, 4043 sc, tparam, parameters, dedtypes, 4044 best, numBaseClassMatches); 4045 } 4046 4047 } 4048 4049 void visit(TypeClass *t) 4050 { 4051 //printf("TypeClass::deduceType(this = %s)\n", t->toChars()); 4052 4053 /* If this class is a template class, and we're matching 4054 * it against a template instance, convert the class type 4055 * to a template instance, too, and try again. 4056 */ 4057 TemplateInstance *ti = t->sym->parent->isTemplateInstance(); 4058 4059 if (tparam && tparam->ty == Tinstance) 4060 { 4061 if (ti && ti->toAlias() == t->sym) 4062 { 4063 TypeInstance *tx = new TypeInstance(Loc(), ti); 4064 MATCH m = deduceType(tx, sc, tparam, parameters, dedtypes, wm); 4065 // Even if the match fails, there is still a chance it could match 4066 // a base class. 4067 if (m != MATCHnomatch) 4068 { 4069 result = m; 4070 return; 4071 } 4072 } 4073 4074 /* Match things like: 4075 * S!(T).foo 4076 */ 4077 TypeInstance *tpi = (TypeInstance *)tparam; 4078 if (tpi->idents.dim) 4079 { 4080 RootObject *id = tpi->idents[tpi->idents.dim - 1]; 4081 if (id->dyncast() == DYNCAST_IDENTIFIER && t->sym->ident->equals((Identifier *)id)) 4082 { 4083 Type *tparent = t->sym->parent->getType(); 4084 if (tparent) 4085 { 4086 /* Slice off the .foo in S!(T).foo 4087 */ 4088 tpi->idents.dim--; 4089 result = deduceType(tparent, sc, tpi, parameters, dedtypes, wm); 4090 tpi->idents.dim++; 4091 return; 4092 } 4093 } 4094 } 4095 4096 // If it matches exactly or via implicit conversion, we're done 4097 visit((Type *)t); 4098 if (result != MATCHnomatch) 4099 return; 4100 4101 /* There is still a chance to match via implicit conversion to 4102 * a base class or interface. Because there could be more than one such 4103 * match, we need to check them all. 4104 */ 4105 4106 int numBaseClassMatches = 0; // Have we found an interface match? 4107 4108 // Our best guess at dedtypes 4109 Objects *best = new Objects(); 4110 best->setDim(dedtypes->dim); 4111 4112 ClassDeclaration *s = t->sym; 4113 while (s && s->baseclasses->dim > 0) 4114 { 4115 // Test the base class 4116 deduceBaseClassParameters((*s->baseclasses)[0], 4117 sc, tparam, parameters, dedtypes, 4118 best, numBaseClassMatches); 4119 4120 // Test the interfaces inherited by the base class 4121 for (size_t i = 0; i < s->interfaces.length; ++i) 4122 { 4123 BaseClass *b = s->interfaces.ptr[i]; 4124 deduceBaseClassParameters(b, sc, tparam, parameters, dedtypes, 4125 best, numBaseClassMatches); 4126 } 4127 s = (*s->baseclasses)[0]->sym; 4128 } 4129 4130 if (numBaseClassMatches == 0) 4131 { 4132 result = MATCHnomatch; 4133 return; 4134 } 4135 4136 // If we got at least one match, copy the known types into dedtypes 4137 memcpy(dedtypes->tdata(), best->tdata(), best->dim * sizeof(void *)); 4138 result = MATCHconvert; 4139 return; 4140 } 4141 4142 // Extra check 4143 if (tparam && tparam->ty == Tclass) 4144 { 4145 TypeClass *tp = (TypeClass *)tparam; 4146 4147 //printf("\t%d\n", (MATCH) t->implicitConvTo(tp)); 4148 if (wm && t->deduceWild(tparam, false)) 4149 { 4150 result = MATCHconst; 4151 return; 4152 } 4153 result = t->implicitConvTo(tp); 4154 return; 4155 } 4156 visit((Type *)t); 4157 } 4158 4159 void visit(Expression *e) 4160 { 4161 //printf("Expression::deduceType(e = %s)\n", e->toChars()); 4162 size_t i = templateParameterLookup(tparam, parameters); 4163 if (i == IDX_NOTFOUND || ((TypeIdentifier *)tparam)->idents.dim > 0) 4164 { 4165 if (e == emptyArrayElement && tparam->ty == Tarray) 4166 { 4167 Type *tn = ((TypeNext *)tparam)->next; 4168 result = deduceType(emptyArrayElement, sc, tn, parameters, dedtypes, wm); 4169 return; 4170 } 4171 e->type->accept(this); 4172 return; 4173 } 4174 4175 TemplateTypeParameter *tp = (*parameters)[i]->isTemplateTypeParameter(); 4176 if (!tp) 4177 return; // nomatch 4178 4179 if (e == emptyArrayElement) 4180 { 4181 if ((*dedtypes)[i]) 4182 { 4183 result = MATCHexact; 4184 return; 4185 } 4186 if (tp->defaultType) 4187 { 4188 tp->defaultType->accept(this); 4189 return; 4190 } 4191 } 4192 4193 Type *at = (Type *)(*dedtypes)[i]; 4194 Type *tt; 4195 if (unsigned char wx = deduceWildHelper(e->type, &tt, tparam)) 4196 { 4197 *wm |= wx; 4198 result = MATCHconst; 4199 } 4200 else if (MATCH m = deduceTypeHelper(e->type, &tt, tparam)) 4201 { 4202 result = m; 4203 } 4204 else 4205 return; // nomatch 4206 4207 // expression vs (none) 4208 if (!at) 4209 { 4210 (*dedtypes)[i] = new TypeDeduced(tt, e, tparam); 4211 return; 4212 } 4213 4214 TypeDeduced *xt = NULL; 4215 if (at->ty == Tnone) 4216 { 4217 xt = (TypeDeduced *)at; 4218 at = xt->tded; 4219 } 4220 4221 // From previous matched expressions to current deduced type 4222 MATCH match1 = xt ? xt->matchAll(tt) : MATCHnomatch; 4223 4224 // From current expresssion to previous deduced type 4225 Type *pt = at->addMod(tparam->mod); 4226 if (*wm) 4227 pt = pt->substWildTo(*wm); 4228 MATCH match2 = e->implicitConvTo(pt); 4229 4230 if (match1 > MATCHnomatch && match2 > MATCHnomatch) 4231 { 4232 if (at->implicitConvTo(tt) <= MATCHnomatch) 4233 match1 = MATCHnomatch; // Prefer at 4234 else if (tt->implicitConvTo(at) <= MATCHnomatch) 4235 match2 = MATCHnomatch; // Prefer tt 4236 else if (tt->isTypeBasic() && tt->ty == at->ty && tt->mod != at->mod) 4237 { 4238 if (!tt->isMutable() && !at->isMutable()) 4239 tt = tt->mutableOf()->addMod(MODmerge(tt->mod, at->mod)); 4240 else if (tt->isMutable()) 4241 { 4242 if (at->mod == 0) // Prefer unshared 4243 match1 = MATCHnomatch; 4244 else 4245 match2 = MATCHnomatch; 4246 } 4247 else if (at->isMutable()) 4248 { 4249 if (tt->mod == 0) // Prefer unshared 4250 match2 = MATCHnomatch; 4251 else 4252 match1 = MATCHnomatch; 4253 } 4254 //printf("tt = %s, at = %s\n", tt->toChars(), at->toChars()); 4255 } 4256 else 4257 { 4258 match1 = MATCHnomatch; 4259 match2 = MATCHnomatch; 4260 } 4261 } 4262 if (match1 > MATCHnomatch) 4263 { 4264 // Prefer current match: tt 4265 if (xt) 4266 xt->update(tt, e, tparam); 4267 else 4268 (*dedtypes)[i] = tt; 4269 result = match1; 4270 return; 4271 } 4272 if (match2 > MATCHnomatch) 4273 { 4274 // Prefer previous match: (*dedtypes)[i] 4275 if (xt) 4276 xt->update(e, tparam); 4277 result = match2; 4278 return; 4279 } 4280 4281 /* Deduce common type 4282 */ 4283 if (Type *t = rawTypeMerge(at, tt)) 4284 { 4285 if (xt) 4286 xt->update(t, e, tparam); 4287 else 4288 (*dedtypes)[i] = t; 4289 4290 pt = tt->addMod(tparam->mod); 4291 if (*wm) 4292 pt = pt->substWildTo(*wm); 4293 result = e->implicitConvTo(pt); 4294 return; 4295 } 4296 4297 result = MATCHnomatch; 4298 } 4299 4300 MATCH deduceEmptyArrayElement() 4301 { 4302 if (!emptyArrayElement) 4303 { 4304 emptyArrayElement = new IdentifierExp(Loc(), Id::p); // dummy 4305 emptyArrayElement->type = Type::tvoid; 4306 } 4307 assert(tparam->ty == Tarray); 4308 4309 Type *tn = ((TypeNext *)tparam)->next; 4310 return deduceType(emptyArrayElement, sc, tn, parameters, dedtypes, wm); 4311 } 4312 4313 void visit(NullExp *e) 4314 { 4315 if (tparam->ty == Tarray && e->type->ty == Tnull) 4316 { 4317 // tparam:T[] <- e:null (void[]) 4318 result = deduceEmptyArrayElement(); 4319 return; 4320 } 4321 visit((Expression *)e); 4322 } 4323 4324 void visit(StringExp *e) 4325 { 4326 Type *taai; 4327 if (e->type->ty == Tarray && 4328 (tparam->ty == Tsarray || 4329 (tparam->ty == Taarray && (taai = ((TypeAArray *)tparam)->index)->ty == Tident && 4330 ((TypeIdentifier *)taai)->idents.dim == 0))) 4331 { 4332 // Consider compile-time known boundaries 4333 e->type->nextOf()->sarrayOf(e->len)->accept(this); 4334 return; 4335 } 4336 visit((Expression *)e); 4337 } 4338 4339 void visit(ArrayLiteralExp *e) 4340 { 4341 // https://issues.dlang.org/show_bug.cgi?id=20092 4342 if (e->elements && e->elements->dim && 4343 e->type->toBasetype()->nextOf()->ty == Tvoid) 4344 { 4345 result = deduceEmptyArrayElement(); 4346 return; 4347 } 4348 if ((!e->elements || !e->elements->dim) && 4349 e->type->toBasetype()->nextOf()->ty == Tvoid && 4350 tparam->ty == Tarray) 4351 { 4352 // tparam:T[] <- e:[] (void[]) 4353 result = deduceEmptyArrayElement(); 4354 return; 4355 } 4356 4357 if (tparam->ty == Tarray && e->elements && e->elements->dim) 4358 { 4359 Type *tn = ((TypeDArray *)tparam)->next; 4360 result = MATCHexact; 4361 if (e->basis) 4362 { 4363 MATCH m = deduceType(e->basis, sc, tn, parameters, dedtypes, wm); 4364 if (m < result) 4365 result = m; 4366 } 4367 for (size_t i = 0; i < e->elements->dim; i++) 4368 { 4369 if (result <= MATCHnomatch) 4370 break; 4371 Expression *el = (*e->elements)[i]; 4372 if (!el) 4373 continue; 4374 MATCH m = deduceType(el, sc, tn, parameters, dedtypes, wm); 4375 if (m < result) 4376 result = m; 4377 } 4378 return; 4379 } 4380 4381 Type *taai; 4382 if (e->type->ty == Tarray && 4383 (tparam->ty == Tsarray || 4384 (tparam->ty == Taarray && (taai = ((TypeAArray *)tparam)->index)->ty == Tident && 4385 ((TypeIdentifier *)taai)->idents.dim == 0))) 4386 { 4387 // Consider compile-time known boundaries 4388 e->type->nextOf()->sarrayOf(e->elements->dim)->accept(this); 4389 return; 4390 } 4391 visit((Expression *)e); 4392 } 4393 4394 void visit(AssocArrayLiteralExp *e) 4395 { 4396 if (tparam->ty == Taarray && e->keys && e->keys->dim) 4397 { 4398 TypeAArray *taa = (TypeAArray *)tparam; 4399 result = MATCHexact; 4400 for (size_t i = 0; i < e->keys->dim; i++) 4401 { 4402 MATCH m1 = deduceType((*e->keys)[i], sc, taa->index, parameters, dedtypes, wm); 4403 if (m1 < result) 4404 result = m1; 4405 if (result <= MATCHnomatch) 4406 break; 4407 MATCH m2 = deduceType((*e->values)[i], sc, taa->next, parameters, dedtypes, wm); 4408 if (m2 < result) 4409 result = m2; 4410 if (result <= MATCHnomatch) 4411 break; 4412 } 4413 return; 4414 } 4415 visit((Expression *)e); 4416 } 4417 4418 void visit(FuncExp *e) 4419 { 4420 //printf("e->type = %s, tparam = %s\n", e->type->toChars(), tparam->toChars()); 4421 if (e->td) 4422 { 4423 Type *to = tparam; 4424 if (!to->nextOf() || to->nextOf()->ty != Tfunction) 4425 return; 4426 TypeFunction *tof = (TypeFunction *)to->nextOf(); 4427 4428 // Parameter types inference from 'tof' 4429 assert(e->td->_scope); 4430 TypeFunction *tf = (TypeFunction *)e->fd->type; 4431 //printf("\ttof = %s\n", tof->toChars()); 4432 //printf("\ttf = %s\n", tf->toChars()); 4433 size_t dim = Parameter::dim(tf->parameters); 4434 4435 if (Parameter::dim(tof->parameters) != dim || 4436 tof->varargs != tf->varargs) 4437 return; 4438 4439 Objects *tiargs = new Objects(); 4440 tiargs->reserve(e->td->parameters->dim); 4441 4442 for (size_t i = 0; i < e->td->parameters->dim; i++) 4443 { 4444 TemplateParameter *tp = (*e->td->parameters)[i]; 4445 size_t u = 0; 4446 for (; u < dim; u++) 4447 { 4448 Parameter *p = Parameter::getNth(tf->parameters, u); 4449 if (p->type->ty == Tident && 4450 ((TypeIdentifier *)p->type)->ident == tp->ident) 4451 { 4452 break; 4453 } 4454 } 4455 assert(u < dim); 4456 Parameter *pto = Parameter::getNth(tof->parameters, u); 4457 if (!pto) 4458 break; 4459 Type *t = pto->type->syntaxCopy(); // Bugzilla 11774 4460 if (reliesOnTident(t, parameters, inferStart)) 4461 return; 4462 t = t->semantic(e->loc, sc); 4463 if (t->ty == Terror) 4464 return; 4465 tiargs->push(t); 4466 } 4467 4468 // Set target of return type inference 4469 if (!tf->next && tof->next) 4470 e->fd->treq = tparam; 4471 4472 TemplateInstance *ti = new TemplateInstance(e->loc, e->td, tiargs); 4473 Expression *ex = new ScopeExp(e->loc, ti); 4474 ex = ::semantic(ex, e->td->_scope); 4475 4476 // Reset inference target for the later re-semantic 4477 e->fd->treq = NULL; 4478 4479 if (ex->op == TOKerror) 4480 return; 4481 if (ex->op != TOKfunction) 4482 return; 4483 visit(ex->type); 4484 return; 4485 } 4486 4487 Type *t = e->type; 4488 4489 if (t->ty == Tdelegate && tparam->ty == Tpointer) 4490 return; 4491 4492 // Allow conversion from implicit function pointer to delegate 4493 if (e->tok == TOKreserved && 4494 t->ty == Tpointer && tparam->ty == Tdelegate) 4495 { 4496 TypeFunction *tf = (TypeFunction *)t->nextOf(); 4497 t = (new TypeDelegate(tf))->merge(); 4498 } 4499 //printf("tparam = %s <= e->type = %s, t = %s\n", tparam->toChars(), e->type->toChars(), t->toChars()); 4500 visit(t); 4501 } 4502 4503 void visit(SliceExp *e) 4504 { 4505 Type *taai; 4506 if (e->type->ty == Tarray && 4507 (tparam->ty == Tsarray || 4508 (tparam->ty == Taarray && (taai = ((TypeAArray *)tparam)->index)->ty == Tident && 4509 ((TypeIdentifier *)taai)->idents.dim == 0))) 4510 { 4511 // Consider compile-time known boundaries 4512 if (Type *tsa = toStaticArrayType(e)) 4513 { 4514 tsa->accept(this); 4515 return; 4516 } 4517 } 4518 visit((Expression *)e); 4519 } 4520 4521 void visit(CommaExp *e) 4522 { 4523 ((CommaExp *)e)->e2->accept(this); 4524 } 4525 }; 4526 4527 DeduceType v(sc, tparam, parameters, dedtypes, wm, inferStart); 4528 if (Type *t = isType(o)) 4529 t->accept(&v); 4530 else 4531 { 4532 assert(isExpression(o) && wm); 4533 ((Expression *)o)->accept(&v); 4534 } 4535 return v.result; 4536 } 4537 4538 /******************************* 4539 * Input: 4540 * t Tested type, if NULL, returns NULL. 4541 * tparams Optional template parameters. 4542 * == NULL: 4543 * If one of the subtypes of this type is a TypeIdentifier, 4544 * i.e. it's an unresolved type, return that type. 4545 * != NULL: 4546 * Only when the TypeIdentifier is one of template parameters, 4547 * return that type. 4548 */ 4549 4550 bool reliesOnTident(Type *t, TemplateParameters *tparams, size_t iStart) 4551 { 4552 class ReliesOnTident : public Visitor 4553 { 4554 public: 4555 TemplateParameters *tparams; 4556 size_t iStart; 4557 bool result; 4558 4559 ReliesOnTident(TemplateParameters *tparams, size_t iStart) 4560 : tparams(tparams), iStart(iStart) 4561 { 4562 result = false; 4563 } 4564 4565 void visit(Type *) 4566 { 4567 } 4568 4569 void visit(TypeNext *t) 4570 { 4571 t->next->accept(this); 4572 } 4573 4574 void visit(TypeVector *t) 4575 { 4576 t->basetype->accept(this); 4577 } 4578 4579 void visit(TypeAArray *t) 4580 { 4581 visit((TypeNext *)t); 4582 if (!result) 4583 t->index->accept(this); 4584 } 4585 4586 void visit(TypeFunction *t) 4587 { 4588 size_t dim = Parameter::dim(t->parameters); 4589 for (size_t i = 0; i < dim; i++) 4590 { 4591 Parameter *fparam = Parameter::getNth(t->parameters, i); 4592 fparam->type->accept(this); 4593 if (result) 4594 return; 4595 } 4596 if (t->next) 4597 t->next->accept(this); 4598 } 4599 4600 void visit(TypeIdentifier *t) 4601 { 4602 if (!tparams) 4603 { 4604 result = true; 4605 return; 4606 } 4607 4608 for (size_t i = iStart; i < tparams->dim; i++) 4609 { 4610 TemplateParameter *tp = (*tparams)[i]; 4611 if (tp->ident->equals(t->ident)) 4612 { 4613 result = true; 4614 return; 4615 } 4616 } 4617 } 4618 4619 void visit(TypeInstance *t) 4620 { 4621 if (!tparams) 4622 return; 4623 4624 for (size_t i = iStart; i < tparams->dim; i++) 4625 { 4626 TemplateParameter *tp = (*tparams)[i]; 4627 if (t->tempinst->name == tp->ident) 4628 { 4629 result = true; 4630 return; 4631 } 4632 } 4633 if (!t->tempinst->tiargs) 4634 return; 4635 for (size_t i = 0; i < t->tempinst->tiargs->dim; i++) 4636 { 4637 Type *ta = isType((*t->tempinst->tiargs)[i]); 4638 if (ta) 4639 { 4640 ta->accept(this); 4641 if (result) 4642 return; 4643 } 4644 } 4645 } 4646 4647 void visit(TypeTypeof *t) 4648 { 4649 //printf("TypeTypeof::reliesOnTident('%s')\n", t->toChars()); 4650 t->exp->accept(this); 4651 } 4652 4653 void visit(TypeTuple *t) 4654 { 4655 if (t->arguments) 4656 { 4657 for (size_t i = 0; i < t->arguments->dim; i++) 4658 { 4659 Parameter *arg = (*t->arguments)[i]; 4660 arg->type->accept(this); 4661 if (result) 4662 return; 4663 } 4664 } 4665 } 4666 4667 void visit(Expression *) 4668 { 4669 //printf("Expression::reliesOnTident('%s')\n", e->toChars()); 4670 } 4671 4672 void visit(IdentifierExp *e) 4673 { 4674 //printf("IdentifierExp::reliesOnTident('%s')\n", e->toChars()); 4675 for (size_t i = iStart; i < tparams->dim; i++) 4676 { 4677 TemplateParameter *tp = (*tparams)[i]; 4678 if (e->ident == tp->ident) 4679 { 4680 result = true; 4681 return; 4682 } 4683 } 4684 } 4685 4686 void visit(TupleExp *e) 4687 { 4688 //printf("TupleExp::reliesOnTident('%s')\n", e->toChars()); 4689 if (e->exps) 4690 { 4691 for (size_t i = 0; i < e->exps->dim; i++) 4692 { 4693 Expression *ea = (*e->exps)[i]; 4694 ea->accept(this); 4695 if (result) 4696 return; 4697 } 4698 } 4699 } 4700 4701 void visit(ArrayLiteralExp *e) 4702 { 4703 //printf("ArrayLiteralExp::reliesOnTident('%s')\n", e->toChars()); 4704 if (e->elements) 4705 { 4706 for (size_t i = 0; i < e->elements->dim; i++) 4707 { 4708 Expression *el = (*e->elements)[i]; 4709 el->accept(this); 4710 if (result) 4711 return; 4712 } 4713 } 4714 } 4715 4716 void visit(AssocArrayLiteralExp *e) 4717 { 4718 //printf("AssocArrayLiteralExp::reliesOnTident('%s')\n", e->toChars()); 4719 for (size_t i = 0; i < e->keys->dim; i++) 4720 { 4721 Expression *ek = (*e->keys)[i]; 4722 ek->accept(this); 4723 if (result) 4724 return; 4725 } 4726 for (size_t i = 0; i < e->values->dim; i++) 4727 { 4728 Expression *ev = (*e->values)[i]; 4729 ev->accept(this); 4730 if (result) 4731 return; 4732 } 4733 } 4734 4735 void visit(StructLiteralExp *e) 4736 { 4737 //printf("StructLiteralExp::reliesOnTident('%s')\n", e->toChars()); 4738 if (e->elements) 4739 { 4740 for (size_t i = 0; i < e->elements->dim; i++) 4741 { 4742 Expression *ea = (*e->elements)[i]; 4743 ea->accept(this); 4744 if (result) 4745 return; 4746 } 4747 } 4748 } 4749 4750 void visit(TypeExp *e) 4751 { 4752 //printf("TypeExp::reliesOnTident('%s')\n", e->toChars()); 4753 e->type->accept(this); 4754 } 4755 4756 void visit(NewExp *e) 4757 { 4758 //printf("NewExp::reliesOnTident('%s')\n", e->toChars()); 4759 if (e->thisexp) 4760 e->thisexp->accept(this); 4761 if (!result && e->newargs) 4762 { 4763 for (size_t i = 0; i < e->newargs->dim; i++) 4764 { 4765 Expression *ea = (*e->newargs)[i]; 4766 ea->accept(this); 4767 if (result) 4768 return; 4769 } 4770 } 4771 e->newtype->accept(this); 4772 if (!result && e->arguments) 4773 { 4774 for (size_t i = 0; i < e->arguments->dim; i++) 4775 { 4776 Expression *ea = (*e->arguments)[i]; 4777 ea->accept(this); 4778 if (result) 4779 return; 4780 } 4781 } 4782 } 4783 4784 void visit(NewAnonClassExp *) 4785 { 4786 //printf("NewAnonClassExp::reliesOnTident('%s')\n", e->toChars()); 4787 result = true; 4788 } 4789 4790 void visit(FuncExp *) 4791 { 4792 //printf("FuncExp::reliesOnTident('%s')\n", e->toChars()); 4793 result = true; 4794 } 4795 4796 void visit(TypeidExp *e) 4797 { 4798 //printf("TypeidExp::reliesOnTident('%s')\n", e->toChars()); 4799 if (Expression *ea = isExpression(e->obj)) 4800 ea->accept(this); 4801 else if (Type *ta = isType(e->obj)) 4802 ta->accept(this); 4803 } 4804 4805 void visit(TraitsExp *e) 4806 { 4807 //printf("TraitsExp::reliesOnTident('%s')\n", e->toChars()); 4808 if (e->args) 4809 { 4810 for (size_t i = 0; i < e->args->dim; i++) 4811 { 4812 RootObject *oa = (*e->args)[i]; 4813 if (Expression *ea = isExpression(oa)) 4814 ea->accept(this); 4815 else if (Type *ta = isType(oa)) 4816 ta->accept(this); 4817 if (result) 4818 return; 4819 } 4820 } 4821 } 4822 4823 void visit(IsExp *e) 4824 { 4825 //printf("IsExp::reliesOnTident('%s')\n", e->toChars()); 4826 e->targ->accept(this); 4827 } 4828 4829 void visit(UnaExp *e) 4830 { 4831 //printf("UnaExp::reliesOnTident('%s')\n", e->toChars()); 4832 e->e1->accept(this); 4833 } 4834 4835 void visit(DotTemplateInstanceExp *e) 4836 { 4837 //printf("DotTemplateInstanceExp::reliesOnTident('%s')\n", e->toChars()); 4838 visit((UnaExp *)e); 4839 if (!result && e->ti->tiargs) 4840 { 4841 for (size_t i = 0; i < e->ti->tiargs->dim; i++) 4842 { 4843 RootObject *oa = (*e->ti->tiargs)[i]; 4844 if (Expression *ea = isExpression(oa)) 4845 ea->accept(this); 4846 else if (Type *ta = isType(oa)) 4847 ta->accept(this); 4848 if (result) 4849 return; 4850 } 4851 } 4852 } 4853 4854 void visit(CallExp *e) 4855 { 4856 //printf("CallExp::reliesOnTident('%s')\n", e->toChars()); 4857 visit((UnaExp *)e); 4858 if (!result && e->arguments) 4859 { 4860 for (size_t i = 0; i < e->arguments->dim; i++) 4861 { 4862 Expression *ea = (*e->arguments)[i]; 4863 ea->accept(this); 4864 if (result) 4865 return; 4866 } 4867 } 4868 } 4869 4870 void visit(CastExp *e) 4871 { 4872 //printf("CastExp::reliesOnTident('%s')\n", e->toChars()); 4873 visit((UnaExp *)e); 4874 // e.to can be null for cast() with no type 4875 if (!result && e->to) 4876 e->to->accept(this); 4877 } 4878 4879 void visit(SliceExp *e) 4880 { 4881 //printf("SliceExp::reliesOnTident('%s')\n", e->toChars()); 4882 visit((UnaExp *)e); 4883 if (!result && e->lwr) 4884 e->lwr->accept(this); 4885 if (!result && e->upr) 4886 e->upr->accept(this); 4887 } 4888 4889 void visit(IntervalExp *e) 4890 { 4891 //printf("IntervalExp::reliesOnTident('%s')\n", e->toChars()); 4892 e->lwr->accept(this); 4893 if (!result) 4894 e->upr->accept(this); 4895 } 4896 4897 void visit(ArrayExp *e) 4898 { 4899 //printf("ArrayExp::reliesOnTident('%s')\n", e->toChars()); 4900 visit((UnaExp *)e); 4901 if (!result && e->arguments) 4902 { 4903 for (size_t i = 0; i < e->arguments->dim; i++) 4904 { 4905 Expression *ea = (*e->arguments)[i]; 4906 ea->accept(this); 4907 } 4908 } 4909 } 4910 4911 void visit(BinExp *e) 4912 { 4913 //printf("BinExp::reliesOnTident('%s')\n", e->toChars()); 4914 e->e1->accept(this); 4915 if (!result) 4916 e->e2->accept(this); 4917 } 4918 4919 void visit(CondExp *e) 4920 { 4921 //printf("BinExp::reliesOnTident('%s')\n", e->toChars()); 4922 e->econd->accept(this); 4923 if (!result) 4924 visit((BinExp *)e); 4925 } 4926 }; 4927 4928 if (!t) 4929 return false; 4930 4931 ReliesOnTident v(tparams, iStart); 4932 t->accept(&v); 4933 return v.result; 4934 } 4935 4936 /* ======================== TemplateParameter =============================== */ 4937 4938 TemplateParameter::TemplateParameter(Loc loc, Identifier *ident) 4939 { 4940 this->loc = loc; 4941 this->ident = ident; 4942 this->dependent = false; 4943 } 4944 4945 TemplateTypeParameter *TemplateParameter::isTemplateTypeParameter() 4946 { 4947 return NULL; 4948 } 4949 4950 TemplateValueParameter *TemplateParameter::isTemplateValueParameter() 4951 { 4952 return NULL; 4953 } 4954 4955 TemplateAliasParameter *TemplateParameter::isTemplateAliasParameter() 4956 { 4957 return NULL; 4958 } 4959 4960 TemplateTupleParameter *TemplateParameter::isTemplateTupleParameter() 4961 { 4962 return NULL; 4963 } 4964 4965 TemplateThisParameter *TemplateParameter::isTemplateThisParameter() 4966 { 4967 return NULL; 4968 } 4969 4970 /******************************************* 4971 * Match to a particular TemplateParameter. 4972 * Input: 4973 * instLoc location that the template is instantiated. 4974 * tiargs[] actual arguments to template instance 4975 * i i'th argument 4976 * parameters[] template parameters 4977 * dedtypes[] deduced arguments to template instance 4978 * *psparam set to symbol declared and initialized to dedtypes[i] 4979 */ 4980 MATCH TemplateParameter::matchArg(Loc instLoc, Scope *sc, Objects *tiargs, 4981 size_t i, TemplateParameters *parameters, Objects *dedtypes, 4982 Declaration **psparam) 4983 { 4984 RootObject *oarg; 4985 4986 if (i < tiargs->dim) 4987 oarg = (*tiargs)[i]; 4988 else 4989 { 4990 // Get default argument instead 4991 oarg = defaultArg(instLoc, sc); 4992 if (!oarg) 4993 { 4994 assert(i < dedtypes->dim); 4995 // It might have already been deduced 4996 oarg = (*dedtypes)[i]; 4997 if (!oarg) 4998 goto Lnomatch; 4999 } 5000 } 5001 return matchArg(sc, oarg, i, parameters, dedtypes, psparam); 5002 5003 Lnomatch: 5004 if (psparam) 5005 *psparam = NULL; 5006 return MATCHnomatch; 5007 } 5008 5009 /* ======================== TemplateTypeParameter =========================== */ 5010 5011 // type-parameter 5012 5013 Type *TemplateTypeParameter::tdummy = NULL; 5014 5015 TemplateTypeParameter::TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType, 5016 Type *defaultType) 5017 : TemplateParameter(loc, ident) 5018 { 5019 this->ident = ident; 5020 this->specType = specType; 5021 this->defaultType = defaultType; 5022 } 5023 5024 TemplateTypeParameter *TemplateTypeParameter::isTemplateTypeParameter() 5025 { 5026 return this; 5027 } 5028 5029 TemplateParameter *TemplateTypeParameter::syntaxCopy() 5030 { 5031 return new TemplateTypeParameter(loc, ident, 5032 specType ? specType->syntaxCopy() : NULL, 5033 defaultType ? defaultType->syntaxCopy() : NULL); 5034 } 5035 5036 bool TemplateTypeParameter::declareParameter(Scope *sc) 5037 { 5038 //printf("TemplateTypeParameter::declareParameter('%s')\n", ident->toChars()); 5039 TypeIdentifier *ti = new TypeIdentifier(loc, ident); 5040 Declaration *ad = new AliasDeclaration(loc, ident, ti); 5041 return sc->insert(ad) != NULL; 5042 } 5043 5044 bool TemplateTypeParameter::semantic(Scope *sc, TemplateParameters *parameters) 5045 { 5046 //printf("TemplateTypeParameter::semantic('%s')\n", ident->toChars()); 5047 if (specType && !reliesOnTident(specType, parameters)) 5048 { 5049 specType = specType->semantic(loc, sc); 5050 } 5051 return !(specType && isError(specType)); 5052 } 5053 5054 MATCH TemplateTypeParameter::matchArg(Scope *sc, RootObject *oarg, 5055 size_t i, TemplateParameters *parameters, Objects *dedtypes, 5056 Declaration **psparam) 5057 { 5058 //printf("TemplateTypeParameter::matchArg('%s')\n", ident->toChars()); 5059 MATCH m = MATCHexact; 5060 Type *ta = isType(oarg); 5061 if (!ta) 5062 { 5063 //printf("%s %p %p %p\n", oarg->toChars(), isExpression(oarg), isDsymbol(oarg), isTuple(oarg)); 5064 goto Lnomatch; 5065 } 5066 //printf("ta is %s\n", ta->toChars()); 5067 5068 if (specType) 5069 { 5070 if (!ta || ta == tdummy) 5071 goto Lnomatch; 5072 5073 //printf("\tcalling deduceType(): ta is %s, specType is %s\n", ta->toChars(), specType->toChars()); 5074 MATCH m2 = deduceType(ta, sc, specType, parameters, dedtypes); 5075 if (m2 <= MATCHnomatch) 5076 { 5077 //printf("\tfailed deduceType\n"); 5078 goto Lnomatch; 5079 } 5080 5081 if (m2 < m) 5082 m = m2; 5083 if ((*dedtypes)[i]) 5084 { 5085 Type *t = (Type *)(*dedtypes)[i]; 5086 5087 if (dependent && !t->equals(ta)) // Bugzilla 14357 5088 goto Lnomatch; 5089 5090 /* This is a self-dependent parameter. For example: 5091 * template X(T : T*) {} 5092 * template X(T : S!T, alias S) {} 5093 */ 5094 //printf("t = %s ta = %s\n", t->toChars(), ta->toChars()); 5095 ta = t; 5096 } 5097 } 5098 else 5099 { 5100 if ((*dedtypes)[i]) 5101 { 5102 // Must match already deduced type 5103 Type *t = (Type *)(*dedtypes)[i]; 5104 5105 if (!t->equals(ta)) 5106 { 5107 //printf("t = %s ta = %s\n", t->toChars(), ta->toChars()); 5108 goto Lnomatch; 5109 } 5110 } 5111 else 5112 { 5113 // So that matches with specializations are better 5114 m = MATCHconvert; 5115 } 5116 } 5117 (*dedtypes)[i] = ta; 5118 5119 if (psparam) 5120 *psparam = new AliasDeclaration(loc, ident, ta); 5121 //printf("\tm = %d\n", m); 5122 return dependent ? MATCHexact : m; 5123 5124 Lnomatch: 5125 if (psparam) 5126 *psparam = NULL; 5127 //printf("\tm = %d\n", MATCHnomatch); 5128 return MATCHnomatch; 5129 } 5130 5131 5132 void TemplateTypeParameter::print(RootObject *oarg, RootObject *oded) 5133 { 5134 printf(" %s\n", ident->toChars()); 5135 5136 Type *t = isType(oarg); 5137 Type *ta = isType(oded); 5138 5139 assert(ta); 5140 5141 if (specType) 5142 printf("\tSpecialization: %s\n", specType->toChars()); 5143 if (defaultType) 5144 printf("\tDefault: %s\n", defaultType->toChars()); 5145 printf("\tParameter: %s\n", t ? t->toChars() : "NULL"); 5146 printf("\tDeduced Type: %s\n", ta->toChars()); 5147 } 5148 5149 void *TemplateTypeParameter::dummyArg() 5150 { 5151 Type *t = specType; 5152 if (!t) 5153 { 5154 // Use this for alias-parameter's too (?) 5155 if (!tdummy) 5156 tdummy = new TypeIdentifier(loc, ident); 5157 t = tdummy; 5158 } 5159 return (void *)t; 5160 } 5161 5162 5163 RootObject *TemplateTypeParameter::specialization() 5164 { 5165 return specType; 5166 } 5167 5168 RootObject *TemplateTypeParameter::defaultArg(Loc, Scope *sc) 5169 { 5170 Type *t = defaultType; 5171 if (t) 5172 { 5173 t = t->syntaxCopy(); 5174 t = t->semantic(loc, sc); // use the parameter loc 5175 } 5176 return t; 5177 } 5178 5179 bool TemplateTypeParameter::hasDefaultArg() 5180 { 5181 return defaultType != NULL; 5182 } 5183 5184 /* ======================== TemplateThisParameter =========================== */ 5185 5186 // this-parameter 5187 5188 TemplateThisParameter::TemplateThisParameter(Loc loc, Identifier *ident, 5189 Type *specType, 5190 Type *defaultType) 5191 : TemplateTypeParameter(loc, ident, specType, defaultType) 5192 { 5193 } 5194 5195 TemplateThisParameter *TemplateThisParameter::isTemplateThisParameter() 5196 { 5197 return this; 5198 } 5199 5200 TemplateParameter *TemplateThisParameter::syntaxCopy() 5201 { 5202 return new TemplateThisParameter(loc, ident, 5203 specType ? specType->syntaxCopy() : NULL, 5204 defaultType ? defaultType->syntaxCopy() : NULL); 5205 } 5206 5207 /* ======================== TemplateAliasParameter ========================== */ 5208 5209 // alias-parameter 5210 5211 Dsymbol *TemplateAliasParameter::sdummy = NULL; 5212 5213 TemplateAliasParameter::TemplateAliasParameter(Loc loc, Identifier *ident, 5214 Type *specType, RootObject *specAlias, RootObject *defaultAlias) 5215 : TemplateParameter(loc, ident) 5216 { 5217 this->ident = ident; 5218 this->specType = specType; 5219 this->specAlias = specAlias; 5220 this->defaultAlias = defaultAlias; 5221 } 5222 5223 TemplateAliasParameter *TemplateAliasParameter::isTemplateAliasParameter() 5224 { 5225 return this; 5226 } 5227 5228 TemplateParameter *TemplateAliasParameter::syntaxCopy() 5229 { 5230 return new TemplateAliasParameter(loc, ident, 5231 specType ? specType->syntaxCopy() : NULL, 5232 objectSyntaxCopy(specAlias), 5233 objectSyntaxCopy(defaultAlias)); 5234 } 5235 5236 bool TemplateAliasParameter::declareParameter(Scope *sc) 5237 { 5238 TypeIdentifier *ti = new TypeIdentifier(loc, ident); 5239 Declaration *ad = new AliasDeclaration(loc, ident, ti); 5240 return sc->insert(ad) != NULL; 5241 } 5242 5243 static RootObject *aliasParameterSemantic(Loc loc, Scope *sc, RootObject *o, TemplateParameters *parameters) 5244 { 5245 if (o) 5246 { 5247 Expression *ea = isExpression(o); 5248 Type *ta = isType(o); 5249 if (ta && (!parameters || !reliesOnTident(ta, parameters))) 5250 { 5251 Dsymbol *s = ta->toDsymbol(sc); 5252 if (s) 5253 o = s; 5254 else 5255 o = ta->semantic(loc, sc); 5256 } 5257 else if (ea) 5258 { 5259 sc = sc->startCTFE(); 5260 ea = ::semantic(ea, sc); 5261 sc = sc->endCTFE(); 5262 o = ea->ctfeInterpret(); 5263 } 5264 } 5265 return o; 5266 } 5267 5268 bool TemplateAliasParameter::semantic(Scope *sc, TemplateParameters *parameters) 5269 { 5270 if (specType && !reliesOnTident(specType, parameters)) 5271 { 5272 specType = specType->semantic(loc, sc); 5273 } 5274 specAlias = aliasParameterSemantic(loc, sc, specAlias, parameters); 5275 return !(specType && isError(specType)) && 5276 !(specAlias && isError(specAlias)); 5277 } 5278 5279 MATCH TemplateAliasParameter::matchArg(Scope *sc, RootObject *oarg, 5280 size_t i, TemplateParameters *parameters, Objects *dedtypes, 5281 Declaration **psparam) 5282 { 5283 //printf("TemplateAliasParameter::matchArg('%s')\n", ident->toChars()); 5284 MATCH m = MATCHexact; 5285 Type *ta = isType(oarg); 5286 RootObject *sa = ta && !ta->deco ? NULL : getDsymbol(oarg); 5287 Expression *ea = isExpression(oarg); 5288 if (ea && (ea->op == TOKthis || ea->op == TOKsuper)) 5289 sa = ((ThisExp *)ea)->var; 5290 else if (ea && ea->op == TOKscope) 5291 sa = ((ScopeExp *)ea)->sds; 5292 if (sa) 5293 { 5294 if (((Dsymbol *)sa)->isAggregateDeclaration()) 5295 m = MATCHconvert; 5296 5297 /* specType means the alias must be a declaration with a type 5298 * that matches specType. 5299 */ 5300 if (specType) 5301 { 5302 Declaration *d = ((Dsymbol *)sa)->isDeclaration(); 5303 if (!d) 5304 goto Lnomatch; 5305 if (!d->type->equals(specType)) 5306 goto Lnomatch; 5307 } 5308 } 5309 else 5310 { 5311 sa = oarg; 5312 if (ea) 5313 { 5314 if (specType) 5315 { 5316 if (!ea->type->equals(specType)) 5317 goto Lnomatch; 5318 } 5319 } 5320 else if (ta && ta->ty == Tinstance && !specAlias) 5321 { 5322 /* Bugzilla xxxxx: Specialized parameter should be prefeerd 5323 * match to the template type parameter. 5324 * template X(alias a) {} // a == this 5325 * template X(alias a : B!A, alias B, A...) {} // B!A => ta 5326 */ 5327 } 5328 else if (sa && sa == TemplateTypeParameter::tdummy) 5329 { 5330 /* Bugzilla 2025: Aggregate Types should preferentially 5331 * match to the template type parameter. 5332 * template X(alias a) {} // a == this 5333 * template X(T) {} // T => sa 5334 */ 5335 } 5336 else 5337 goto Lnomatch; 5338 } 5339 5340 if (specAlias) 5341 { 5342 if (sa == sdummy) 5343 goto Lnomatch; 5344 Dsymbol *sx = isDsymbol(sa); 5345 if (sa != specAlias && sx) 5346 { 5347 Type *talias = isType(specAlias); 5348 if (!talias) 5349 goto Lnomatch; 5350 5351 TemplateInstance *ti = sx->isTemplateInstance(); 5352 if (!ti && sx->parent) 5353 { 5354 ti = sx->parent->isTemplateInstance(); 5355 if (ti && ti->name != sx->ident) 5356 goto Lnomatch; 5357 } 5358 if (!ti) 5359 goto Lnomatch; 5360 5361 Type *t = new TypeInstance(Loc(), ti); 5362 MATCH m2 = deduceType(t, sc, talias, parameters, dedtypes); 5363 if (m2 <= MATCHnomatch) 5364 goto Lnomatch; 5365 } 5366 } 5367 else if ((*dedtypes)[i]) 5368 { 5369 // Must match already deduced symbol 5370 RootObject *si = (*dedtypes)[i]; 5371 if (!sa || si != sa) 5372 goto Lnomatch; 5373 } 5374 (*dedtypes)[i] = sa; 5375 5376 if (psparam) 5377 { 5378 if (Dsymbol *s = isDsymbol(sa)) 5379 { 5380 *psparam = new AliasDeclaration(loc, ident, s); 5381 } 5382 else if (Type *t = isType(sa)) 5383 { 5384 *psparam = new AliasDeclaration(loc, ident, t); 5385 } 5386 else 5387 { 5388 assert(ea); 5389 5390 // Declare manifest constant 5391 Initializer *init = new ExpInitializer(loc, ea); 5392 VarDeclaration *v = new VarDeclaration(loc, NULL, ident, init); 5393 v->storage_class = STCmanifest; 5394 v->semantic(sc); 5395 *psparam = v; 5396 } 5397 } 5398 return dependent ? MATCHexact : m; 5399 5400 Lnomatch: 5401 if (psparam) 5402 *psparam = NULL; 5403 //printf("\tm = %d\n", MATCHnomatch); 5404 return MATCHnomatch; 5405 } 5406 5407 5408 void TemplateAliasParameter::print(RootObject *, RootObject *oded) 5409 { 5410 printf(" %s\n", ident->toChars()); 5411 5412 Dsymbol *sa = isDsymbol(oded); 5413 assert(sa); 5414 5415 printf("\tParameter alias: %s\n", sa->toChars()); 5416 } 5417 5418 void *TemplateAliasParameter::dummyArg() 5419 { 5420 RootObject *s = specAlias; 5421 if (!s) 5422 { 5423 if (!sdummy) 5424 sdummy = new Dsymbol(); 5425 s = sdummy; 5426 } 5427 return (void*)s; 5428 } 5429 5430 5431 RootObject *TemplateAliasParameter::specialization() 5432 { 5433 return specAlias; 5434 } 5435 5436 RootObject *TemplateAliasParameter::defaultArg(Loc, Scope *sc) 5437 { 5438 RootObject *da = defaultAlias; 5439 Type *ta = isType(defaultAlias); 5440 if (ta) 5441 { 5442 if (ta->ty == Tinstance) 5443 { 5444 // If the default arg is a template, instantiate for each type 5445 da = ta->syntaxCopy(); 5446 } 5447 } 5448 5449 RootObject *o = aliasParameterSemantic(loc, sc, da, NULL); // use the parameter loc 5450 return o; 5451 } 5452 5453 bool TemplateAliasParameter::hasDefaultArg() 5454 { 5455 return defaultAlias != NULL; 5456 } 5457 5458 /* ======================== TemplateValueParameter ========================== */ 5459 5460 // value-parameter 5461 5462 AA *TemplateValueParameter::edummies = NULL; 5463 5464 TemplateValueParameter::TemplateValueParameter(Loc loc, Identifier *ident, Type *valType, 5465 Expression *specValue, Expression *defaultValue) 5466 : TemplateParameter(loc, ident) 5467 { 5468 this->ident = ident; 5469 this->valType = valType; 5470 this->specValue = specValue; 5471 this->defaultValue = defaultValue; 5472 } 5473 5474 TemplateValueParameter *TemplateValueParameter::isTemplateValueParameter() 5475 { 5476 return this; 5477 } 5478 5479 TemplateParameter *TemplateValueParameter::syntaxCopy() 5480 { 5481 return new TemplateValueParameter(loc, ident, 5482 valType->syntaxCopy(), 5483 specValue ? specValue->syntaxCopy() : NULL, 5484 defaultValue ? defaultValue->syntaxCopy() : NULL); 5485 } 5486 5487 bool TemplateValueParameter::declareParameter(Scope *sc) 5488 { 5489 VarDeclaration *v = new VarDeclaration(loc, valType, ident, NULL); 5490 v->storage_class = STCtemplateparameter; 5491 return sc->insert(v) != NULL; 5492 } 5493 5494 bool TemplateValueParameter::semantic(Scope *sc, TemplateParameters *) 5495 { 5496 valType = valType->semantic(loc, sc); 5497 5498 return !isError(valType); 5499 } 5500 5501 MATCH TemplateValueParameter::matchArg(Scope *sc, RootObject *oarg, 5502 size_t i, TemplateParameters *, Objects *dedtypes, Declaration **psparam) 5503 { 5504 //printf("TemplateValueParameter::matchArg('%s')\n", ident->toChars()); 5505 5506 MATCH m = MATCHexact; 5507 5508 Expression *ei = isExpression(oarg); 5509 Type *vt; 5510 5511 if (!ei && oarg) 5512 { 5513 Dsymbol *si = isDsymbol(oarg); 5514 FuncDeclaration *f = si ? si->isFuncDeclaration() : NULL; 5515 if (!f || !f->fbody || f->needThis()) 5516 goto Lnomatch; 5517 5518 ei = new VarExp(loc, f); 5519 ei = ::semantic(ei, sc); 5520 5521 /* If a function is really property-like, and then 5522 * it's CTFEable, ei will be a literal expression. 5523 */ 5524 unsigned int olderrors = global.startGagging(); 5525 ei = resolveProperties(sc, ei); 5526 ei = ei->ctfeInterpret(); 5527 if (global.endGagging(olderrors) || ei->op == TOKerror) 5528 goto Lnomatch; 5529 5530 /* Bugzilla 14520: A property-like function can match to both 5531 * TemplateAlias and ValueParameter. But for template overloads, 5532 * it should always prefer alias parameter to be consistent 5533 * template match result. 5534 * 5535 * template X(alias f) { enum X = 1; } 5536 * template X(int val) { enum X = 2; } 5537 * int f1() { return 0; } // CTFEable 5538 * int f2(); // body-less function is not CTFEable 5539 * enum x1 = X!f1; // should be 1 5540 * enum x2 = X!f2; // should be 1 5541 * 5542 * e.g. The x1 value must be same even if the f1 definition will be moved 5543 * into di while stripping body code. 5544 */ 5545 m = MATCHconvert; 5546 } 5547 5548 if (ei && ei->op == TOKvar) 5549 { 5550 // Resolve const variables that we had skipped earlier 5551 ei = ei->ctfeInterpret(); 5552 } 5553 5554 //printf("\tvalType: %s, ty = %d\n", valType->toChars(), valType->ty); 5555 vt = valType->semantic(loc, sc); 5556 //printf("ei: %s, ei->type: %s\n", ei->toChars(), ei->type->toChars()); 5557 //printf("vt = %s\n", vt->toChars()); 5558 5559 if (ei->type) 5560 { 5561 MATCH m2 = ei->implicitConvTo(vt); 5562 //printf("m: %d\n", m); 5563 if (m2 < m) 5564 m = m2; 5565 if (m <= MATCHnomatch) 5566 goto Lnomatch; 5567 ei = ei->implicitCastTo(sc, vt); 5568 ei = ei->ctfeInterpret(); 5569 } 5570 5571 if (specValue) 5572 { 5573 if (!ei || (Expression *)dmd_aaGetRvalue(edummies, (void *)ei->type) == ei) 5574 goto Lnomatch; 5575 5576 Expression *e = specValue; 5577 5578 sc = sc->startCTFE(); 5579 e = ::semantic(e, sc); 5580 e = resolveProperties(sc, e); 5581 sc = sc->endCTFE(); 5582 e = e->implicitCastTo(sc, vt); 5583 e = e->ctfeInterpret(); 5584 5585 ei = ei->syntaxCopy(); 5586 sc = sc->startCTFE(); 5587 ei = ::semantic(ei, sc); 5588 sc = sc->endCTFE(); 5589 ei = ei->implicitCastTo(sc, vt); 5590 ei = ei->ctfeInterpret(); 5591 //printf("\tei: %s, %s\n", ei->toChars(), ei->type->toChars()); 5592 //printf("\te : %s, %s\n", e->toChars(), e->type->toChars()); 5593 if (!ei->equals(e)) 5594 goto Lnomatch; 5595 } 5596 else 5597 { 5598 if ((*dedtypes)[i]) 5599 { 5600 // Must match already deduced value 5601 Expression *e = (Expression *)(*dedtypes)[i]; 5602 5603 if (!ei || !ei->equals(e)) 5604 goto Lnomatch; 5605 } 5606 } 5607 (*dedtypes)[i] = ei; 5608 5609 if (psparam) 5610 { 5611 Initializer *init = new ExpInitializer(loc, ei); 5612 Declaration *sparam = new VarDeclaration(loc, vt, ident, init); 5613 sparam->storage_class = STCmanifest; 5614 *psparam = sparam; 5615 } 5616 return dependent ? MATCHexact : m; 5617 5618 Lnomatch: 5619 //printf("\tno match\n"); 5620 if (psparam) 5621 *psparam = NULL; 5622 return MATCHnomatch; 5623 } 5624 5625 5626 void TemplateValueParameter::print(RootObject *, RootObject *oded) 5627 { 5628 printf(" %s\n", ident->toChars()); 5629 5630 Expression *ea = isExpression(oded); 5631 5632 if (specValue) 5633 printf("\tSpecialization: %s\n", specValue->toChars()); 5634 printf("\tParameter Value: %s\n", ea ? ea->toChars() : "NULL"); 5635 } 5636 5637 void *TemplateValueParameter::dummyArg() 5638 { 5639 Expression *e = specValue; 5640 if (!e) 5641 { 5642 // Create a dummy value 5643 Expression **pe = (Expression **)dmd_aaGet(&edummies, (void *)valType); 5644 if (!*pe) 5645 *pe = valType->defaultInit(); 5646 e = *pe; 5647 } 5648 return (void *)e; 5649 } 5650 5651 5652 RootObject *TemplateValueParameter::specialization() 5653 { 5654 return specValue; 5655 } 5656 5657 RootObject *TemplateValueParameter::defaultArg(Loc instLoc, Scope *sc) 5658 { 5659 Expression *e = defaultValue; 5660 if (e) 5661 { 5662 e = e->syntaxCopy(); 5663 if ((e = ::semantic(e, sc)) == NULL) 5664 return NULL; 5665 if ((e = resolveProperties(sc, e)) == NULL) 5666 return NULL; 5667 e = e->resolveLoc(instLoc, sc); // use the instantiated loc 5668 e = e->optimize(WANTvalue); 5669 } 5670 return e; 5671 } 5672 5673 bool TemplateValueParameter::hasDefaultArg() 5674 { 5675 return defaultValue != NULL; 5676 } 5677 5678 /* ======================== TemplateTupleParameter ========================== */ 5679 5680 // variadic-parameter 5681 5682 TemplateTupleParameter::TemplateTupleParameter(Loc loc, Identifier *ident) 5683 : TemplateParameter(loc, ident) 5684 { 5685 this->ident = ident; 5686 } 5687 5688 TemplateTupleParameter *TemplateTupleParameter::isTemplateTupleParameter() 5689 { 5690 return this; 5691 } 5692 5693 TemplateParameter *TemplateTupleParameter::syntaxCopy() 5694 { 5695 return new TemplateTupleParameter(loc, ident); 5696 } 5697 5698 bool TemplateTupleParameter::declareParameter(Scope *sc) 5699 { 5700 TypeIdentifier *ti = new TypeIdentifier(loc, ident); 5701 Declaration *ad = new AliasDeclaration(loc, ident, ti); 5702 return sc->insert(ad) != NULL; 5703 } 5704 5705 bool TemplateTupleParameter::semantic(Scope *, TemplateParameters *) 5706 { 5707 return true; 5708 } 5709 5710 MATCH TemplateTupleParameter::matchArg(Loc, Scope *sc, Objects *tiargs, 5711 size_t i, TemplateParameters *parameters, Objects *dedtypes, 5712 Declaration **psparam) 5713 { 5714 /* The rest of the actual arguments (tiargs[]) form the match 5715 * for the variadic parameter. 5716 */ 5717 assert(i + 1 == dedtypes->dim); // must be the last one 5718 Tuple *ovar; 5719 5720 if (Tuple *u = isTuple((*dedtypes)[i])) 5721 { 5722 // It has already been deduced 5723 ovar = u; 5724 } 5725 else if (i + 1 == tiargs->dim && isTuple((*tiargs)[i])) 5726 ovar = isTuple((*tiargs)[i]); 5727 else 5728 { 5729 ovar = new Tuple(); 5730 //printf("ovar = %p\n", ovar); 5731 if (i < tiargs->dim) 5732 { 5733 //printf("i = %d, tiargs->dim = %d\n", i, tiargs->dim); 5734 ovar->objects.setDim(tiargs->dim - i); 5735 for (size_t j = 0; j < ovar->objects.dim; j++) 5736 ovar->objects[j] = (*tiargs)[i + j]; 5737 } 5738 } 5739 return matchArg(sc, ovar, i, parameters, dedtypes, psparam); 5740 } 5741 5742 MATCH TemplateTupleParameter::matchArg(Scope *, RootObject *oarg, 5743 size_t i, TemplateParameters *, Objects *dedtypes, Declaration **psparam) 5744 { 5745 //printf("TemplateTupleParameter::matchArg('%s')\n", ident->toChars()); 5746 Tuple *ovar = isTuple(oarg); 5747 if (!ovar) 5748 return MATCHnomatch; 5749 if ((*dedtypes)[i]) 5750 { 5751 Tuple *tup = isTuple((*dedtypes)[i]); 5752 if (!tup) 5753 return MATCHnomatch; 5754 if (!match(tup, ovar)) 5755 return MATCHnomatch; 5756 } 5757 (*dedtypes)[i] = ovar; 5758 5759 if (psparam) 5760 *psparam = new TupleDeclaration(loc, ident, &ovar->objects); 5761 return dependent ? MATCHexact : MATCHconvert; 5762 } 5763 5764 5765 void TemplateTupleParameter::print(RootObject *, RootObject *oded) 5766 { 5767 printf(" %s... [", ident->toChars()); 5768 Tuple *v = isTuple(oded); 5769 assert(v); 5770 5771 //printf("|%d| ", v->objects.dim); 5772 for (size_t i = 0; i < v->objects.dim; i++) 5773 { 5774 if (i) 5775 printf(", "); 5776 5777 RootObject *o = v->objects[i]; 5778 5779 Dsymbol *sa = isDsymbol(o); 5780 if (sa) 5781 printf("alias: %s", sa->toChars()); 5782 5783 Type *ta = isType(o); 5784 if (ta) 5785 printf("type: %s", ta->toChars()); 5786 5787 Expression *ea = isExpression(o); 5788 if (ea) 5789 printf("exp: %s", ea->toChars()); 5790 5791 assert(!isTuple(o)); // no nested Tuple arguments 5792 } 5793 5794 printf("]\n"); 5795 } 5796 5797 void *TemplateTupleParameter::dummyArg() 5798 { 5799 return NULL; 5800 } 5801 5802 5803 RootObject *TemplateTupleParameter::specialization() 5804 { 5805 return NULL; 5806 } 5807 5808 RootObject *TemplateTupleParameter::defaultArg(Loc, Scope *) 5809 { 5810 return NULL; 5811 } 5812 5813 bool TemplateTupleParameter::hasDefaultArg() 5814 { 5815 return false; 5816 } 5817 5818 /* ======================== TemplateInstance ================================ */ 5819 5820 TemplateInstance::TemplateInstance(Loc loc, Identifier *ident) 5821 : ScopeDsymbol(NULL) 5822 { 5823 this->loc = loc; 5824 this->name = ident; 5825 this->tiargs = NULL; 5826 this->tempdecl = NULL; 5827 this->inst = NULL; 5828 this->tinst = NULL; 5829 this->tnext = NULL; 5830 this->minst = NULL; 5831 this->deferred = NULL; 5832 this->memberOf = NULL; 5833 this->argsym = NULL; 5834 this->aliasdecl = NULL; 5835 this->semantictiargsdone = false; 5836 this->inuse = 0; 5837 this->nest = 0; 5838 this->havetempdecl = false; 5839 this->enclosing = NULL; 5840 this->gagged = false; 5841 this->hash = 0; 5842 this->fargs = NULL; 5843 } 5844 5845 /***************** 5846 * This constructor is only called when we figured out which function 5847 * template to instantiate. 5848 */ 5849 5850 TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *tiargs) 5851 : ScopeDsymbol(NULL) 5852 { 5853 this->loc = loc; 5854 this->name = td->ident; 5855 this->tiargs = tiargs; 5856 this->tempdecl = td; 5857 this->inst = NULL; 5858 this->tinst = NULL; 5859 this->tnext = NULL; 5860 this->minst = NULL; 5861 this->deferred = NULL; 5862 this->memberOf = NULL; 5863 this->argsym = NULL; 5864 this->aliasdecl = NULL; 5865 this->semantictiargsdone = true; 5866 this->inuse = 0; 5867 this->nest = 0; 5868 this->havetempdecl = true; 5869 this->enclosing = NULL; 5870 this->gagged = false; 5871 this->hash = 0; 5872 this->fargs = NULL; 5873 5874 assert(tempdecl->_scope); 5875 } 5876 5877 5878 Objects *TemplateInstance::arraySyntaxCopy(Objects *objs) 5879 { 5880 Objects *a = NULL; 5881 if (objs) 5882 { 5883 a = new Objects(); 5884 a->setDim(objs->dim); 5885 for (size_t i = 0; i < objs->dim; i++) 5886 (*a)[i] = objectSyntaxCopy((*objs)[i]); 5887 } 5888 return a; 5889 } 5890 5891 Dsymbol *TemplateInstance::syntaxCopy(Dsymbol *s) 5892 { 5893 TemplateInstance *ti = 5894 s ? (TemplateInstance *)s 5895 : new TemplateInstance(loc, name); 5896 ti->tiargs = arraySyntaxCopy(tiargs); 5897 TemplateDeclaration *td; 5898 if (inst && tempdecl && (td = tempdecl->isTemplateDeclaration()) != NULL) 5899 td->ScopeDsymbol::syntaxCopy(ti); 5900 else 5901 ScopeDsymbol::syntaxCopy(ti); 5902 return ti; 5903 } 5904 5905 void TemplateInstance::semantic(Scope *sc) 5906 { 5907 semantic(sc, NULL); 5908 } 5909 5910 void TemplateInstance::expandMembers(Scope *sc2) 5911 { 5912 for (size_t i = 0; i < members->dim; i++) 5913 { 5914 Dsymbol *s = (*members)[i]; 5915 s->setScope(sc2); 5916 } 5917 5918 for (size_t i = 0; i < members->dim; i++) 5919 { 5920 Dsymbol *s = (*members)[i]; 5921 s->importAll(sc2); 5922 } 5923 5924 for (size_t i = 0; i < members->dim; i++) 5925 { 5926 Dsymbol *s = (*members)[i]; 5927 //printf("\t[%d] semantic on '%s' %p kind %s in '%s'\n", i, s->toChars(), s, s->kind(), this->toChars()); 5928 //printf("test: enclosing = %d, sc2->parent = %s\n", enclosing, sc2->parent->toChars()); 5929 // if (enclosing) 5930 // s->parent = sc->parent; 5931 //printf("test3: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars()); 5932 s->semantic(sc2); 5933 //printf("test4: enclosing = %d, s->parent = %s\n", enclosing, s->parent->toChars()); 5934 Module::runDeferredSemantic(); 5935 } 5936 } 5937 5938 void TemplateInstance::tryExpandMembers(Scope *sc2) 5939 { 5940 static int nest; 5941 // extracted to a function to allow windows SEH to work without destructors in the same function 5942 //printf("%d\n", nest); 5943 if (++nest > global.recursionLimit) 5944 { 5945 global.gag = 0; // ensure error message gets printed 5946 error("recursive expansion exceeded allowed nesting limit"); 5947 fatal(); 5948 } 5949 5950 expandMembers(sc2); 5951 5952 nest--; 5953 } 5954 5955 void TemplateInstance::trySemantic3(Scope *sc2) 5956 { 5957 // extracted to a function to allow windows SEH to work without destructors in the same function 5958 static int nest; 5959 //printf("%d\n", nest); 5960 if (++nest > global.recursionLimit) 5961 { 5962 global.gag = 0; // ensure error message gets printed 5963 error("recursive expansion exceeded allowed nesting limit"); 5964 fatal(); 5965 } 5966 semantic3(sc2); 5967 5968 --nest; 5969 } 5970 5971 void TemplateInstance::semantic(Scope *sc, Expressions *fargs) 5972 { 5973 //printf("[%s] TemplateInstance::semantic('%s', this=%p, gag = %d, sc = %p)\n", loc.toChars(), toChars(), this, global.gag, sc); 5974 if (inst) // if semantic() was already run 5975 { 5976 return; 5977 } 5978 if (semanticRun != PASSinit) 5979 { 5980 Ungag ungag(global.gag); 5981 if (!gagged) 5982 global.gag = 0; 5983 error(loc, "recursive template expansion"); 5984 if (gagged) 5985 semanticRun = PASSinit; 5986 else 5987 inst = this; 5988 errors = true; 5989 return; 5990 } 5991 5992 // Get the enclosing template instance from the scope tinst 5993 tinst = sc->tinst; 5994 5995 // Get the instantiating module from the scope minst 5996 minst = sc->minst; 5997 // Bugzilla 10920: If the enclosing function is non-root symbol, 5998 // this instance should be speculative. 5999 if (!tinst && sc->func && sc->func->inNonRoot()) 6000 { 6001 minst = NULL; 6002 } 6003 6004 gagged = (global.gag > 0); 6005 6006 semanticRun = PASSsemantic; 6007 6008 /* Find template declaration first, 6009 * then run semantic on each argument (place results in tiargs[]), 6010 * last find most specialized template from overload list/set. 6011 */ 6012 if (!findTempDecl(sc, NULL) || 6013 !semanticTiargs(sc) || 6014 !findBestMatch(sc, fargs)) 6015 { 6016 Lerror: 6017 if (gagged) 6018 { 6019 // Bugzilla 13220: Rollback status for later semantic re-running. 6020 semanticRun = PASSinit; 6021 } 6022 else 6023 inst = this; 6024 errors = true; 6025 return; 6026 } 6027 TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration(); 6028 assert(tempdecl); 6029 6030 // If tempdecl is a mixin, disallow it 6031 if (tempdecl->ismixin) 6032 { 6033 error("mixin templates are not regular templates"); 6034 goto Lerror; 6035 } 6036 6037 hasNestedArgs(tiargs, tempdecl->isstatic); 6038 if (errors) 6039 goto Lerror; 6040 6041 /* See if there is an existing TemplateInstantiation that already 6042 * implements the typeargs. If so, just refer to that one instead. 6043 */ 6044 inst = tempdecl->findExistingInstance(this, fargs); 6045 TemplateInstance *errinst = NULL; 6046 if (!inst) 6047 { 6048 // So, we need to implement 'this' instance. 6049 } 6050 else if (inst->gagged && !gagged && inst->errors) 6051 { 6052 // If the first instantiation had failed, re-run semantic, 6053 // so that error messages are shown. 6054 errinst = inst; 6055 } 6056 else 6057 { 6058 // It's a match 6059 parent = inst->parent; 6060 errors = inst->errors; 6061 6062 // If both this and the previous instantiation were gagged, 6063 // use the number of errors that happened last time. 6064 global.errors += errors; 6065 global.gaggedErrors += errors; 6066 6067 // If the first instantiation was gagged, but this is not: 6068 if (inst->gagged) 6069 { 6070 // It had succeeded, mark it is a non-gagged instantiation, 6071 // and reuse it. 6072 inst->gagged = gagged; 6073 } 6074 6075 this->tnext = inst->tnext; 6076 inst->tnext = this; 6077 6078 /* A module can have explicit template instance and its alias 6079 * in module scope (e,g, `alias Base64 = Base64Impl!('+', '/');`). 6080 * If the first instantiation 'inst' had happened in non-root module, 6081 * compiler can assume that its instantiated code would be included 6082 * in the separately compiled obj/lib file (e.g. phobos.lib). 6083 * 6084 * However, if 'this' second instantiation happened in root module, 6085 * compiler might need to invoke its codegen (Bugzilla 2500 & 2644). 6086 * But whole import graph is not determined until all semantic pass finished, 6087 * so 'inst' should conservatively finish the semantic3 pass for the codegen. 6088 */ 6089 if (minst && minst->isRoot() && !(inst->minst && inst->minst->isRoot())) 6090 { 6091 /* Swap the position of 'inst' and 'this' in the instantiation graph. 6092 * Then, the primary instance `inst` will be changed to a root instance, 6093 * along with all members of `inst` having their scopes updated. 6094 * 6095 * Before: 6096 * non-root -> A!() -> B!()[inst] -> C!() { members[non-root] } 6097 * | 6098 * root -> D!() -> B!()[this] 6099 * 6100 * After: 6101 * non-root -> A!() -> B!()[this] 6102 * | 6103 * root -> D!() -> B!()[inst] -> C!() { members[root] } 6104 */ 6105 Module *mi = minst; 6106 TemplateInstance *ti = tinst; 6107 minst = inst->minst; 6108 tinst = inst->tinst; 6109 inst->minst = mi; 6110 inst->tinst = ti; 6111 6112 /* https://issues.dlang.org/show_bug.cgi?id=21299 6113 `minst` has been updated on the primary instance `inst` so it is 6114 now coming from a root module, however all Dsymbol `inst.members` 6115 of the instance still have their `_scope.minst` pointing at the 6116 original non-root module. We must now propagate `minst` to all 6117 members so that forward referenced dependencies that get 6118 instantiated will also be appended to the root module, otherwise 6119 there will be undefined references at link-time. */ 6120 class InstMemberWalker : public Visitor 6121 { 6122 public: 6123 TemplateInstance *inst; 6124 6125 InstMemberWalker(TemplateInstance *inst) 6126 : inst(inst) { } 6127 6128 void visit(Dsymbol *d) 6129 { 6130 if (d->_scope) 6131 d->_scope->minst = inst->minst; 6132 } 6133 6134 void visit(ScopeDsymbol *sds) 6135 { 6136 if (!sds->members) 6137 return; 6138 for (size_t i = 0; i < sds->members->dim; i++) 6139 { 6140 Dsymbol *s = (*sds->members)[i]; 6141 s->accept(this); 6142 } 6143 visit((Dsymbol *)sds); 6144 } 6145 6146 void visit(AttribDeclaration *ad) 6147 { 6148 Dsymbols *d = ad->include(NULL, NULL); 6149 if (!d) 6150 return; 6151 for (size_t i = 0; i < d->dim; i++) 6152 { 6153 Dsymbol *s = (*d)[i]; 6154 s->accept(this); 6155 } 6156 visit((Dsymbol *)ad); 6157 } 6158 6159 void visit(ConditionalDeclaration *cd) 6160 { 6161 if (cd->condition->inc) 6162 visit((AttribDeclaration *)cd); 6163 else 6164 visit((Dsymbol *)cd); 6165 } 6166 }; 6167 InstMemberWalker v(inst); 6168 inst->accept(&v); 6169 6170 if (minst) // if inst was not speculative 6171 { 6172 /* Add 'inst' once again to the root module members[], then the 6173 * instance members will get codegen chances. 6174 */ 6175 inst->appendToModuleMember(); 6176 } 6177 } 6178 6179 return; 6180 } 6181 unsigned errorsave = global.errors; 6182 6183 inst = this; 6184 parent = enclosing ? enclosing : tempdecl->parent; 6185 //printf("parent = '%s'\n", parent->kind()); 6186 6187 TemplateInstance *tempdecl_instance_idx = tempdecl->addInstance(this); 6188 6189 //getIdent(); 6190 6191 // Store the place we added it to in target_symbol_list(_idx) so we can 6192 // remove it later if we encounter an error. 6193 Dsymbols *target_symbol_list = appendToModuleMember(); 6194 size_t target_symbol_list_idx = target_symbol_list ? target_symbol_list->dim - 1 : 0; 6195 6196 // Copy the syntax trees from the TemplateDeclaration 6197 members = Dsymbol::arraySyntaxCopy(tempdecl->members); 6198 6199 // resolve TemplateThisParameter 6200 for (size_t i = 0; i < tempdecl->parameters->dim; i++) 6201 { 6202 if ((*tempdecl->parameters)[i]->isTemplateThisParameter() == NULL) 6203 continue; 6204 Type *t = isType((*tiargs)[i]); 6205 assert(t); 6206 if (StorageClass stc = ModToStc(t->mod)) 6207 { 6208 //printf("t = %s, stc = x%llx\n", t->toChars(), stc); 6209 Dsymbols *s = new Dsymbols(); 6210 s->push(new StorageClassDeclaration(stc, members)); 6211 members = s; 6212 } 6213 break; 6214 } 6215 6216 // Create our own scope for the template parameters 6217 Scope *scope = tempdecl->_scope; 6218 if (tempdecl->semanticRun == PASSinit) 6219 { 6220 error("template instantiation %s forward references template declaration %s", toChars(), tempdecl->toChars()); 6221 return; 6222 } 6223 6224 argsym = new ScopeDsymbol(); 6225 argsym->parent = scope->parent; 6226 scope = scope->push(argsym); 6227 scope->tinst = this; 6228 scope->minst = minst; 6229 //scope->stc = 0; 6230 6231 // Declare each template parameter as an alias for the argument type 6232 Scope *paramscope = scope->push(); 6233 paramscope->stc = 0; 6234 paramscope->protection = Prot(PROTpublic); // Bugzilla 14169: template parameters should be public 6235 declareParameters(paramscope); 6236 paramscope->pop(); 6237 6238 // Add members of template instance to template instance symbol table 6239 // parent = scope->scopesym; 6240 symtab = new DsymbolTable(); 6241 for (size_t i = 0; i < members->dim; i++) 6242 { 6243 Dsymbol *s = (*members)[i]; 6244 s->addMember(scope, this); 6245 } 6246 6247 /* See if there is only one member of template instance, and that 6248 * member has the same name as the template instance. 6249 * If so, this template instance becomes an alias for that member. 6250 */ 6251 //printf("members->dim = %d\n", members->dim); 6252 if (members->dim) 6253 { 6254 Dsymbol *s; 6255 if (Dsymbol::oneMembers(members, &s, tempdecl->ident) && s) 6256 { 6257 //printf("tempdecl->ident = %s, s = '%s'\n", tempdecl->ident->toChars(), s->kind(), s->toPrettyChars()); 6258 //printf("setting aliasdecl\n"); 6259 aliasdecl = s; 6260 } 6261 } 6262 6263 /* If function template declaration 6264 */ 6265 if (fargs && aliasdecl) 6266 { 6267 FuncDeclaration *fd = aliasdecl->isFuncDeclaration(); 6268 if (fd) 6269 { 6270 /* Transmit fargs to type so that TypeFunction::semantic() can 6271 * resolve any "auto ref" storage classes. 6272 */ 6273 TypeFunction *tf = (TypeFunction *)fd->type; 6274 if (tf && tf->ty == Tfunction) 6275 tf->fargs = fargs; 6276 } 6277 } 6278 6279 // Do semantic() analysis on template instance members 6280 Scope *sc2; 6281 sc2 = scope->push(this); 6282 //printf("enclosing = %d, sc->parent = %s\n", enclosing, sc->parent->toChars()); 6283 sc2->parent = this; 6284 sc2->tinst = this; 6285 sc2->minst = minst; 6286 6287 tryExpandMembers(sc2); 6288 6289 semanticRun = PASSsemanticdone; 6290 6291 /* ConditionalDeclaration may introduce eponymous declaration, 6292 * so we should find it once again after semantic. 6293 */ 6294 if (members->dim) 6295 { 6296 Dsymbol *s; 6297 if (Dsymbol::oneMembers(members, &s, tempdecl->ident) && s) 6298 { 6299 if (!aliasdecl || aliasdecl != s) 6300 { 6301 //printf("tempdecl->ident = %s, s = '%s'\n", tempdecl->ident->toChars(), s->kind(), s->toPrettyChars()); 6302 //printf("setting aliasdecl 2\n"); 6303 aliasdecl = s; 6304 } 6305 } 6306 } 6307 6308 if (global.errors != errorsave) 6309 goto Laftersemantic; 6310 6311 /* If any of the instantiation members didn't get semantic() run 6312 * on them due to forward references, we cannot run semantic2() 6313 * or semantic3() yet. 6314 */ 6315 { 6316 bool found_deferred_ad = false; 6317 for (size_t i = 0; i < Module::deferred.dim; i++) 6318 { 6319 Dsymbol *sd = Module::deferred[i]; 6320 AggregateDeclaration *ad = sd->isAggregateDeclaration(); 6321 if (ad && ad->parent && ad->parent->isTemplateInstance()) 6322 { 6323 //printf("deferred template aggregate: %s %s\n", 6324 // sd->parent->toChars(), sd->toChars()); 6325 found_deferred_ad = true; 6326 if (ad->parent == this) 6327 { 6328 ad->deferred = this; 6329 break; 6330 } 6331 } 6332 } 6333 if (found_deferred_ad || Module::deferred.dim) 6334 goto Laftersemantic; 6335 } 6336 6337 /* The problem is when to parse the initializer for a variable. 6338 * Perhaps VarDeclaration::semantic() should do it like it does 6339 * for initializers inside a function. 6340 */ 6341 //if (sc->parent->isFuncDeclaration()) 6342 { 6343 /* BUG 782: this has problems if the classes this depends on 6344 * are forward referenced. Find a way to defer semantic() 6345 * on this template. 6346 */ 6347 semantic2(sc2); 6348 } 6349 if (global.errors != errorsave) 6350 goto Laftersemantic; 6351 6352 if ((sc->func || (sc->flags & SCOPEfullinst)) && !tinst) 6353 { 6354 /* If a template is instantiated inside function, the whole instantiation 6355 * should be done at that position. But, immediate running semantic3 of 6356 * dependent templates may cause unresolved forward reference (Bugzilla 9050). 6357 * To avoid the issue, don't run semantic3 until semantic and semantic2 done. 6358 */ 6359 TemplateInstances deferred; 6360 this->deferred = &deferred; 6361 6362 //printf("Run semantic3 on %s\n", toChars()); 6363 trySemantic3(sc2); 6364 6365 for (size_t i = 0; i < deferred.dim; i++) 6366 { 6367 //printf("+ run deferred semantic3 on %s\n", deferred[i]->toChars()); 6368 deferred[i]->semantic3(NULL); 6369 } 6370 6371 this->deferred = NULL; 6372 } 6373 else if (tinst) 6374 { 6375 bool doSemantic3 = false; 6376 if (sc->func && aliasdecl && aliasdecl->toAlias()->isFuncDeclaration()) 6377 { 6378 /* Template function instantiation should run semantic3 immediately 6379 * for attribute inference. 6380 */ 6381 trySemantic3(sc2); 6382 } 6383 else if (sc->func) 6384 { 6385 /* A lambda function in template arguments might capture the 6386 * instantiated scope context. For the correct context inference, 6387 * all instantiated functions should run the semantic3 immediately. 6388 * See also compilable/test14973.d 6389 */ 6390 for (size_t i = 0; i < tdtypes.dim; i++) 6391 { 6392 RootObject *oarg = tdtypes[i]; 6393 Dsymbol *s = getDsymbol(oarg); 6394 if (!s) 6395 continue; 6396 6397 if (TemplateDeclaration *td = s->isTemplateDeclaration()) 6398 { 6399 if (!td->literal) 6400 continue; 6401 assert(td->members && td->members->dim == 1); 6402 s = (*td->members)[0]; 6403 } 6404 if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration()) 6405 { 6406 if (fld->tok == TOKreserved) 6407 { 6408 doSemantic3 = true; 6409 break; 6410 } 6411 } 6412 } 6413 //printf("[%s] %s doSemantic3 = %d\n", loc.toChars(), toChars(), doSemantic3); 6414 } 6415 if (doSemantic3) 6416 trySemantic3(sc2); 6417 6418 TemplateInstance *ti = tinst; 6419 int nest = 0; 6420 while (ti && !ti->deferred && ti->tinst) 6421 { 6422 ti = ti->tinst; 6423 if (++nest > global.recursionLimit) 6424 { 6425 global.gag = 0; // ensure error message gets printed 6426 error("recursive expansion"); 6427 fatal(); 6428 } 6429 } 6430 if (ti && ti->deferred) 6431 { 6432 //printf("deferred semantic3 of %p %s, ti = %s, ti->deferred = %p\n", this, toChars(), ti->toChars()); 6433 for (size_t i = 0; ; i++) 6434 { 6435 if (i == ti->deferred->dim) 6436 { 6437 ti->deferred->push(this); 6438 break; 6439 } 6440 if ((*ti->deferred)[i] == this) 6441 break; 6442 } 6443 } 6444 } 6445 6446 if (aliasdecl) 6447 { 6448 /* Bugzilla 13816: AliasDeclaration tries to resolve forward reference 6449 * twice (See inuse check in AliasDeclaration::toAlias()). It's 6450 * necessary to resolve mutual references of instantiated symbols, but 6451 * it will left a true recursive alias in tuple declaration - an 6452 * AliasDeclaration A refers TupleDeclaration B, and B contains A 6453 * in its elements. To correctly make it an error, we strictly need to 6454 * resolve the alias of eponymous member. 6455 */ 6456 aliasdecl = aliasdecl->toAlias2(); 6457 } 6458 6459 Laftersemantic: 6460 sc2->pop(); 6461 6462 scope->pop(); 6463 6464 // Give additional context info if error occurred during instantiation 6465 if (global.errors != errorsave) 6466 { 6467 if (!errors) 6468 { 6469 if (!tempdecl->literal) 6470 error(loc, "error instantiating"); 6471 if (tinst) 6472 tinst->printInstantiationTrace(); 6473 } 6474 errors = true; 6475 if (gagged) 6476 { 6477 // Errors are gagged, so remove the template instance from the 6478 // instance/symbol lists we added it to and reset our state to 6479 // finish clean and so we can try to instantiate it again later 6480 // (see bugzilla 4302 and 6602). 6481 tempdecl->removeInstance(tempdecl_instance_idx); 6482 if (target_symbol_list) 6483 { 6484 // Because we added 'this' in the last position above, we 6485 // should be able to remove it without messing other indices up. 6486 assert((*target_symbol_list)[target_symbol_list_idx] == this); 6487 target_symbol_list->remove(target_symbol_list_idx); 6488 memberOf = NULL; // no longer a member 6489 } 6490 semanticRun = PASSinit; 6491 inst = NULL; 6492 symtab = NULL; 6493 } 6494 } 6495 else if (errinst) 6496 { 6497 /* Bugzilla 14541: If the previous gagged instance had failed by 6498 * circular references, currrent "error reproduction instantiation" 6499 * might succeed, because of the difference of instantiated context. 6500 * On such case, the cached error instance needs to be overridden by the 6501 * succeeded instance. 6502 */ 6503 //printf("replaceInstance()\n"); 6504 TemplateInstances *tinstances = (TemplateInstances *)dmd_aaGetRvalue((AA *)tempdecl->instances, (void *)hash); 6505 assert(tinstances); 6506 for (size_t i = 0; i < tinstances->dim; i++) 6507 { 6508 TemplateInstance *ti = (*tinstances)[i]; 6509 if (ti == errinst) 6510 { 6511 (*tinstances)[i] = this; // override 6512 break; 6513 } 6514 } 6515 } 6516 } 6517 6518 6519 /********************************************** 6520 * Find template declaration corresponding to template instance. 6521 * 6522 * Returns: 6523 * false if finding fails. 6524 * Note: 6525 * This function is reentrant against error occurrence. If returns false, 6526 * any members of this object won't be modified, and repetition call will 6527 * reproduce same error. 6528 */ 6529 6530 bool TemplateInstance::findTempDecl(Scope *sc, WithScopeSymbol **pwithsym) 6531 { 6532 if (pwithsym) 6533 *pwithsym = NULL; 6534 6535 if (havetempdecl) 6536 return true; 6537 6538 //printf("TemplateInstance::findTempDecl() %s\n", toChars()); 6539 if (!tempdecl) 6540 { 6541 /* Given: 6542 * foo!( ... ) 6543 * figure out which TemplateDeclaration foo refers to. 6544 */ 6545 Identifier *id = name; 6546 Dsymbol *scopesym; 6547 Dsymbol *s = sc->search(loc, id, &scopesym); 6548 if (!s) 6549 { 6550 s = sc->search_correct(id); 6551 if (s) 6552 error("template '%s' is not defined, did you mean %s?", id->toChars(), s->toChars()); 6553 else 6554 error("template '%s' is not defined", id->toChars()); 6555 return false; 6556 } 6557 6558 if (pwithsym) 6559 *pwithsym = scopesym->isWithScopeSymbol(); 6560 6561 /* We might have found an alias within a template when 6562 * we really want the template. 6563 */ 6564 TemplateInstance *ti; 6565 if (s->parent && 6566 (ti = s->parent->isTemplateInstance()) != NULL) 6567 { 6568 if (ti->tempdecl && ti->tempdecl->ident == id) 6569 { 6570 /* This is so that one can refer to the enclosing 6571 * template, even if it has the same name as a member 6572 * of the template, if it has a !(arguments) 6573 */ 6574 TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration(); 6575 assert(td); 6576 if (td->overroot) // if not start of overloaded list of TemplateDeclaration's 6577 td = td->overroot; // then get the start 6578 s = td; 6579 } 6580 } 6581 6582 if (!updateTempDecl(sc, s)) 6583 { 6584 return false; 6585 } 6586 } 6587 assert(tempdecl); 6588 6589 struct ParamFwdTi 6590 { 6591 static int fp(void *param, Dsymbol *s) 6592 { 6593 TemplateDeclaration *td = s->isTemplateDeclaration(); 6594 if (!td) 6595 return 0; 6596 6597 TemplateInstance *ti = (TemplateInstance *)param; 6598 if (td->semanticRun == PASSinit) 6599 { 6600 if (td->_scope) 6601 { 6602 // Try to fix forward reference. Ungag errors while doing so. 6603 Ungag ungag = td->ungagSpeculative(); 6604 td->semantic(td->_scope); 6605 } 6606 if (td->semanticRun == PASSinit) 6607 { 6608 ti->error("%s forward references template declaration %s", ti->toChars(), td->toChars()); 6609 return 1; 6610 } 6611 } 6612 return 0; 6613 } 6614 }; 6615 // Look for forward references 6616 OverloadSet *tovers = tempdecl->isOverloadSet(); 6617 size_t overs_dim = tovers ? tovers->a.dim : 1; 6618 for (size_t oi = 0; oi < overs_dim; oi++) 6619 { 6620 if (overloadApply(tovers ? tovers->a[oi] : tempdecl, (void *)this, &ParamFwdTi::fp)) 6621 return false; 6622 } 6623 return true; 6624 } 6625 6626 /********************************************** 6627 * Confirm s is a valid template, then store it. 6628 * Input: 6629 * sc 6630 * s candidate symbol of template. It may be: 6631 * TemplateDeclaration 6632 * FuncDeclaration with findTemplateDeclRoot() != NULL 6633 * OverloadSet which contains candidates 6634 * Returns: 6635 * true if updating succeeds. 6636 */ 6637 6638 bool TemplateInstance::updateTempDecl(Scope *sc, Dsymbol *s) 6639 { 6640 if (s) 6641 { 6642 Identifier *id = name; 6643 s = s->toAlias(); 6644 6645 /* If an OverloadSet, look for a unique member that is a template declaration 6646 */ 6647 OverloadSet *os = s->isOverloadSet(); 6648 if (os) 6649 { 6650 s = NULL; 6651 for (size_t i = 0; i < os->a.dim; i++) 6652 { 6653 Dsymbol *s2 = os->a[i]; 6654 if (FuncDeclaration *f = s2->isFuncDeclaration()) 6655 s2 = f->findTemplateDeclRoot(); 6656 else 6657 s2 = s2->isTemplateDeclaration(); 6658 if (s2) 6659 { 6660 if (s) 6661 { 6662 tempdecl = os; 6663 return true; 6664 } 6665 s = s2; 6666 } 6667 } 6668 if (!s) 6669 { 6670 error("template '%s' is not defined", id->toChars()); 6671 return false; 6672 } 6673 } 6674 6675 OverDeclaration *od = s->isOverDeclaration(); 6676 if (od) 6677 { 6678 tempdecl = od; // TODO: more strict check 6679 return true; 6680 } 6681 6682 /* It should be a TemplateDeclaration, not some other symbol 6683 */ 6684 if (FuncDeclaration *f = s->isFuncDeclaration()) 6685 tempdecl = f->findTemplateDeclRoot(); 6686 else 6687 tempdecl = s->isTemplateDeclaration(); 6688 if (!tempdecl) 6689 { 6690 if (!s->parent && global.errors) 6691 return false; 6692 if (!s->parent && s->getType()) 6693 { 6694 Dsymbol *s2 = s->getType()->toDsymbol(sc); 6695 if (!s2) 6696 { 6697 error("%s is not a template declaration, it is a %s", id->toChars(), s->kind()); 6698 return false; 6699 } 6700 s = s2; 6701 } 6702 //assert(s->parent); 6703 TemplateInstance *ti = s->parent ? s->parent->isTemplateInstance() : NULL; 6704 if (ti && 6705 (ti->name == s->ident || 6706 ti->toAlias()->ident == s->ident) 6707 && 6708 ti->tempdecl) 6709 { 6710 /* This is so that one can refer to the enclosing 6711 * template, even if it has the same name as a member 6712 * of the template, if it has a !(arguments) 6713 */ 6714 TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration(); 6715 assert(td); 6716 if (td->overroot) // if not start of overloaded list of TemplateDeclaration's 6717 td = td->overroot; // then get the start 6718 tempdecl = td; 6719 } 6720 else 6721 { 6722 error("%s is not a template declaration, it is a %s", id->toChars(), s->kind()); 6723 return false; 6724 } 6725 } 6726 } 6727 return (tempdecl != NULL); 6728 } 6729 6730 /********************************** 6731 * Run semantic on the elements of tiargs. 6732 * Input: 6733 * sc 6734 * Returns: 6735 * false if one or more arguments have errors. 6736 * Note: 6737 * This function is reentrant against error occurrence. If returns false, 6738 * all elements of tiargs won't be modified. 6739 */ 6740 6741 bool TemplateInstance::semanticTiargs(Scope *sc) 6742 { 6743 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars()); 6744 if (semantictiargsdone) 6745 return true; 6746 if (semanticTiargs(loc, sc, tiargs, 0)) 6747 { 6748 // cache the result iff semantic analysis succeeded entirely 6749 semantictiargsdone = 1; 6750 return true; 6751 } 6752 return false; 6753 } 6754 6755 /********************************** 6756 * Run semantic of tiargs as arguments of template. 6757 * Input: 6758 * loc 6759 * sc 6760 * tiargs array of template arguments 6761 * flags 1: replace const variables with their initializers 6762 * 2: don't devolve Parameter to Type 6763 * Returns: 6764 * false if one or more arguments have errors. 6765 */ 6766 6767 bool TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags) 6768 { 6769 // Run semantic on each argument, place results in tiargs[] 6770 //printf("+TemplateInstance::semanticTiargs()\n"); 6771 if (!tiargs) 6772 return true; 6773 bool err = false; 6774 for (size_t j = 0; j < tiargs->dim; j++) 6775 { 6776 RootObject *o = (*tiargs)[j]; 6777 Type *ta = isType(o); 6778 Expression *ea = isExpression(o); 6779 Dsymbol *sa = isDsymbol(o); 6780 6781 //printf("1: (*tiargs)[%d] = %p, s=%p, v=%p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta); 6782 if (ta) 6783 { 6784 //printf("type %s\n", ta->toChars()); 6785 // It might really be an Expression or an Alias 6786 ta->resolve(loc, sc, &ea, &ta, &sa); 6787 if (ea) goto Lexpr; 6788 if (sa) goto Ldsym; 6789 if (ta == NULL) 6790 { 6791 assert(global.errors); 6792 ta = Type::terror; 6793 } 6794 6795 Ltype: 6796 if (ta->ty == Ttuple) 6797 { 6798 // Expand tuple 6799 TypeTuple *tt = (TypeTuple *)ta; 6800 size_t dim = tt->arguments->dim; 6801 tiargs->remove(j); 6802 if (dim) 6803 { 6804 tiargs->reserve(dim); 6805 for (size_t i = 0; i < dim; i++) 6806 { 6807 Parameter *arg = (*tt->arguments)[i]; 6808 if (flags & 2 && arg->ident) 6809 tiargs->insert(j + i, arg); 6810 else 6811 tiargs->insert(j + i, arg->type); 6812 } 6813 } 6814 j--; 6815 continue; 6816 } 6817 if (ta->ty == Terror) 6818 { 6819 err = true; 6820 continue; 6821 } 6822 (*tiargs)[j] = ta->merge2(); 6823 } 6824 else if (ea) 6825 { 6826 Lexpr: 6827 //printf("+[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars()); 6828 if (flags & 1) // only used by __traits 6829 { 6830 ea = ::semantic(ea, sc); 6831 6832 // must not interpret the args, excepting template parameters 6833 if (ea->op != TOKvar || 6834 (((VarExp *)ea)->var->storage_class & STCtemplateparameter)) 6835 { 6836 ea = ea->optimize(WANTvalue); 6837 } 6838 } 6839 else 6840 { 6841 sc = sc->startCTFE(); 6842 ea = ::semantic(ea, sc); 6843 sc = sc->endCTFE(); 6844 6845 if (ea->op == TOKvar) 6846 { 6847 /* This test is to skip substituting a const var with 6848 * its initializer. The problem is the initializer won't 6849 * match with an 'alias' parameter. Instead, do the 6850 * const substitution in TemplateValueParameter::matchArg(). 6851 */ 6852 } 6853 else if (definitelyValueParameter(ea)) 6854 { 6855 if (ea->checkValue()) // check void expression 6856 ea = new ErrorExp(); 6857 unsigned int olderrs = global.errors; 6858 ea = ea->ctfeInterpret(); 6859 if (global.errors != olderrs) 6860 ea = new ErrorExp(); 6861 } 6862 } 6863 //printf("-[%d] ea = %s %s\n", j, Token::toChars(ea->op), ea->toChars()); 6864 if (ea->op == TOKtuple) 6865 { 6866 // Expand tuple 6867 TupleExp *te = (TupleExp *)ea; 6868 size_t dim = te->exps->dim; 6869 tiargs->remove(j); 6870 if (dim) 6871 { 6872 tiargs->reserve(dim); 6873 for (size_t i = 0; i < dim; i++) 6874 tiargs->insert(j + i, (*te->exps)[i]); 6875 } 6876 j--; 6877 continue; 6878 } 6879 if (ea->op == TOKerror) 6880 { 6881 err = true; 6882 continue; 6883 } 6884 (*tiargs)[j] = ea; 6885 6886 if (ea->op == TOKtype) 6887 { 6888 ta = ea->type; 6889 goto Ltype; 6890 } 6891 if (ea->op == TOKscope) 6892 { 6893 sa = ((ScopeExp *)ea)->sds; 6894 goto Ldsym; 6895 } 6896 if (ea->op == TOKfunction) 6897 { 6898 FuncExp *fe = (FuncExp *)ea; 6899 /* A function literal, that is passed to template and 6900 * already semanticed as function pointer, never requires 6901 * outer frame. So convert it to global function is valid. 6902 */ 6903 if (fe->fd->tok == TOKreserved && fe->type->ty == Tpointer) 6904 { 6905 // change to non-nested 6906 fe->fd->tok = TOKfunction; 6907 fe->fd->vthis = NULL; 6908 } 6909 else if (fe->td) 6910 { 6911 /* If template argument is a template lambda, 6912 * get template declaration itself. */ 6913 //sa = fe->td; 6914 //goto Ldsym; 6915 } 6916 } 6917 if (ea->op == TOKdotvar) 6918 { 6919 // translate expression to dsymbol. 6920 sa = ((DotVarExp *)ea)->var; 6921 goto Ldsym; 6922 } 6923 if (ea->op == TOKtemplate) 6924 { 6925 sa = ((TemplateExp *)ea)->td; 6926 goto Ldsym; 6927 } 6928 if (ea->op == TOKdottd) 6929 { 6930 // translate expression to dsymbol. 6931 sa = ((DotTemplateExp *)ea)->td; 6932 goto Ldsym; 6933 } 6934 } 6935 else if (sa) 6936 { 6937 Ldsym: 6938 //printf("dsym %s %s\n", sa->kind(), sa->toChars()); 6939 if (sa->errors) 6940 { 6941 err = true; 6942 continue; 6943 } 6944 6945 TupleDeclaration *d = sa->toAlias()->isTupleDeclaration(); 6946 if (d) 6947 { 6948 // Expand tuple 6949 tiargs->remove(j); 6950 tiargs->insert(j, d->objects); 6951 j--; 6952 continue; 6953 } 6954 if (FuncAliasDeclaration *fa = sa->isFuncAliasDeclaration()) 6955 { 6956 FuncDeclaration *f = fa->toAliasFunc(); 6957 if (!fa->hasOverloads && f->isUnique()) 6958 { 6959 // Strip FuncAlias only when the aliased function 6960 // does not have any overloads. 6961 sa = f; 6962 } 6963 } 6964 (*tiargs)[j] = sa; 6965 6966 TemplateDeclaration *td = sa->isTemplateDeclaration(); 6967 if (td && td->semanticRun == PASSinit && td->literal) 6968 { 6969 td->semantic(sc); 6970 } 6971 FuncDeclaration *fd = sa->isFuncDeclaration(); 6972 if (fd) 6973 fd->functionSemantic(); 6974 } 6975 else if (isParameter(o)) 6976 { 6977 } 6978 else 6979 { 6980 assert(0); 6981 } 6982 //printf("1: (*tiargs)[%d] = %p\n", j, (*tiargs)[j]); 6983 } 6984 return !err; 6985 } 6986 6987 bool TemplateInstance::findBestMatch(Scope *sc, Expressions *fargs) 6988 { 6989 if (havetempdecl) 6990 { 6991 TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration(); 6992 assert(tempdecl); 6993 assert(tempdecl->_scope); 6994 // Deduce tdtypes 6995 tdtypes.setDim(tempdecl->parameters->dim); 6996 if (!tempdecl->matchWithInstance(sc, this, &tdtypes, fargs, 2)) 6997 { 6998 error("incompatible arguments for template instantiation"); 6999 return false; 7000 } 7001 // TODO: Normalizing tiargs for bugzilla 7469 is necessary? 7002 return true; 7003 } 7004 7005 unsigned errs = global.errors; 7006 7007 struct ParamBest 7008 { 7009 // context 7010 Scope *sc; 7011 TemplateInstance *ti; 7012 Objects dedtypes; 7013 // result 7014 TemplateDeclaration *td_best; 7015 TemplateDeclaration *td_ambig; 7016 MATCH m_best; 7017 7018 static int fp(void *param, Dsymbol *s) 7019 { 7020 return ((ParamBest *)param)->fp(s); 7021 } 7022 int fp(Dsymbol *s) 7023 { 7024 TemplateDeclaration *td = s->isTemplateDeclaration(); 7025 if (!td) 7026 return 0; 7027 7028 if (td == td_best) // skip duplicates 7029 return 0; 7030 7031 //printf("td = %s\n", td->toPrettyChars()); 7032 7033 // If more arguments than parameters, 7034 // then this is no match. 7035 if (td->parameters->dim < ti->tiargs->dim) 7036 { 7037 if (!td->isVariadic()) 7038 return 0; 7039 } 7040 7041 dedtypes.setDim(td->parameters->dim); 7042 dedtypes.zero(); 7043 assert(td->semanticRun != PASSinit); 7044 MATCH m = td->matchWithInstance(sc, ti, &dedtypes, ti->fargs, 0); 7045 //printf("matchWithInstance = %d\n", m); 7046 if (m <= MATCHnomatch) // no match at all 7047 return 0; 7048 7049 if (m < m_best) goto Ltd_best; 7050 if (m > m_best) goto Ltd; 7051 7052 { 7053 // Disambiguate by picking the most specialized TemplateDeclaration 7054 MATCH c1 = td->leastAsSpecialized(sc, td_best, ti->fargs); 7055 MATCH c2 = td_best->leastAsSpecialized(sc, td, ti->fargs); 7056 //printf("c1 = %d, c2 = %d\n", c1, c2); 7057 if (c1 > c2) goto Ltd; 7058 if (c1 < c2) goto Ltd_best; 7059 } 7060 7061 td_ambig = td; 7062 return 0; 7063 7064 Ltd_best: // td_best is the best match so far 7065 td_ambig = NULL; 7066 return 0; 7067 7068 Ltd: // td is the new best match 7069 td_ambig = NULL; 7070 td_best = td; 7071 m_best = m; 7072 ti->tdtypes.setDim(dedtypes.dim); 7073 memcpy(ti->tdtypes.tdata(), dedtypes.tdata(), ti->tdtypes.dim * sizeof(void *)); 7074 return 0; 7075 } 7076 }; 7077 ParamBest p; 7078 // context 7079 p.ti = this; 7080 p.sc = sc; 7081 7082 /* Since there can be multiple TemplateDeclaration's with the same 7083 * name, look for the best match. 7084 */ 7085 TemplateDeclaration *td_last = NULL; 7086 7087 OverloadSet *tovers = tempdecl->isOverloadSet(); 7088 size_t overs_dim = tovers ? tovers->a.dim : 1; 7089 for (size_t oi = 0; oi < overs_dim; oi++) 7090 { 7091 // result 7092 p.td_best = NULL; 7093 p.td_ambig = NULL; 7094 p.m_best = MATCHnomatch; 7095 overloadApply(tovers ? tovers->a[oi] : tempdecl, &p, &ParamBest::fp); 7096 7097 if (p.td_ambig) 7098 { 7099 ::error(loc, "%s %s.%s matches more than one template declaration:\n%s: %s\nand\n%s: %s", 7100 p.td_best->kind(), p.td_best->parent->toPrettyChars(), p.td_best->ident->toChars(), 7101 p.td_best->loc.toChars() , p.td_best->toChars(), 7102 p.td_ambig->loc.toChars(), p.td_ambig->toChars()); 7103 return false; 7104 } 7105 if (p.td_best) 7106 { 7107 if (!td_last) 7108 td_last = p.td_best; 7109 else if (td_last != p.td_best) 7110 { 7111 ScopeDsymbol::multiplyDefined(loc, td_last, p.td_best); 7112 return false; 7113 } 7114 } 7115 } 7116 7117 if (td_last) 7118 { 7119 /* Bugzilla 7469: Normalize tiargs by using corresponding deduced 7120 * template value parameters and tuples for the correct mangling. 7121 * 7122 * By doing this before hasNestedArgs, CTFEable local variable will be 7123 * accepted as a value parameter. For example: 7124 * 7125 * void foo() { 7126 * struct S(int n) {} // non-global template 7127 * const int num = 1; // CTFEable local variable 7128 * S!num s; // S!1 is instantiated, not S!num 7129 * } 7130 */ 7131 size_t dim = td_last->parameters->dim - (td_last->isVariadic() ? 1 : 0); 7132 for (size_t i = 0; i < dim; i++) 7133 { 7134 if (tiargs->dim <= i) 7135 tiargs->push(tdtypes[i]); 7136 assert(i < tiargs->dim); 7137 7138 TemplateValueParameter *tvp = (*td_last->parameters)[i]->isTemplateValueParameter(); 7139 if (!tvp) 7140 continue; 7141 assert(tdtypes[i]); 7142 // tdtypes[i] is already normalized to the required type in matchArg 7143 7144 (*tiargs)[i] = tdtypes[i]; 7145 } 7146 if (td_last->isVariadic() && tiargs->dim == dim && tdtypes[dim]) 7147 { 7148 Tuple *va = isTuple(tdtypes[dim]); 7149 assert(va); 7150 for (size_t i = 0; i < va->objects.dim; i++) 7151 tiargs->push(va->objects[i]); 7152 } 7153 } 7154 else if (errors && inst) 7155 { 7156 // instantiation was failed with error reporting 7157 assert(global.errors); 7158 return false; 7159 } 7160 else 7161 { 7162 TemplateDeclaration *tdecl = tempdecl->isTemplateDeclaration(); 7163 7164 if (errs != global.errors) 7165 errorSupplemental(loc, "while looking for match for %s", toChars()); 7166 else if (tdecl && !tdecl->overnext) 7167 { 7168 // Only one template, so we can give better error message 7169 error("does not match template declaration %s", tdecl->toChars()); 7170 } 7171 else 7172 ::error(loc, "%s %s.%s does not match any template declaration", 7173 tempdecl->kind(), tempdecl->parent->toPrettyChars(), tempdecl->ident->toChars()); 7174 return false; 7175 } 7176 7177 /* The best match is td_last 7178 */ 7179 tempdecl = td_last; 7180 7181 return (errs == global.errors); 7182 } 7183 7184 /***************************************************** 7185 * Determine if template instance is really a template function, 7186 * and that template function needs to infer types from the function 7187 * arguments. 7188 * 7189 * Like findBestMatch, iterate possible template candidates, 7190 * but just looks only the necessity of type inference. 7191 */ 7192 7193 bool TemplateInstance::needsTypeInference(Scope *sc, int flag) 7194 { 7195 //printf("TemplateInstance::needsTypeInference() %s\n", toChars()); 7196 if (semanticRun != PASSinit) 7197 return false; 7198 7199 struct ParamNeedsInf 7200 { 7201 // context 7202 Scope *sc; 7203 TemplateInstance *ti; 7204 int flag; 7205 // result 7206 Objects dedtypes; 7207 size_t count; 7208 7209 static int fp(void *param, Dsymbol *s) 7210 { 7211 return ((ParamNeedsInf *)param)->fp(s); 7212 } 7213 int fp(Dsymbol *s) 7214 { 7215 TemplateDeclaration *td = s->isTemplateDeclaration(); 7216 if (!td) 7217 { 7218 return 0; 7219 } 7220 7221 /* If any of the overloaded template declarations need inference, 7222 * then return true 7223 */ 7224 FuncDeclaration *fd; 7225 if (!td->onemember) 7226 return 0; 7227 if (TemplateDeclaration *td2 = td->onemember->isTemplateDeclaration()) 7228 { 7229 if (!td2->onemember || !td2->onemember->isFuncDeclaration()) 7230 return 0; 7231 if (ti->tiargs->dim >= td->parameters->dim - (td->isVariadic() ? 1 : 0)) 7232 return 0; 7233 return 1; 7234 } 7235 if ((fd = td->onemember->isFuncDeclaration()) == NULL || 7236 fd->type->ty != Tfunction) 7237 { 7238 return 0; 7239 } 7240 7241 for (size_t i = 0; i < td->parameters->dim; i++) 7242 { 7243 if ((*td->parameters)[i]->isTemplateThisParameter()) 7244 return 1; 7245 } 7246 7247 /* Determine if the instance arguments, tiargs, are all that is necessary 7248 * to instantiate the template. 7249 */ 7250 //printf("tp = %p, td->parameters->dim = %d, tiargs->dim = %d\n", tp, td->parameters->dim, ti->tiargs->dim); 7251 TypeFunction *tf = (TypeFunction *)fd->type; 7252 if (size_t dim = Parameter::dim(tf->parameters)) 7253 { 7254 TemplateParameter *tp = td->isVariadic(); 7255 if (tp && td->parameters->dim > 1) 7256 return 1; 7257 7258 if (!tp && ti->tiargs->dim < td->parameters->dim) 7259 { 7260 // Can remain tiargs be filled by default arguments? 7261 for (size_t i = ti->tiargs->dim; i < td->parameters->dim; i++) 7262 { 7263 if (!(*td->parameters)[i]->hasDefaultArg()) 7264 return 1; 7265 } 7266 } 7267 7268 for (size_t i = 0; i < dim; i++) 7269 { 7270 // 'auto ref' needs inference. 7271 if (Parameter::getNth(tf->parameters, i)->storageClass & STCauto) 7272 return 1; 7273 } 7274 } 7275 7276 if (!flag) 7277 { 7278 /* Calculate the need for overload resolution. 7279 * When only one template can match with tiargs, inference is not necessary. 7280 */ 7281 dedtypes.setDim(td->parameters->dim); 7282 dedtypes.zero(); 7283 if (td->semanticRun == PASSinit) 7284 { 7285 if (td->_scope) 7286 { 7287 // Try to fix forward reference. Ungag errors while doing so. 7288 Ungag ungag = td->ungagSpeculative(); 7289 td->semantic(td->_scope); 7290 } 7291 if (td->semanticRun == PASSinit) 7292 { 7293 ti->error("%s forward references template declaration %s", ti->toChars(), td->toChars()); 7294 return 1; 7295 } 7296 } 7297 assert(td->semanticRun != PASSinit); 7298 MATCH m = td->matchWithInstance(sc, ti, &dedtypes, NULL, 0); 7299 if (m <= MATCHnomatch) 7300 return 0; 7301 } 7302 7303 /* If there is more than one function template which matches, we may 7304 * need type inference (see Bugzilla 4430) 7305 */ 7306 if (++count > 1) 7307 return 1; 7308 7309 return 0; 7310 } 7311 }; 7312 ParamNeedsInf p; 7313 // context 7314 p.ti = this; 7315 p.sc = sc; 7316 p.flag = flag; 7317 // result 7318 p.count = 0; 7319 7320 OverloadSet *tovers = tempdecl->isOverloadSet(); 7321 size_t overs_dim = tovers ? tovers->a.dim : 1; 7322 unsigned olderrs = global.errors; 7323 for (size_t oi = 0; oi < overs_dim; oi++) 7324 { 7325 if (overloadApply(tovers ? tovers->a[oi] : tempdecl, &p, &ParamNeedsInf::fp)) 7326 return true; 7327 } 7328 if (olderrs != global.errors) 7329 { 7330 if (!global.gag) 7331 { 7332 errorSupplemental(loc, "while looking for match for %s", toChars()); 7333 semanticRun = PASSsemanticdone; 7334 inst = this; 7335 } 7336 errors = true; 7337 } 7338 //printf("false\n"); 7339 return false; 7340 } 7341 7342 7343 /***************************************** 7344 * Determines if a TemplateInstance will need a nested 7345 * generation of the TemplateDeclaration. 7346 * Sets enclosing property if so, and returns != 0; 7347 */ 7348 7349 bool TemplateInstance::hasNestedArgs(Objects *args, bool isstatic) 7350 { 7351 int nested = 0; 7352 //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars()); 7353 7354 /* A nested instance happens when an argument references a local 7355 * symbol that is on the stack. 7356 */ 7357 for (size_t i = 0; i < args->dim; i++) 7358 { 7359 RootObject *o = (*args)[i]; 7360 Expression *ea = isExpression(o); 7361 Dsymbol *sa = isDsymbol(o); 7362 Tuple *va = isTuple(o); 7363 if (ea) 7364 { 7365 if (ea->op == TOKvar) 7366 { 7367 sa = ((VarExp *)ea)->var; 7368 goto Lsa; 7369 } 7370 if (ea->op == TOKthis) 7371 { 7372 sa = ((ThisExp *)ea)->var; 7373 goto Lsa; 7374 } 7375 if (ea->op == TOKfunction) 7376 { 7377 if (((FuncExp *)ea)->td) 7378 sa = ((FuncExp *)ea)->td; 7379 else 7380 sa = ((FuncExp *)ea)->fd; 7381 goto Lsa; 7382 } 7383 // Emulate Expression::toMangleBuffer call that had exist in TemplateInstance::genIdent. 7384 if (ea->op != TOKint64 && 7385 ea->op != TOKfloat64 && 7386 ea->op != TOKcomplex80 && 7387 ea->op != TOKnull && 7388 ea->op != TOKstring && 7389 ea->op != TOKarrayliteral && 7390 ea->op != TOKassocarrayliteral && 7391 ea->op != TOKstructliteral) 7392 { 7393 ea->error("expression %s is not a valid template value argument", ea->toChars()); 7394 errors = true; 7395 } 7396 } 7397 else if (sa) 7398 { 7399 Lsa: 7400 sa = sa->toAlias(); 7401 TemplateDeclaration *td = sa->isTemplateDeclaration(); 7402 if (td) 7403 { 7404 TemplateInstance *ti = sa->toParent()->isTemplateInstance(); 7405 if (ti && ti->enclosing) 7406 sa = ti; 7407 } 7408 TemplateInstance *ti = sa->isTemplateInstance(); 7409 Declaration *d = sa->isDeclaration(); 7410 if ((td && td->literal) || 7411 (ti && ti->enclosing) || 7412 (d && !d->isDataseg() && 7413 !(d->storage_class & STCmanifest) && 7414 (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) && 7415 !isTemplateMixin() 7416 )) 7417 { 7418 // if module level template 7419 if (isstatic) 7420 { 7421 Dsymbol *dparent = sa->toParent2(); 7422 if (!enclosing) 7423 enclosing = dparent; 7424 else if (enclosing != dparent) 7425 { 7426 /* Select the more deeply nested of the two. 7427 * Error if one is not nested inside the other. 7428 */ 7429 for (Dsymbol *p = enclosing; p; p = p->parent) 7430 { 7431 if (p == dparent) 7432 goto L1; // enclosing is most nested 7433 } 7434 for (Dsymbol *p = dparent; p; p = p->parent) 7435 { 7436 if (p == enclosing) 7437 { 7438 enclosing = dparent; 7439 goto L1; // dparent is most nested 7440 } 7441 } 7442 error("%s is nested in both %s and %s", 7443 toChars(), enclosing->toChars(), dparent->toChars()); 7444 errors = true; 7445 } 7446 L1: 7447 //printf("\tnested inside %s\n", enclosing->toChars()); 7448 nested |= 1; 7449 } 7450 else 7451 { 7452 error("cannot use local '%s' as parameter to non-global template %s", sa->toChars(), tempdecl->toChars()); 7453 errors = true; 7454 } 7455 } 7456 } 7457 else if (va) 7458 { 7459 nested |= (int)hasNestedArgs(&va->objects, isstatic); 7460 } 7461 } 7462 //printf("-TemplateInstance::hasNestedArgs('%s') = %d\n", tempdecl->ident->toChars(), nested); 7463 return nested != 0; 7464 } 7465 7466 /***************************************** 7467 * Append 'this' to the specific module members[] 7468 */ 7469 Dsymbols *TemplateInstance::appendToModuleMember() 7470 { 7471 Module *mi = minst; // instantiated -> inserted module 7472 7473 if (global.params.useUnitTests || 7474 global.params.debuglevel) 7475 { 7476 // Turn all non-root instances to speculative 7477 if (mi && !mi->isRoot()) 7478 mi = NULL; 7479 } 7480 7481 //printf("%s->appendToModuleMember() enclosing = %s mi = %s\n", 7482 // toPrettyChars(), 7483 // enclosing ? enclosing->toPrettyChars() : NULL, 7484 // mi ? mi->toPrettyChars() : NULL); 7485 if (!mi || mi->isRoot()) 7486 { 7487 /* If the instantiated module is speculative or root, insert to the 7488 * member of a root module. Then: 7489 * - semantic3 pass will get called on the instance members. 7490 * - codegen pass will get a selection chance to do/skip it. 7491 */ 7492 7493 struct N 7494 { 7495 static Dsymbol *getStrictEnclosing(TemplateInstance *ti) 7496 { 7497 do 7498 { 7499 if (ti->enclosing) 7500 return ti->enclosing; 7501 ti = ti->tempdecl->isInstantiated(); 7502 } 7503 while (ti); 7504 return NULL; 7505 } 7506 }; 7507 Dsymbol *enc = N::getStrictEnclosing(this); 7508 7509 // insert target is made stable by using the module 7510 // where tempdecl is declared. 7511 mi = (enc ? enc : tempdecl)->getModule(); 7512 if (!mi->isRoot()) 7513 mi = mi->importedFrom; 7514 assert(mi->isRoot()); 7515 } 7516 else 7517 { 7518 /* If the instantiated module is non-root, insert to the member of the 7519 * non-root module. Then: 7520 * - semantic3 pass won't be called on the instance. 7521 * - codegen pass won't reach to the instance. 7522 */ 7523 } 7524 //printf("\t--> mi = %s\n", mi->toPrettyChars()); 7525 7526 if (memberOf == mi) // already a member 7527 { 7528 return NULL; 7529 } 7530 7531 Dsymbols *a = mi->members; 7532 a->push(this); 7533 memberOf = mi; 7534 if (mi->semanticRun >= PASSsemantic2done && mi->isRoot()) 7535 Module::addDeferredSemantic2(this); 7536 if (mi->semanticRun >= PASSsemantic3done && mi->isRoot()) 7537 Module::addDeferredSemantic3(this); 7538 return a; 7539 } 7540 7541 /**************************************** 7542 * This instance needs an identifier for name mangling purposes. 7543 * Create one by taking the template declaration name and adding 7544 * the type signature for it. 7545 */ 7546 7547 Identifier *TemplateInstance::genIdent(Objects *args) 7548 { 7549 TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration(); 7550 assert(tempdecl); 7551 7552 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); 7553 OutBuffer buf; 7554 const char *id = tempdecl->ident->toChars(); 7555 if (!members) 7556 { 7557 // Use "__U" for the symbols declared inside template constraint. 7558 buf.printf("__U%llu%s", (ulonglong)strlen(id), id); 7559 } 7560 else 7561 buf.printf("__T%llu%s", (ulonglong)strlen(id), id); 7562 size_t nparams = tempdecl->parameters->dim - (tempdecl->isVariadic() ? 1 : 0); 7563 for (size_t i = 0; i < args->dim; i++) 7564 { 7565 RootObject *o = (*args)[i]; 7566 Type *ta = isType(o); 7567 Expression *ea = isExpression(o); 7568 Dsymbol *sa = isDsymbol(o); 7569 Tuple *va = isTuple(o); 7570 //printf("\to [%d] %p ta %p ea %p sa %p va %p\n", i, o, ta, ea, sa, va); 7571 if (i < nparams && (*tempdecl->parameters)[i]->specialization()) 7572 buf.writeByte('H'); // Bugzilla 6574 7573 if (ta) 7574 { 7575 buf.writeByte('T'); 7576 if (ta->deco) 7577 buf.writestring(ta->deco); 7578 else 7579 { 7580 assert(global.errors); 7581 } 7582 } 7583 else if (ea) 7584 { 7585 // Don't interpret it yet, it might actually be an alias template parameter. 7586 // Only constfold manifest constants, not const/immutable lvalues, see https://issues.dlang.org/show_bug.cgi?id=17339. 7587 const bool keepLvalue = true; 7588 ea = ea->optimize(WANTvalue, keepLvalue); 7589 if (ea->op == TOKvar) 7590 { 7591 sa = ((VarExp *)ea)->var; 7592 ea = NULL; 7593 goto Lsa; 7594 } 7595 if (ea->op == TOKthis) 7596 { 7597 sa = ((ThisExp *)ea)->var; 7598 ea = NULL; 7599 goto Lsa; 7600 } 7601 if (ea->op == TOKfunction) 7602 { 7603 if (((FuncExp *)ea)->td) 7604 sa = ((FuncExp *)ea)->td; 7605 else 7606 sa = ((FuncExp *)ea)->fd; 7607 ea = NULL; 7608 goto Lsa; 7609 } 7610 buf.writeByte('V'); 7611 if (ea->op == TOKtuple) 7612 { 7613 ea->error("tuple is not a valid template value argument"); 7614 continue; 7615 } 7616 // Now that we know it is not an alias, we MUST obtain a value 7617 unsigned olderr = global.errors; 7618 ea = ea->ctfeInterpret(); 7619 if (ea->op == TOKerror || olderr != global.errors) 7620 continue; 7621 7622 /* Use deco that matches what it would be for a function parameter 7623 */ 7624 buf.writestring(ea->type->deco); 7625 mangleToBuffer(ea, &buf); 7626 } 7627 else if (sa) 7628 { 7629 Lsa: 7630 buf.writeByte('S'); 7631 sa = sa->toAlias(); 7632 Declaration *d = sa->isDeclaration(); 7633 if (d && (!d->type || !d->type->deco)) 7634 { 7635 error("forward reference of %s %s", d->kind(), d->toChars()); 7636 continue; 7637 } 7638 7639 OutBuffer bufsa; 7640 mangleToBuffer(sa, &bufsa); 7641 const char *s = bufsa.extractString(); 7642 7643 /* Bugzilla 3043: if the first character of s is a digit this 7644 * causes ambiguity issues because the digits of the two numbers are adjacent. 7645 * Current demanglers resolve this by trying various places to separate the 7646 * numbers until one gets a successful demangle. 7647 * Unfortunately, fixing this ambiguity will break existing binary 7648 * compatibility and the demanglers, so we'll leave it as is. 7649 */ 7650 buf.printf("%u%s", (unsigned)strlen(s), s); 7651 } 7652 else if (va) 7653 { 7654 assert(i + 1 == args->dim); // must be last one 7655 args = &va->objects; 7656 i = -(size_t)1; 7657 } 7658 else 7659 assert(0); 7660 } 7661 buf.writeByte('Z'); 7662 id = buf.peekString(); 7663 //printf("\tgenIdent = %s\n", id); 7664 return Identifier::idPool(id); 7665 } 7666 7667 /************************************* 7668 * Lazily generate identifier for template instance. 7669 * This is because 75% of the ident's are never needed. 7670 */ 7671 7672 Identifier *TemplateInstance::getIdent() 7673 { 7674 if (!ident && inst && !errors) 7675 ident = genIdent(tiargs); // need an identifier for name mangling purposes. 7676 return ident; 7677 } 7678 7679 /**************************************************** 7680 * Declare parameters of template instance, initialize them with the 7681 * template instance arguments. 7682 */ 7683 7684 void TemplateInstance::declareParameters(Scope *sc) 7685 { 7686 TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration(); 7687 assert(tempdecl); 7688 7689 //printf("TemplateInstance::declareParameters()\n"); 7690 for (size_t i = 0; i < tdtypes.dim; i++) 7691 { 7692 TemplateParameter *tp = (*tempdecl->parameters)[i]; 7693 //RootObject *o = (*tiargs)[i]; 7694 RootObject *o = tdtypes[i]; // initializer for tp 7695 7696 //printf("\ttdtypes[%d] = %p\n", i, o); 7697 tempdecl->declareParameter(sc, tp, o); 7698 } 7699 } 7700 7701 void TemplateInstance::semantic2(Scope *sc) 7702 { 7703 if (semanticRun >= PASSsemantic2) 7704 return; 7705 semanticRun = PASSsemantic2; 7706 if (!errors && members) 7707 { 7708 TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration(); 7709 assert(tempdecl); 7710 7711 sc = tempdecl->_scope; 7712 assert(sc); 7713 sc = sc->push(argsym); 7714 sc = sc->push(this); 7715 sc->tinst = this; 7716 sc->minst = minst; 7717 7718 int needGagging = (gagged && !global.gag); 7719 unsigned int olderrors = global.errors; 7720 int oldGaggedErrors = -1; // dead-store to prevent spurious warning 7721 if (needGagging) 7722 oldGaggedErrors = global.startGagging(); 7723 7724 for (size_t i = 0; i < members->dim; i++) 7725 { 7726 Dsymbol *s = (*members)[i]; 7727 s->semantic2(sc); 7728 if (gagged && global.errors != olderrors) 7729 break; 7730 } 7731 7732 if (global.errors != olderrors) 7733 { 7734 if (!errors) 7735 { 7736 if (!tempdecl->literal) 7737 error(loc, "error instantiating"); 7738 if (tinst) 7739 tinst->printInstantiationTrace(); 7740 } 7741 errors = true; 7742 } 7743 if (needGagging) 7744 global.endGagging(oldGaggedErrors); 7745 7746 sc = sc->pop(); 7747 sc->pop(); 7748 } 7749 } 7750 7751 void TemplateInstance::semantic3(Scope *sc) 7752 { 7753 //if (toChars()[0] == 'D') *(char*)0=0; 7754 if (semanticRun >= PASSsemantic3) 7755 return; 7756 semanticRun = PASSsemantic3; 7757 if (!errors && members) 7758 { 7759 TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration(); 7760 assert(tempdecl); 7761 7762 sc = tempdecl->_scope; 7763 sc = sc->push(argsym); 7764 sc = sc->push(this); 7765 sc->tinst = this; 7766 sc->minst = minst; 7767 7768 int needGagging = (gagged && !global.gag); 7769 unsigned int olderrors = global.errors; 7770 int oldGaggedErrors = -1; // dead-store to prevent spurious warning 7771 /* If this is a gagged instantiation, gag errors. 7772 * Future optimisation: If the results are actually needed, errors 7773 * would already be gagged, so we don't really need to run semantic 7774 * on the members. 7775 */ 7776 if (needGagging) 7777 oldGaggedErrors = global.startGagging(); 7778 7779 for (size_t i = 0; i < members->dim; i++) 7780 { 7781 Dsymbol *s = (*members)[i]; 7782 s->semantic3(sc); 7783 if (gagged && global.errors != olderrors) 7784 break; 7785 } 7786 7787 if (global.errors != olderrors) 7788 { 7789 if (!errors) 7790 { 7791 if (!tempdecl->literal) 7792 error(loc, "error instantiating"); 7793 if (tinst) 7794 tinst->printInstantiationTrace(); 7795 } 7796 errors = true; 7797 } 7798 if (needGagging) 7799 global.endGagging(oldGaggedErrors); 7800 7801 sc = sc->pop(); 7802 sc->pop(); 7803 } 7804 } 7805 7806 /************************************** 7807 * Given an error instantiating the TemplateInstance, 7808 * give the nested TemplateInstance instantiations that got 7809 * us here. Those are a list threaded into the nested scopes. 7810 */ 7811 void TemplateInstance::printInstantiationTrace() 7812 { 7813 if (global.gag) 7814 return; 7815 7816 const unsigned max_shown = 6; 7817 const char format[] = "instantiated from here: %s"; 7818 7819 // determine instantiation depth and number of recursive instantiations 7820 unsigned n_instantiations = 1; 7821 unsigned n_totalrecursions = 0; 7822 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 7823 { 7824 ++n_instantiations; 7825 // If two instantiations use the same declaration, they are recursive. 7826 // (this works even if they are instantiated from different places in the 7827 // same template). 7828 // In principle, we could also check for multiple-template recursion, but it's 7829 // probably not worthwhile. 7830 if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl 7831 && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) 7832 ++n_totalrecursions; 7833 } 7834 7835 // show full trace only if it's short or verbose is on 7836 if (n_instantiations <= max_shown || global.params.verbose) 7837 { 7838 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 7839 { 7840 cur->errors = true; 7841 errorSupplemental(cur->loc, format, cur->toChars()); 7842 } 7843 } 7844 else if (n_instantiations - n_totalrecursions <= max_shown) 7845 { 7846 // By collapsing recursive instantiations into a single line, 7847 // we can stay under the limit. 7848 int recursionDepth=0; 7849 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 7850 { 7851 cur->errors = true; 7852 if (cur->tinst && cur->tempdecl && cur->tinst->tempdecl 7853 && cur->tempdecl->loc.equals(cur->tinst->tempdecl->loc)) 7854 { 7855 ++recursionDepth; 7856 } 7857 else 7858 { 7859 if (recursionDepth) 7860 errorSupplemental(cur->loc, "%d recursive instantiations from here: %s", recursionDepth+2, cur->toChars()); 7861 else 7862 errorSupplemental(cur->loc, format, cur->toChars()); 7863 recursionDepth = 0; 7864 } 7865 } 7866 } 7867 else 7868 { 7869 // Even after collapsing the recursions, the depth is too deep. 7870 // Just display the first few and last few instantiations. 7871 unsigned i = 0; 7872 for (TemplateInstance *cur = this; cur; cur = cur->tinst) 7873 { 7874 cur->errors = true; 7875 7876 if (i == max_shown / 2) 7877 errorSupplemental(cur->loc, "... (%d instantiations, -v to show) ...", n_instantiations - max_shown); 7878 7879 if (i < max_shown / 2 || 7880 i >= n_instantiations - max_shown + max_shown / 2) 7881 errorSupplemental(cur->loc, format, cur->toChars()); 7882 ++i; 7883 } 7884 } 7885 } 7886 7887 Dsymbol *TemplateInstance::toAlias() 7888 { 7889 if (!inst) 7890 { 7891 // Maybe we can resolve it 7892 if (_scope) 7893 { 7894 semantic(_scope); 7895 } 7896 if (!inst) 7897 { 7898 error("cannot resolve forward reference"); 7899 errors = true; 7900 return this; 7901 } 7902 } 7903 7904 if (inst != this) 7905 return inst->toAlias(); 7906 7907 if (aliasdecl) 7908 { 7909 return aliasdecl->toAlias(); 7910 } 7911 7912 return inst; 7913 } 7914 7915 const char *TemplateInstance::kind() const 7916 { 7917 return "template instance"; 7918 } 7919 7920 bool TemplateInstance::oneMember(Dsymbol **ps, Identifier *) 7921 { 7922 *ps = NULL; 7923 return true; 7924 } 7925 7926 const char *TemplateInstance::toChars() 7927 { 7928 OutBuffer buf; 7929 toCBufferInstance(this, &buf); 7930 return buf.extractString(); 7931 } 7932 7933 const char *TemplateInstance::toPrettyCharsHelper() 7934 { 7935 OutBuffer buf; 7936 toCBufferInstance(this, &buf, true); 7937 return buf.extractString(); 7938 } 7939 7940 /************************************* 7941 * Compare proposed template instantiation with existing template instantiation. 7942 * Note that this is not commutative because of the auto ref check. 7943 * Params: 7944 * this = proposed template instantiation 7945 * o = existing template instantiation 7946 * Returns: 7947 * 0 for match, 1 for no match 7948 */ 7949 int TemplateInstance::compare(RootObject *o) 7950 { 7951 TemplateInstance *ti = (TemplateInstance *)o; 7952 7953 //printf("this = %p, ti = %p\n", this, ti); 7954 assert(tdtypes.dim == ti->tdtypes.dim); 7955 7956 // Nesting must match 7957 if (enclosing != ti->enclosing) 7958 { 7959 //printf("test2 enclosing %s ti->enclosing %s\n", enclosing ? enclosing->toChars() : "", ti->enclosing ? ti->enclosing->toChars() : ""); 7960 goto Lnotequals; 7961 } 7962 //printf("parent = %s, ti->parent = %s\n", parent->toPrettyChars(), ti->parent->toPrettyChars()); 7963 7964 if (!arrayObjectMatch(&tdtypes, &ti->tdtypes)) 7965 goto Lnotequals; 7966 7967 /* Template functions may have different instantiations based on 7968 * "auto ref" parameters. 7969 */ 7970 if (FuncDeclaration *fd = ti->toAlias()->isFuncDeclaration()) 7971 { 7972 if (!fd->errors) 7973 { 7974 Parameters *fparameters = fd->getParameters(NULL); 7975 size_t nfparams = Parameter::dim(fparameters); // Num function parameters 7976 for (size_t j = 0; j < nfparams; j++) 7977 { 7978 Parameter *fparam = Parameter::getNth(fparameters, j); 7979 if (fparam->storageClass & STCautoref) // if "auto ref" 7980 { 7981 if (!fargs) 7982 goto Lnotequals; 7983 if (fargs->dim <= j) 7984 break; 7985 Expression *farg = (*fargs)[j]; 7986 if (farg->isLvalue()) 7987 { 7988 if (!(fparam->storageClass & STCref)) 7989 goto Lnotequals; // auto ref's don't match 7990 } 7991 else 7992 { 7993 if (fparam->storageClass & STCref) 7994 goto Lnotequals; // auto ref's don't match 7995 } 7996 } 7997 } 7998 } 7999 } 8000 return 0; 8001 8002 Lnotequals: 8003 return 1; 8004 } 8005 8006 hash_t TemplateInstance::toHash() 8007 { 8008 if (!hash) 8009 { 8010 hash = (size_t)(void *)enclosing; 8011 hash += arrayObjectHash(&tdtypes); 8012 hash += hash == 0; 8013 } 8014 return hash; 8015 } 8016 8017 /************************************** 8018 * IsExpression can evaluate the specified type speculatively, and even if 8019 * it instantiates any symbols, they are normally unnecessary for the 8020 * final executable. 8021 * However, if those symbols leak to the actual code, compiler should remark 8022 * them as non-speculative to generate their code and link to the final executable. 8023 */ 8024 void unSpeculative(Scope *sc, RootObject *o) 8025 { 8026 if (!o) 8027 return; 8028 8029 if (Tuple *tup = isTuple(o)) 8030 { 8031 for (size_t i = 0; i < tup->objects.dim; i++) 8032 { 8033 unSpeculative(sc, tup->objects[i]); 8034 } 8035 return; 8036 } 8037 8038 Dsymbol *s = getDsymbol(o); 8039 if (!s) 8040 return; 8041 8042 if (Declaration *d = s->isDeclaration()) 8043 { 8044 if (VarDeclaration *vd = d->isVarDeclaration()) 8045 o = vd->type; 8046 else if (AliasDeclaration *ad = d->isAliasDeclaration()) 8047 { 8048 o = ad->getType(); 8049 if (!o) 8050 o = ad->toAlias(); 8051 } 8052 else 8053 o = d->toAlias(); 8054 8055 s = getDsymbol(o); 8056 if (!s) 8057 return; 8058 } 8059 8060 if (TemplateInstance *ti = s->isTemplateInstance()) 8061 { 8062 // If the instance is already non-speculative, 8063 // or it is leaked to the speculative scope. 8064 if (ti->minst != NULL || sc->minst == NULL) 8065 return; 8066 8067 // Remark as non-speculative instance. 8068 ti->minst = sc->minst; 8069 if (!ti->tinst) 8070 ti->tinst = sc->tinst; 8071 8072 unSpeculative(sc, ti->tempdecl); 8073 } 8074 8075 if (TemplateInstance *ti = s->isInstantiated()) 8076 unSpeculative(sc, ti); 8077 } 8078 8079 /*********************************************** 8080 * Returns true if this is not instantiated in non-root module, and 8081 * is a part of non-speculative instantiatiation. 8082 * 8083 * Note: minst does not stabilize until semantic analysis is completed, 8084 * so don't call this function during semantic analysis to return precise result. 8085 */ 8086 bool TemplateInstance::needsCodegen() 8087 { 8088 // Now -allInst is just for the backward compatibility. 8089 if (global.params.allInst) 8090 { 8091 //printf("%s minst = %s, enclosing (%s)->isNonRoot = %d\n", 8092 // toPrettyChars(), minst ? minst->toChars() : NULL, 8093 // enclosing ? enclosing->toPrettyChars() : NULL, enclosing && enclosing->inNonRoot()); 8094 if (enclosing) 8095 { 8096 // Bugzilla 14588: If the captured context is not a function 8097 // (e.g. class), the instance layout determination is guaranteed, 8098 // because the semantic/semantic2 pass will be executed 8099 // even for non-root instances. 8100 if (!enclosing->isFuncDeclaration()) 8101 return true; 8102 8103 // Bugzilla 14834: If the captured context is a function, 8104 // this excessive instantiation may cause ODR violation, because 8105 // -allInst and others doesn't guarantee the semantic3 execution 8106 // for that function. 8107 8108 // If the enclosing is also an instantiated function, 8109 // we have to rely on the ancestor's needsCodegen() result. 8110 if (TemplateInstance *ti = enclosing->isInstantiated()) 8111 return ti->needsCodegen(); 8112 8113 // Bugzilla 13415: If and only if the enclosing scope needs codegen, 8114 // this nested templates would also need code generation. 8115 return !enclosing->inNonRoot(); 8116 } 8117 return true; 8118 } 8119 8120 if (!minst) 8121 { 8122 // If this is a speculative instantiation, 8123 // 1. do codegen if ancestors really needs codegen. 8124 // 2. become non-speculative if siblings are not speculative 8125 8126 TemplateInstance *tnext = this->tnext; 8127 TemplateInstance *tinst = this->tinst; 8128 // At first, disconnect chain first to prevent infinite recursion. 8129 this->tnext = NULL; 8130 this->tinst = NULL; 8131 8132 // Determine necessity of tinst before tnext. 8133 if (tinst && tinst->needsCodegen()) 8134 { 8135 minst = tinst->minst; // cache result 8136 assert(minst); 8137 assert(minst->isRoot() || minst->rootImports()); 8138 return true; 8139 } 8140 if (tnext && (tnext->needsCodegen() || tnext->minst)) 8141 { 8142 minst = tnext->minst; // cache result 8143 assert(minst); 8144 return minst->isRoot() || minst->rootImports(); 8145 } 8146 8147 // Elide codegen because this is really speculative. 8148 return false; 8149 } 8150 8151 /* Even when this is reached to the codegen pass, 8152 * a non-root nested template should not generate code, 8153 * due to avoid ODR violation. 8154 */ 8155 if (enclosing && enclosing->inNonRoot()) 8156 { 8157 if (tinst) 8158 { 8159 bool r = tinst->needsCodegen(); 8160 minst = tinst->minst; // cache result 8161 return r; 8162 } 8163 if (tnext) 8164 { 8165 bool r = tnext->needsCodegen(); 8166 minst = tnext->minst; // cache result 8167 return r; 8168 } 8169 return false; 8170 } 8171 8172 /* The issue is that if the importee is compiled with a different -debug 8173 * setting than the importer, the importer may believe it exists 8174 * in the compiled importee when it does not, when the instantiation 8175 * is behind a conditional debug declaration. 8176 */ 8177 // workaround for Bugzilla 11239 8178 if (global.params.useUnitTests || 8179 global.params.debuglevel) 8180 { 8181 // Prefer instantiations from root modules, to maximize link-ability. 8182 if (minst->isRoot()) 8183 return true; 8184 8185 TemplateInstance *tnext = this->tnext; 8186 TemplateInstance *tinst = this->tinst; 8187 this->tnext = NULL; 8188 this->tinst = NULL; 8189 8190 if (tinst && tinst->needsCodegen()) 8191 { 8192 minst = tinst->minst; // cache result 8193 assert(minst); 8194 assert(minst->isRoot() || minst->rootImports()); 8195 return true; 8196 } 8197 if (tnext && tnext->needsCodegen()) 8198 { 8199 minst = tnext->minst; // cache result 8200 assert(minst); 8201 assert(minst->isRoot() || minst->rootImports()); 8202 return true; 8203 } 8204 8205 // Bugzilla 2500 case 8206 if (minst->rootImports()) 8207 return true; 8208 8209 // Elide codegen because this is not included in root instances. 8210 return false; 8211 } 8212 else 8213 { 8214 // Prefer instantiations from non-root module, to minimize object code size. 8215 8216 /* If a TemplateInstance is ever instantiated by non-root modules, 8217 * we do not have to generate code for it, 8218 * because it will be generated when the non-root module is compiled. 8219 * 8220 * But, if the non-root 'minst' imports any root modules, it might still need codegen. 8221 * 8222 * The problem is if A imports B, and B imports A, and both A 8223 * and B instantiate the same template, does the compilation of A 8224 * or the compilation of B do the actual instantiation? 8225 * 8226 * See Bugzilla 2500. 8227 */ 8228 if (!minst->isRoot() && !minst->rootImports()) 8229 return false; 8230 8231 TemplateInstance *tnext = this->tnext; 8232 this->tnext = NULL; 8233 8234 if (tnext && !tnext->needsCodegen() && tnext->minst) 8235 { 8236 minst = tnext->minst; // cache result 8237 assert(!minst->isRoot()); 8238 return false; 8239 } 8240 8241 // Do codegen because this is not included in non-root instances. 8242 return true; 8243 } 8244 } 8245 8246 /* ======================== TemplateMixin ================================ */ 8247 8248 TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, TypeQualified *tqual, Objects *tiargs) 8249 : TemplateInstance(loc, tqual->idents.dim ? (Identifier *)tqual->idents[tqual->idents.dim - 1] 8250 : ((TypeIdentifier *)tqual)->ident) 8251 { 8252 //printf("TemplateMixin(ident = '%s')\n", ident ? ident->toChars() : ""); 8253 this->ident = ident; 8254 this->tqual = tqual; 8255 this->tiargs = tiargs ? tiargs : new Objects(); 8256 } 8257 8258 Dsymbol *TemplateMixin::syntaxCopy(Dsymbol *) 8259 { 8260 TemplateMixin *tm = new TemplateMixin(loc, ident, 8261 (TypeQualified *)tqual->syntaxCopy(), tiargs); 8262 return TemplateInstance::syntaxCopy(tm); 8263 } 8264 8265 bool TemplateMixin::findTempDecl(Scope *sc) 8266 { 8267 // Follow qualifications to find the TemplateDeclaration 8268 if (!tempdecl) 8269 { 8270 Expression *e; 8271 Type *t; 8272 Dsymbol *s; 8273 tqual->resolve(loc, sc, &e, &t, &s); 8274 if (!s) 8275 { 8276 error("is not defined"); 8277 return false; 8278 } 8279 s = s->toAlias(); 8280 tempdecl = s->isTemplateDeclaration(); 8281 OverloadSet *os = s->isOverloadSet(); 8282 8283 /* If an OverloadSet, look for a unique member that is a template declaration 8284 */ 8285 if (os) 8286 { 8287 Dsymbol *ds = NULL; 8288 for (size_t i = 0; i < os->a.dim; i++) 8289 { 8290 Dsymbol *s2 = os->a[i]->isTemplateDeclaration(); 8291 if (s2) 8292 { 8293 if (ds) 8294 { 8295 tempdecl = os; 8296 break; 8297 } 8298 ds = s2; 8299 } 8300 } 8301 } 8302 if (!tempdecl) 8303 { 8304 error("%s isn't a template", s->toChars()); 8305 return false; 8306 } 8307 } 8308 assert(tempdecl); 8309 8310 struct ParamFwdResTm 8311 { 8312 static int fp(void *param, Dsymbol *s) 8313 { 8314 TemplateDeclaration *td = s->isTemplateDeclaration(); 8315 if (!td) 8316 return 0; 8317 8318 TemplateMixin *tm = (TemplateMixin *)param; 8319 if (td->semanticRun == PASSinit) 8320 { 8321 if (td->_scope) 8322 td->semantic(td->_scope); 8323 else 8324 { 8325 tm->semanticRun = PASSinit; 8326 return 1; 8327 } 8328 } 8329 return 0; 8330 } 8331 }; 8332 // Look for forward references 8333 OverloadSet *tovers = tempdecl->isOverloadSet(); 8334 size_t overs_dim = tovers ? tovers->a.dim : 1; 8335 for (size_t oi = 0; oi < overs_dim; oi++) 8336 { 8337 if (overloadApply(tovers ? tovers->a[oi] : tempdecl, (void *)this, &ParamFwdResTm::fp)) 8338 return false; 8339 } 8340 return true; 8341 } 8342 8343 void TemplateMixin::semantic(Scope *sc) 8344 { 8345 if (semanticRun != PASSinit) 8346 { 8347 // When a class/struct contains mixin members, and is done over 8348 // because of forward references, never reach here so semanticRun 8349 // has been reset to PASSinit. 8350 return; 8351 } 8352 semanticRun = PASSsemantic; 8353 8354 Scope *scx = NULL; 8355 if (_scope) 8356 { 8357 sc = _scope; 8358 scx = _scope; // save so we don't make redundant copies 8359 _scope = NULL; 8360 } 8361 8362 /* Run semantic on each argument, place results in tiargs[], 8363 * then find best match template with tiargs 8364 */ 8365 if (!findTempDecl(sc) || 8366 !semanticTiargs(sc) || 8367 !findBestMatch(sc, NULL)) 8368 { 8369 if (semanticRun == PASSinit) // forward reference had occured 8370 { 8371 //printf("forward reference - deferring\n"); 8372 _scope = scx ? scx : sc->copy(); 8373 _scope->setNoFree(); 8374 _scope->_module->addDeferredSemantic(this); 8375 return; 8376 } 8377 8378 inst = this; 8379 errors = true; 8380 return; // error recovery 8381 } 8382 TemplateDeclaration *tempdecl = this->tempdecl->isTemplateDeclaration(); 8383 assert(tempdecl); 8384 8385 if (!ident) 8386 { 8387 /* Assign scope local unique identifier, as same as lambdas. 8388 */ 8389 const char *s = "__mixin"; 8390 8391 DsymbolTable *symtab; 8392 if (FuncDeclaration *func = sc->parent->isFuncDeclaration()) 8393 { 8394 symtab = func->localsymtab; 8395 if (symtab) 8396 { 8397 // Inside template constraint, symtab is not set yet. 8398 goto L1; 8399 } 8400 } 8401 else 8402 { 8403 symtab = sc->parent->isScopeDsymbol()->symtab; 8404 L1: 8405 assert(symtab); 8406 int num = (int)dmd_aaLen(symtab->tab) + 1; 8407 ident = Identifier::generateId(s, num); 8408 symtab->insert(this); 8409 } 8410 } 8411 8412 inst = this; 8413 parent = sc->parent; 8414 8415 /* Detect recursive mixin instantiations. 8416 */ 8417 for (Dsymbol *s = parent; s; s = s->parent) 8418 { 8419 //printf("\ts = '%s'\n", s->toChars()); 8420 TemplateMixin *tm = s->isTemplateMixin(); 8421 if (!tm || tempdecl != tm->tempdecl) 8422 continue; 8423 8424 /* Different argument list lengths happen with variadic args 8425 */ 8426 if (tiargs->dim != tm->tiargs->dim) 8427 continue; 8428 8429 for (size_t i = 0; i < tiargs->dim; i++) 8430 { 8431 RootObject *o = (*tiargs)[i]; 8432 Type *ta = isType(o); 8433 Expression *ea = isExpression(o); 8434 Dsymbol *sa = isDsymbol(o); 8435 RootObject *tmo = (*tm->tiargs)[i]; 8436 if (ta) 8437 { 8438 Type *tmta = isType(tmo); 8439 if (!tmta) 8440 goto Lcontinue; 8441 if (!ta->equals(tmta)) 8442 goto Lcontinue; 8443 } 8444 else if (ea) 8445 { 8446 Expression *tme = isExpression(tmo); 8447 if (!tme || !ea->equals(tme)) 8448 goto Lcontinue; 8449 } 8450 else if (sa) 8451 { 8452 Dsymbol *tmsa = isDsymbol(tmo); 8453 if (sa != tmsa) 8454 goto Lcontinue; 8455 } 8456 else 8457 assert(0); 8458 } 8459 error("recursive mixin instantiation"); 8460 return; 8461 8462 Lcontinue: 8463 continue; 8464 } 8465 8466 // Copy the syntax trees from the TemplateDeclaration 8467 members = Dsymbol::arraySyntaxCopy(tempdecl->members); 8468 if (!members) 8469 return; 8470 8471 symtab = new DsymbolTable(); 8472 8473 for (Scope *sce = sc; 1; sce = sce->enclosing) 8474 { 8475 ScopeDsymbol *sds = (ScopeDsymbol *)sce->scopesym; 8476 if (sds) 8477 { 8478 sds->importScope(this, Prot(PROTpublic)); 8479 break; 8480 } 8481 } 8482 8483 Scope *scy = sc->push(this); 8484 scy->parent = this; 8485 8486 argsym = new ScopeDsymbol(); 8487 argsym->parent = scy->parent; 8488 Scope *argscope = scy->push(argsym); 8489 8490 unsigned errorsave = global.errors; 8491 8492 // Declare each template parameter as an alias for the argument type 8493 declareParameters(argscope); 8494 8495 // Add members to enclosing scope, as well as this scope 8496 for (size_t i = 0; i < members->dim; i++) 8497 { 8498 Dsymbol *s = (*members)[i]; 8499 s->addMember(argscope, this); 8500 //printf("sc->parent = %p, sc->scopesym = %p\n", sc->parent, sc->scopesym); 8501 //printf("s->parent = %s\n", s->parent->toChars()); 8502 } 8503 8504 // Do semantic() analysis on template instance members 8505 Scope *sc2 = argscope->push(this); 8506 //size_t deferred_dim = Module::deferred.dim; 8507 8508 static int nest; 8509 //printf("%d\n", nest); 8510 if (++nest > global.recursionLimit) 8511 { 8512 global.gag = 0; // ensure error message gets printed 8513 error("recursive expansion"); 8514 fatal(); 8515 } 8516 8517 for (size_t i = 0; i < members->dim; i++) 8518 { 8519 Dsymbol *s = (*members)[i]; 8520 s->setScope(sc2); 8521 } 8522 8523 for (size_t i = 0; i < members->dim; i++) 8524 { 8525 Dsymbol *s = (*members)[i]; 8526 s->importAll(sc2); 8527 } 8528 8529 for (size_t i = 0; i < members->dim; i++) 8530 { 8531 Dsymbol *s = (*members)[i]; 8532 s->semantic(sc2); 8533 } 8534 8535 nest--; 8536 8537 /* In DeclDefs scope, TemplateMixin does not have to handle deferred symbols. 8538 * Because the members would already call Module::addDeferredSemantic() for themselves. 8539 * See Struct, Class, Interface, and EnumDeclaration::semantic(). 8540 */ 8541 //if (!sc->func && Module::deferred.dim > deferred_dim) {} 8542 8543 AggregateDeclaration *ad = toParent()->isAggregateDeclaration(); 8544 if (sc->func && !ad) 8545 { 8546 semantic2(sc2); 8547 semantic3(sc2); 8548 } 8549 8550 // Give additional context info if error occurred during instantiation 8551 if (global.errors != errorsave) 8552 { 8553 error("error instantiating"); 8554 errors = true; 8555 } 8556 8557 sc2->pop(); 8558 argscope->pop(); 8559 scy->pop(); 8560 } 8561 8562 void TemplateMixin::semantic2(Scope *sc) 8563 { 8564 if (semanticRun >= PASSsemantic2) 8565 return; 8566 semanticRun = PASSsemantic2; 8567 if (members) 8568 { 8569 assert(sc); 8570 sc = sc->push(argsym); 8571 sc = sc->push(this); 8572 for (size_t i = 0; i < members->dim; i++) 8573 { 8574 Dsymbol *s = (*members)[i]; 8575 s->semantic2(sc); 8576 } 8577 sc = sc->pop(); 8578 sc->pop(); 8579 } 8580 } 8581 8582 void TemplateMixin::semantic3(Scope *sc) 8583 { 8584 if (semanticRun >= PASSsemantic3) 8585 return; 8586 semanticRun = PASSsemantic3; 8587 if (members) 8588 { 8589 sc = sc->push(argsym); 8590 sc = sc->push(this); 8591 for (size_t i = 0; i < members->dim; i++) 8592 { 8593 Dsymbol *s = (*members)[i]; 8594 s->semantic3(sc); 8595 } 8596 sc = sc->pop(); 8597 sc->pop(); 8598 } 8599 } 8600 8601 const char *TemplateMixin::kind() const 8602 { 8603 return "mixin"; 8604 } 8605 8606 bool TemplateMixin::oneMember(Dsymbol **ps, Identifier *ident) 8607 { 8608 return Dsymbol::oneMember(ps, ident); 8609 } 8610 8611 int TemplateMixin::apply(Dsymbol_apply_ft_t fp, void *param) 8612 { 8613 if (_scope) // if fwd reference 8614 semantic(NULL); // try to resolve it 8615 if (members) 8616 { 8617 for (size_t i = 0; i < members->dim; i++) 8618 { 8619 Dsymbol *s = (*members)[i]; 8620 if (s) 8621 { 8622 if (s->apply(fp, param)) 8623 return 1; 8624 } 8625 } 8626 } 8627 return 0; 8628 } 8629 8630 bool TemplateMixin::hasPointers() 8631 { 8632 //printf("TemplateMixin::hasPointers() %s\n", toChars()); 8633 8634 if (members) 8635 { 8636 for (size_t i = 0; i < members->dim; i++) 8637 { 8638 Dsymbol *s = (*members)[i]; 8639 //printf(" s = %s %s\n", s->kind(), s->toChars()); 8640 if (s->hasPointers()) 8641 { 8642 return true; 8643 } 8644 } 8645 } 8646 return false; 8647 } 8648 8649 void TemplateMixin::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion) 8650 { 8651 //printf("TemplateMixin::setFieldOffset() %s\n", toChars()); 8652 if (_scope) // if fwd reference 8653 semantic(NULL); // try to resolve it 8654 if (members) 8655 { 8656 for (size_t i = 0; i < members->dim; i++) 8657 { 8658 Dsymbol *s = (*members)[i]; 8659 //printf("\t%s\n", s->toChars()); 8660 s->setFieldOffset(ad, poffset, isunion); 8661 } 8662 } 8663 } 8664 8665 const char *TemplateMixin::toChars() 8666 { 8667 OutBuffer buf; 8668 toCBufferInstance(this, &buf); 8669 return buf.extractString(); 8670 } 8671