summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-09-10 01:04:45 +0000
committerReid Kleckner <reid@kleckner.net>2013-09-10 01:04:45 +0000
commit76808056f9be85effe5103d69453bb3b24450b2f (patch)
treeb43a512f561ee5579399ac66933eb64fedfc09e3 /clang/lib/Sema
parentd232222f347d6e8406522e540e76ab89d83e469d (diff)
downloadbcm5719-llvm-76808056f9be85effe5103d69453bb3b24450b2f.tar.gz
bcm5719-llvm-76808056f9be85effe5103d69453bb3b24450b2f.zip
Ignore calling conventions when checking function template specializations
Summary: Calling conventions are inherited during decl merging. Before this change, deduction would fail due to a type mismatch between the template and the specialization. This change adjusts the CCs to match before deduction, and lets the decl merging logic diagnose mismatch or inherit the CC from the template. This allows specializations of static member function templates in the Microsoft C++ ABI. Reviewers: rsmith CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1570 llvm-svn: 190377
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 015d9d8ce94..b6313307c42 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -6403,11 +6403,11 @@ bool Sema::CheckFunctionTemplateSpecialization(
// it will be a static member function until we know which template it
// specializes), so adjust it now assuming it specializes this template.
QualType FT = FD->getType();
+ const FunctionProtoType *FPT = FT->castAs<FunctionProtoType>();
+ FunctionDecl *TmplFD = FunTmpl->getTemplatedDecl();
if (FD->isConstexpr()) {
- CXXMethodDecl *OldMD =
- dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
+ CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(TmplFD);
if (OldMD && OldMD->isConst()) {
- const FunctionProtoType *FPT = FT->castAs<FunctionProtoType>();
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.TypeQuals |= Qualifiers::Const;
FT = Context.getFunctionType(FPT->getResultType(), FPT->getArgTypes(),
@@ -6415,6 +6415,16 @@ bool Sema::CheckFunctionTemplateSpecialization(
}
}
+ // Ignore differences in calling convention until decl merging.
+ const FunctionProtoType *TmplFT =
+ TmplFD->getType()->castAs<FunctionProtoType>();
+ if (FPT->getCallConv() != TmplFT->getCallConv()) {
+ FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
+ EPI.ExtInfo = EPI.ExtInfo.withCallingConv(TmplFT->getCallConv());
+ FT = Context.getFunctionType(FPT->getResultType(), FPT->getArgTypes(),
+ EPI);
+ }
+
// C++ [temp.expl.spec]p11:
// A trailing template-argument can be left unspecified in the
// template-id naming an explicit function template specialization
OpenPOWER on IntegriCloud