370
bool InstantiationCandidate::deduceArguments (CTypeInfo *ftype, CTypeInfo *atype,
371
DeducedArgumentList &dargs) {
372
CTemplateInstance *fui, *aui, *fci, *aci;
373
CObjectInfo *finfo, *ainfo;
374
CTemplateParamInfo *param;
375
CTypeList *ftl, *atl;
379
ftype = ftype->UnqualType ();
380
atype = atype->UnqualType ();
364
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
365
int InstantiationCandidate::deduceArguments (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
368
// ignore qualifiers if exact match is not required
370
ftype = ftype->UnqualType ();
373
// template parameter
382
374
if (ftype->TypeTemplateParam ()) {
383
param = ftype->TypeTemplateParam ()->TemplateParamInfo ();
384
pos = getPosition (param);
386
if (param->isTemplate ()) {
387
if (atype->TypeRecord () &&
388
(ainfo = atype->TypeRecord ()->Record ()) &&
389
ainfo->isTemplateInstance ()) {
390
if (ainfo->UnionInstance ())
391
dargs[pos] = new DeducedArgument (param,
392
ainfo->TemplateInstance ()->Template ()->ObjectInfo ()->TypeInfo ());
393
else if (ainfo->ClassInstance ())
394
dargs[pos] = new DeducedArgument (param,
395
ainfo->TemplateInstance ()->Template ()->ObjectInfo ()->TypeInfo ());
397
} else if (param->isTypeParam ())
398
dargs[pos] = new DeducedArgument (param, atype);
403
if (ftype->Id () != atype->Id () ||
404
ftype->TypeEmpty () || ftype->TypePrimitive ()) {
375
return deduceTemplateParam (ftype, atype, dargs, exact_match);
378
// types must be equal to deduce template arguments
379
if (ftype->Id () != atype->Id ()) {
380
return exact_match ? 2 : 0;
384
if (ftype->TypeEmpty () || ftype->TypePrimitive ()) {
388
// deduce from pointer to class member
408
389
if (ftype->TypeMemberPointer ()) {
409
param = ftype->TypeMemberPointer ()->TemplateParam ();
411
pos = getPosition (param);
412
if (pos != -1 && param->isTypeParam () && atype->TypeMemberPointer ()->Record ())
413
dargs[pos] = new DeducedArgument (param,
414
atype->TypeMemberPointer ()->Record ()->TypeInfo ());
390
return deduceFromMemberPointer (ftype, atype, dargs, exact_match);
392
// deduce from class or union type
416
393
} else if (ftype->TypeRecord ()) {
417
finfo = ftype->TypeRecord ()->Record ();
418
ainfo = atype->TypeRecord ()->Record ();
419
if (finfo && ainfo && finfo->isTemplateInstance () &&
420
ainfo->isTemplateInstance ()) {
421
fui = finfo->UnionInstance () ? finfo->TemplateInstance () : 0;
422
aui = ainfo->UnionInstance () ? ainfo->TemplateInstance () : 0;
423
if (fui && aui && fui->DeducedArgs () == aui->DeducedArgs ()) {
424
for (unsigned i = 0; i < fui->DeducedArgs (); i++)
425
if ((type = fui->DeducedArg (i)->Type ())) {
426
if (aui->DeducedArg (i)->Type ()) {
427
if (! deduceArguments (type, aui->DeducedArg (i)->Type (), dargs))
429
} else if (type->TypeTemplateParam () &&
430
! type->TypeTemplateParam ()->isTypeParam ()) {
431
param = type->TypeTemplateParam ()->TemplateParamInfo ();
433
pos = getPosition (param);
435
dargs[pos] = new DeducedArgument (param, aui->DeducedArg (i)->Value ());
440
fci = finfo->ClassInstance () ? finfo->TemplateInstance () : 0;
441
aci = ainfo->ClassInstance () ? ainfo->TemplateInstance () : 0;
442
if (fci && aci && fci->DeducedArgs () == aci->DeducedArgs ()) {
443
for (unsigned i = 0; i < fci->DeducedArgs (); i++)
444
if ((type = fci->DeducedArg (i)->Type ())) {
445
if (aci->DeducedArg (i)->Type ()) {
446
if (! deduceArguments (type, aci->DeducedArg (i)->Type (), dargs))
448
} else if (type->TypeTemplateParam () &&
449
! type->TypeTemplateParam ()->isTypeParam ()) {
450
param = type->TypeTemplateParam ()->TemplateParamInfo ();
452
pos = getPosition (param);
454
dargs[pos] = new DeducedArgument (param, aci->DeducedArg (i)->Value ());
394
return deduceFromRecord (ftype, atype, dargs, exact_match);
396
// deduce from array type
461
397
} else if (ftype->TypeArray ()) {
462
if (ftype->TypeArray ()->DepDim ()) {
463
param = ftype->TypeArray ()->DepDim ()->TemplateParamInfo ();
465
pos = getPosition (param);
466
if (pos != -1 && ! param->isTypeParam () && atype->TypeArray ()->Dimension ())
467
dargs[pos] = new DeducedArgument (param, atype->TypeArray ()->Dimension ());
398
if ((ret = deduceFromArray (ftype, atype, dargs, exact_match)) != 0) {
402
// deduce from function type
470
403
} else if (ftype->TypeFunction ()) {
471
if (ftype->TypeFunction ()->ArgTypes ()->Entries () ==
472
atype->TypeFunction ()->ArgTypes ()->Entries ()) {
473
ftl = ftype->TypeFunction ()->ArgTypes ();
474
atl = atype->TypeFunction ()->ArgTypes ();
475
for (unsigned i = 0; i < ftl->Entries (); i++) {
476
if (! deduceArguments (ftl->Entry (i), atl->Entry (i), dargs))
482
return deduceArguments (ftype->BaseType (), atype->BaseType (), dargs);
486
// �14.5.4.1.2 try to match a partial specialization
404
if ((ret = deduceFromFunction (ftype, atype, dargs, exact_match)) != 0) {
409
// deduce from the base types, types must match exactly
410
return deduceArguments (ftype->BaseType (), atype->BaseType (), dargs, exact_match);
414
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
415
int InstantiationCandidate::deduceFromFunction (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
416
CTypeFunction *fft = ftype->TypeFunction ();
417
CTypeFunction *aft = atype->TypeFunction ();
419
// number of function parameters must be equal
420
if (fft->ArgTypes ()->Entries () == aft->ArgTypes ()->Entries ()) {
421
CTypeList *ftl = fft->ArgTypes ();
422
CTypeList *atl = aft->ArgTypes ();
424
bool matching_args = true;
425
bool ambiguous_type = false;
426
DeducedArgumentList curr_dargs;
428
// prepare temporary deduced argument container
429
for (unsigned i = 0; i < tpl_info->Parameters (); i++) {
430
curr_dargs.append (0);
433
// deduce from the function parameters
434
for (unsigned i = 0; i < ftl->Entries () && matching_args && ! ambiguous_type; i++) {
435
switch (deduceArguments (ftl->Entry (i), atl->Entry (i), dargs, true)) {
436
case 2: matching_args = false; break;
437
case 1: ambiguous_type = true; break;
442
// join the deduced template arguments if possible
443
if (! joinDeducedArguments (dargs, curr_dargs, matching_args, ambiguous_type)) {
444
return matching_args && ambiguous_type ? 1 :
445
exact_match && ! matching_args ? 2 : 0;
448
// different number of function parameters
449
} else if (exact_match) {
457
bool InstantiationCandidate::joinDeducedArguments (DeducedArgumentList &dargs, DeducedArgumentList &curr_dargs, bool &matching_args, bool &ambiguous_type) {
458
// check if the current deduced template arguments are valid
459
if (! matching_args || ambiguous_type) {
460
// discard the deduced template arguments
461
for (long i = 0; i < curr_dargs.length (); i++) {
462
DeducedArgument *darg = curr_dargs.fetch (i);
463
if (darg) delete darg;
466
// if not ambiguous, add the deduced arguments to dargs
468
// join the deduced template arguments
469
if (! ambiguous_type) {
470
for (long i = 0; i < curr_dargs.length (); i++) {
471
DeducedArgument *darg = curr_dargs.fetch (i);
472
if (darg && ! setDeducedArgument (dargs, i, darg)) {
473
ambiguous_type = true;
478
return matching_args && ! ambiguous_type;
482
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
483
int InstantiationCandidate::deduceFromArray (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
484
CTypeArray *array = ftype->TypeArray ();
486
// array size depends on a template parameter
487
if (array->DepDim ()) {
488
CTemplateParamInfo *param = array->DepDim ()->TemplateParamInfo ();
491
int pos = getPosition (param);
493
// non-type template parameter
494
if (pos != -1 && ! param->isTypeParam ()) {
495
array = atype->TypeArray ();
497
// array has dimension
498
if (array->Dimension ()) {
499
if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, array->Dimension ()))) {
503
// match non-type template parameter for partial ordering of function templates
504
} else if (array->DepDim ()) {
505
CTemplateParamInfo *aparam = array->DepDim ()->TemplateParamInfo ();
507
! aparam->isTypeParam () &&
508
! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) {
515
// ordinary types must be an exact match
516
} else if (exact_match && (*ftype != *atype)) {
524
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
525
int InstantiationCandidate::deduceTemplateParam (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
526
CTemplateParamInfo *param = ftype->TypeTemplateParam ()->TemplateParamInfo ();
527
int ret, pos = getPosition (param);
530
// template template parameter
531
if (param->isTemplate ()) {
532
CObjectInfo *ainfo = atype->TypeRecord () ? (CObjectInfo*)atype->TypeRecord ()->Record () :
533
atype->TypeTemplateParam () ? (CObjectInfo*)atype->TypeTemplateParam ()->TemplateParamInfo () : 0;
535
// template parameter list must match
536
if (! matchingTemplateParameters (param, ainfo)) {
537
return exact_match ? 2 : 0;
540
// get the template instance info of the argument, if it is an template instance
541
CTemplateInstance *ti = ainfo->Record () ? ainfo->TemplateInstance () : ainfo->TemplateParamInfo ()->TemplateInstance ();
542
CTemplateInfo *tpl = getTemplateInfo (ainfo);
544
// match template instance
545
if (param->TemplateInstance ()) {
547
// not a template instance
548
return exact_match ? 2 : 0;
551
// deduce from the argument list
552
ret = deduceArgumentsFromTemplateArgList (param->TemplateInstance (), ti, dargs);
557
// matches the template itself
558
if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, tpl->ObjectInfo ()->TypeInfo ()))) {
562
// template template parameter does not match template instances
564
return exact_match ? 2 : 0;
566
// match template itself (template name)
568
if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, tpl->ObjectInfo ()->TypeInfo ()))) {
573
// type template parameter, matches any type
574
} else if (param->isTypeParam ()) {
575
if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) {
579
// non-type template parameter, matches any value or non-type template parameter,
580
// for partial ordering of function templates
581
} else if (! param->isTypeParam ()) {
582
if (atype->TypeTemplateParam ()) {
583
CTemplateParamInfo *aparam = atype->TypeTemplateParam ()->TemplateParamInfo ();
585
! aparam->isTypeParam () &&
586
! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) {
597
bool InstantiationCandidate::matchingTemplateParameters (CTemplateParamInfo *param, CObjectInfo *ainfo) {
601
CTemplateInfo *atpl = getTemplateInfo (ainfo);
602
CTemplateInfo *ftpl = param->TemplateTemplate ();
604
if (! ftpl && ! atpl)
606
if (! ftpl || ! atpl || ftpl->Parameters () != atpl->Parameters ())
609
for (unsigned i = 0; i < ftpl->Parameters (); i++) {
610
CTemplateParamInfo *fparam = ftpl->Parameter (i);
611
CTemplateParamInfo *aparam = atpl->Parameter (i);
613
if (*fparam->TypeInfo () != *aparam->TypeInfo ())
621
CTemplateInfo *InstantiationCandidate::getTemplateInfo (CObjectInfo *info) {
622
CTemplateInfo *tpl = 0;
623
if (info->TemplateInstance ())
624
tpl = info->TemplateInstance ()->Template ();
625
else if (info->Record ())
626
tpl = info->Record ()->TemplateInfo ();
627
else if (info->TemplateParamInfo ())
628
tpl = info->TemplateParamInfo ()->TemplateTemplate ();
633
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
634
int InstantiationCandidate::deduceFromMemberPointer (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
635
CTemplateParamInfo *param = ftype->TypeMemberPointer ()->TemplateParam ();
637
// member pointer of form T::member where T is a type template parameter
639
int pos = getPosition (param);
640
if (pos != -1 && param->isTypeParam ()) {
642
CRecord *record = atype->TypeMemberPointer ()->Record ();
644
// argument type is class or union, can be deduced
646
if (! setDeducedArgument (dargs, pos, new DeducedArgument (param, record->TypeInfo ()))) {
650
// argument member pointer type contains template parameter, handled as unique type for
651
// partial ordering of function templates
653
CTemplateParamInfo *tp = atype->TypeMemberPointer ()->TemplateParam ();
654
if (tp && tp->isTypeParam () && ! setDeducedArgument (dargs, pos, new DeducedArgument (param, atype))) {
660
// ordinary types must match, if not the top level types
661
} else if (exact_match && (*ftype != *atype)) {
669
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
670
int InstantiationCandidate::deduceFromRecord (CTypeInfo *ftype, CTypeInfo *atype, DeducedArgumentList &dargs, bool exact_match) {
671
CRecord *finfo = ftype->TypeRecord ()->Record ();
672
CRecord *ainfo = atype->TypeRecord ()->Record ();
674
if (finfo && ainfo) {
675
// types must have same record type, i.e. either class or union
676
if ((finfo->ClassInfo () && ! ainfo->ClassInfo ()) ||
677
(finfo->UnionInfo () && ! ainfo->UnionInfo ())) {
678
return exact_match ? 2 : 0;
681
// parameter type is template instance
682
if (finfo->isTemplateInstance ()) {
683
// deduce template arguments from the type arguments of the template instances,
684
// the template used to instantiate finfo must be equal to the template used
685
// to instantiate ainfo or one of its base classes
687
CTemplateInstance *fi = finfo->TemplateInstance ();
688
Array<CTemplateInstance*> instances;
689
getTemplateInstances (ainfo, instances); // search the class hierarchy of ainfo
691
bool at_least_one_match = false;
692
for (long j = 0; j < instances.length (); j++) {
693
CTemplateInstance *ai = instances.fetch (j);
695
// same template and same number of template arguments
696
CTemplateInfo *ft = fi->Template ()->BaseTemplate () ? fi->Template ()->BaseTemplate () : fi->Template ();
697
CTemplateInfo *at = ai->Template ()->BaseTemplate () ? ai->Template ()->BaseTemplate () : ai->Template ();
698
if (*ft != *at || fi->InstantiationArgs () != ai->InstantiationArgs ()) {
702
// deduce from the template arguments
703
int ret = deduceArgumentsFromTemplateArgList (fi, ai, dargs);
707
at_least_one_match = at_least_one_match || (ret == 0);
710
// require exact match
711
if (! at_least_one_match) {
715
// ordinary types must match, if not the top level types
716
} else if (exact_match && (*finfo != *ainfo)) {
725
// return 0 if all ok, 1 if ambiguous type for parameter, 2 if types don't match
726
int InstantiationCandidate::deduceArgumentsFromTemplateArgList (CTemplateInstance *fi, CTemplateInstance *ai, DeducedArgumentList &dargs) {
727
bool matching_args = true;
728
bool ambiguous_type = false;
729
DeducedArgumentList curr_dargs;
731
// number of template arguments must match
732
if (fi->InstantiationArgs () != ai->InstantiationArgs ()) {
736
// prepare temporary deduced argument container
737
for (unsigned i = 0; i < tpl_info->Parameters (); i++) {
738
curr_dargs.append (0);
741
// now try to deduce from the template arguments, must match exactly
742
// for a successful deduction
743
for (unsigned i = 0; i < fi->InstantiationArgs () && matching_args && ! ambiguous_type; i++) {
744
CTypeInfo *fdtype = fi->InstantiationArg (i)->Type ();
745
CTypeInfo *adtype = ai->InstantiationArg (i)->Type ();
746
CConstant *fvalue = fi->InstantiationArg (i)->Value ();
747
CConstant *avalue = ai->InstantiationArg (i)->Value ();
750
// type template arguments
752
switch (deduceArguments (fdtype, adtype, curr_dargs, true)) {
753
case 2: matching_args = false; break;
754
case 1: ambiguous_type = true; break;
758
// non-type template arguments
760
fdtype->TypeTemplateParam () &&
761
! fdtype->TypeTemplateParam ()->isTypeParam ()) {
762
CTemplateParamInfo *param = fdtype->TypeTemplateParam ()->TemplateParamInfo ();
764
int pos = getPosition (param);
765
if (pos != -1 && ! setDeducedArgument (curr_dargs, pos, new DeducedArgument (param, avalue))) {
766
ambiguous_type = true;
771
matching_args = false;
774
// non-type template arguments
775
} else if (fvalue && (! avalue || (*fvalue != *avalue))) {
776
matching_args = false;
780
// check if deduced template arguments are valid
781
if (! matching_args || ambiguous_type) {
782
// discard the deduced template arguments
783
for (long i = 0; i < curr_dargs.length (); i++) {
784
DeducedArgument *darg = curr_dargs.fetch (i);
785
if (darg) delete darg;
788
// if not ambiguous, add the deduced arguments to dargs
790
// add the deduced template arguments
791
if (! ambiguous_type) {
792
for (long i = 0; i < curr_dargs.length (); i++) {
793
DeducedArgument *darg = curr_dargs.fetch (i);
794
if (darg && ! setDeducedArgument (dargs, i, darg)) {
795
ambiguous_type = true;
799
if (ambiguous_type) {
808
void InstantiationCandidate::getTemplateInstances(CRecord* c, Array<CTemplateInstance*>& instances) {
809
if (c->isTemplateInstance ()) {
810
instances.append (c->TemplateInstance ());
812
CClassInfo *cl = c->ClassInfo ();
814
for (unsigned i = 0; i < cl->BaseClasses (); i++) {
815
getTemplateInstances (cl->BaseClass (i)->Class (), instances);
821
// §14.5.4.1.2 try to match a partial specialization
487
822
// against a given template argument list
488
823
bool InstantiationCandidate::match () {
489
824
CT_TemplateArgList *args;