diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-12-01 16:54:29 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-12-01 16:54:29 +0000 |
| commit | 6edca7d9bde368cce0633cf0315735cfa46eccbe (patch) | |
| tree | cef36df2ab2f0f1b7b8465d868537143fb68cb89 /clang/lib/Sema | |
| parent | 2dece5747a0f7bd711a5d8fa93b613351f7b6e07 (diff) | |
| download | bcm5719-llvm-6edca7d9bde368cce0633cf0315735cfa46eccbe.tar.gz bcm5719-llvm-6edca7d9bde368cce0633cf0315735cfa46eccbe.zip | |
Handle CC and NoReturn when instantiating members of class templates.
Before we were considering them only when instantiating templates.
This fixes pr18033.
llvm-svn: 196050
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 41 |
2 files changed, 26 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index e995ae1c36e..7b901d2df87 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -7436,7 +7436,8 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, NamedDecl *Prev = *P; if (!HasExplicitTemplateArgs) { if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Prev)) { - if (Context.hasSameUnqualifiedType(Method->getType(), R)) { + QualType Adjusted = adjustCCAndNoReturn(R, Method->getType()); + if (Context.hasSameUnqualifiedType(Method->getType(), Adjusted)) { Matches.clear(); Matches.addDecl(Method, P.getAccess()); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 56df8bab9ba..8d66ff68efa 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3501,6 +3501,28 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( Specialization, Info, &OriginalCallArgs); } +QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, + QualType FunctionType) { + if (ArgFunctionType.isNull()) + return ArgFunctionType; + + const FunctionProtoType *FunctionTypeP = + FunctionType->castAs<FunctionProtoType>(); + CallingConv CC = FunctionTypeP->getCallConv(); + bool NoReturn = FunctionTypeP->getNoReturnAttr(); + const FunctionProtoType *ArgFunctionTypeP = + ArgFunctionType->getAs<FunctionProtoType>(); + if (ArgFunctionTypeP->getCallConv() == CC && + ArgFunctionTypeP->getNoReturnAttr() == NoReturn) + return ArgFunctionType; + + FunctionType::ExtInfo EI = ArgFunctionTypeP->getExtInfo().withCallingConv(CC); + EI = EI.withNoReturn(NoReturn); + ArgFunctionTypeP = + cast<FunctionProtoType>(Context.adjustFunctionType(ArgFunctionTypeP, EI)); + return QualType(ArgFunctionTypeP, 0); +} + /// \brief Deduce template arguments when taking the address of a function /// template (C++ [temp.deduct.funcaddr]) or matching a specialization to /// a template. @@ -3538,23 +3560,8 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, TemplateParameterList *TemplateParams = FunctionTemplate->getTemplateParameters(); QualType FunctionType = Function->getType(); - if (!InOverloadResolution && !ArgFunctionType.isNull()) { - const FunctionProtoType *FunctionTypeP = - FunctionType->castAs<FunctionProtoType>(); - CallingConv CC = FunctionTypeP->getCallConv(); - bool NoReturn = FunctionTypeP->getNoReturnAttr(); - const FunctionProtoType *ArgFunctionTypeP = - ArgFunctionType->getAs<FunctionProtoType>(); - if (ArgFunctionTypeP->getCallConv() != CC || - ArgFunctionTypeP->getNoReturnAttr() != NoReturn) { - FunctionType::ExtInfo EI = - ArgFunctionTypeP->getExtInfo().withCallingConv(CC); - EI = EI.withNoReturn(NoReturn); - ArgFunctionTypeP = cast<FunctionProtoType>( - Context.adjustFunctionType(ArgFunctionTypeP, EI)); - ArgFunctionType = QualType(ArgFunctionTypeP, 0); - } - } + if (!InOverloadResolution) + ArgFunctionType = adjustCCAndNoReturn(ArgFunctionType, FunctionType); // Substitute any explicit template arguments. LocalInstantiationScope InstScope(*this); |

