@@ -1076,7 +1076,6 @@ DeduceTemplateArguments(Sema &S,
1076
1076
// Pi of the respective parameter-type- list of P is compared with the
1077
1077
// corresponding parameter type Ai of the corresponding parameter-type-list
1078
1078
// of A. [...]
1079
- Sema::TemplateDeductionResult::TDK_NonDeducedMismatch;
1080
1079
unsigned ArgIdx = 0 , ParamIdx = 0 ;
1081
1080
for (; ParamIdx != NumParams; ++ParamIdx) {
1082
1081
// Check argument types.
@@ -1102,8 +1101,12 @@ DeduceTemplateArguments(Sema &S,
1102
1101
S, TemplateParams, Params[ParamIdx].getUnqualifiedType (),
1103
1102
Args[ArgIdx].getUnqualifiedType (), Info, Deduced, TDF,
1104
1103
PartialOrdering,
1105
- /* DeducedFromArrayBound=*/ false ))
1104
+ /* DeducedFromArrayBound=*/ false )){
1105
+ llvm::errs ()<<Result<<" =x" ;
1106
+ Args[ArgIdx].dump ();
1107
+ Params[ParamIdx].dump ();
1106
1108
return Result;
1109
+ }
1107
1110
1108
1111
++ArgIdx;
1109
1112
continue ;
@@ -5489,6 +5492,8 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
5489
5492
5490
5493
bool shouldConvert1;
5491
5494
bool shouldConvert2;
5495
+ QualType ObjType1;
5496
+ QualType ObjType2;
5492
5497
if (getLangOpts ().CPlusPlus20 ){
5493
5498
// C++20 [temp.func.order]p3
5494
5499
// [...] Each function template M that is a member function is considered to have a new first parameter of type
@@ -5500,20 +5505,26 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
5500
5505
// against anything else make no sense.
5501
5506
shouldConvert1= Method1 && !Method1->isExplicitObjectMemberFunction ();
5502
5507
shouldConvert2= Method2 && !Method2->isExplicitObjectMemberFunction ();
5503
- bool isR1=Method1 && !Method1->isExplicitObjectMemberFunction () ?
5504
- Method1->getRefQualifier () == RQ_RValue:
5505
- // Proto1->getRefQualifier() ==RQ_RValue;
5506
- Proto1->param_type_begin ()[0 ]->isRValueReferenceType ();
5507
- bool isR2=Method2 && !Method2->isExplicitObjectMemberFunction () ?
5508
+ if (shouldConvert1 && shouldConvert2 && !Reversed){
5509
+ shouldConvert1=false ;
5510
+ shouldConvert2=false ;
5511
+ }
5512
+ if (shouldConvert1){
5513
+ bool isR2=Method2 && !Method2->isExplicitObjectMemberFunction () ?
5508
5514
Method2->getRefQualifier () == RQ_RValue:
5509
5515
Proto2->param_type_begin ()[0 ]->isRValueReferenceType ();
5510
- // FD2->getParamDecl(0)->getRefQualifier() ==RQ_RValue;
5511
- if (shouldConvert1)
5512
5516
// Compare 'this' from Method1 against first parameter from Method2.
5513
5517
AddImplicitObjectParameterTypeCXX20 (this ->Context , Method1,isR2, Args1);
5514
- if (shouldConvert2)
5518
+ ObjType1=Args1[0 ];
5519
+ }
5520
+ if (shouldConvert2) {
5521
+ bool isR1=Method1 && !Method1->isExplicitObjectMemberFunction () ?
5522
+ Method1->getRefQualifier () == RQ_RValue:
5523
+ Proto1->param_type_begin ()[0 ]->isRValueReferenceType ();
5515
5524
// Compare 'this' from Method2 against first parameter from Method1.
5516
5525
AddImplicitObjectParameterTypeCXX20 (this ->Context , Method2,isR1, Args2);
5526
+ ObjType2=Args2[0 ];
5527
+ }
5517
5528
}else {
5518
5529
// C++11 [temp.func.order]p3:
5519
5530
// [...] If only one of the function templates is a non-static
@@ -5532,12 +5543,16 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
5532
5543
// it as wording was broken prior to it.
5533
5544
shouldConvert1=!Method2 && Method1 && Method1->isImplicitObjectMemberFunction ();
5534
5545
shouldConvert2=!Method1 && Method2 && Method2->isImplicitObjectMemberFunction ();
5535
- if (shouldConvert1)
5546
+ if (shouldConvert1){
5536
5547
// Compare 'this' from Method1 against first parameter from Method2.
5537
5548
AddImplicitObjectParameterType (this ->Context , Method1, Args1);
5538
- if (shouldConvert2)
5549
+ ObjType1=Args1[0 ];
5550
+ }
5551
+ if (shouldConvert2){
5539
5552
// Compare 'this' from Method2 against first parameter from Method1.
5540
5553
AddImplicitObjectParameterType (this ->Context , Method2, Args2);
5554
+ ObjType2=Args2[0 ];
5555
+ }
5541
5556
}
5542
5557
unsigned NumComparedArguments = NumCallArguments1 + shouldConvert1;
5543
5558
@@ -5560,11 +5575,6 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
5560
5575
NumCallArguments1, Reversed,Args1,Args2);
5561
5576
bool Better2 = isAtLeastAsSpecializedAs (*this , Loc, FT2, FT1, TPOC,
5562
5577
NumCallArguments2, Reversed,Args2,Args1);
5563
- FT1->dump ();
5564
- llvm::errs ()<<" ---\n " ;
5565
- FT2->dump ();
5566
- llvm::errs ()<<" ---" <<NumCallArguments1<<" " <<NumCallArguments2<<" \n " ;
5567
- llvm::errs ()<<" ---" <<Better1<<" " <<Better2<<" \n " ;
5568
5578
5569
5579
// C++ [temp.deduct.partial]p10:
5570
5580
// F is more specialized than G if F is at least as specialized as G and G
@@ -5580,54 +5590,37 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
5580
5590
// have a corresponding parameter, and if F does not have a trailing
5581
5591
// function parameter pack, then F is more specialized than G.
5582
5592
5583
- SmallVector<ParmVarDecl* > param1;
5584
- if ( shouldConvert1){
5585
- param1. push_back ({}); // TODO
5586
- }
5587
- param1. insert (param1. end (), FD1->parameters (). begin (),
5588
- FD1-> parameters (). end ());
5593
+ SmallVector<QualType > param1;
5594
+ param1. reserve (FD1-> param_size ()+ shouldConvert1);
5595
+ if (shouldConvert1)
5596
+ param1. push_back (ObjType1);
5597
+ for ( const auto & x: FD1->parameters ())
5598
+ param1. push_back (x-> getType ());
5589
5599
5590
- SmallVector<ParmVarDecl* > param2;
5591
- if ( shouldConvert2){
5592
- param2. push_back ({}); // TODO
5593
- }
5594
- param2. insert (param2. end (), FD2->parameters (). begin (),
5595
- FD2-> parameters (). end ());
5600
+ SmallVector<QualType > param2;
5601
+ param2. reserve (FD2-> param_size ()+ shouldConvert2);
5602
+ if (shouldConvert2)
5603
+ param2. push_back (ObjType2);
5604
+ for ( const auto & x: FD2->parameters ())
5605
+ param2. push_back (x-> getType ());
5596
5606
5597
5607
unsigned NumParams1 = param1.size ();
5598
5608
unsigned NumParams2 = param2.size ();
5599
- /* unsigned NumParams1 = FD1->getNumParams();
5600
- unsigned NumParams2 = FD2->getNumParams();
5601
-
5602
- if (Method1) {
5603
- llvm::errs()<<"METHOD1:";
5604
- Method1->dump();
5605
- for (const auto& x:Method1->parameters()){
5606
- x->dump();
5607
- }
5608
- llvm::errs()<<"#";
5609
- Method1->getNonObjectParameter(0)->dump();
5610
- llvm::errs()<<"=#";
5611
- Method1->getThisType().dump();
5612
- llvm::errs()<<"#=";
5613
- Method1->getType().dump();
5614
- }*/
5615
- bool Variadic1 = NumParams1 && FD1->parameters ().back ()->isParameterPack ();
5616
- bool Variadic2 = NumParams2 && FD2->parameters ().back ()->isParameterPack ();
5609
+
5610
+ bool Variadic1 = FD1->param_size () && FD1->parameters ().back ()->isParameterPack ();
5611
+ bool Variadic2 = FD2->param_size () && FD2->parameters ().back ()->isParameterPack ();
5617
5612
if (Variadic1 != Variadic2) {
5618
- if (Variadic1 && NumParams1 + shouldConvert1 > NumParams2 + shouldConvert2 )
5613
+ if (Variadic1 && NumParams1 > NumParams2 )
5619
5614
return FT2;
5620
- if (Variadic2 && NumParams2 + shouldConvert2 > NumParams1 + shouldConvert1 )
5615
+ if (Variadic2 && NumParams2 > NumParams1 )
5621
5616
return FT1;
5622
5617
}
5623
5618
5624
5619
// This a speculative fix for CWG1432 (Similar to the fix for CWG1395) that
5625
5620
// there is no wording or even resolution for this issue.
5626
5621
for (int i = 0 , e = std::min (NumParams1, NumParams2); i < e; ++i) {
5627
- if (!param1[i] || !param2[i])
5628
- continue ;
5629
- QualType T1 = param1[i]->getType ().getCanonicalType ();
5630
- QualType T2 = param2[i]->getType ().getCanonicalType ();
5622
+ QualType T1 = param1[i].getCanonicalType ();
5623
+ QualType T2 = param2[i].getCanonicalType ();
5631
5624
auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
5632
5625
auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
5633
5626
if (!TST1 || !TST2)
@@ -5683,10 +5676,8 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
5683
5676
return nullptr ;
5684
5677
5685
5678
for (unsigned i = 0 ; i < NumParams1; ++i)
5686
- if (param1[i] && param2[i])// TODO: write in from args
5687
- if (!Context.hasSameType (param1[i]->getType (),
5688
- param2[i]->getType ()))
5689
- return nullptr ;
5679
+ if (!Context.hasSameType (param1[i], param2[i]))
5680
+ return nullptr ;
5690
5681
5691
5682
// C++20 [temp.func.order]p6.3:
5692
5683
// Otherwise, if the context in which the partial ordering is done is
0 commit comments