mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 01:06:06 +00:00
Make explicit specializations at class scope work
for non-type template parameters in microsoft mode. PR12709. llvm-svn: 159147
This commit is contained in:
parent
07594cba7c
commit
7b5a716f3d
@ -2086,23 +2086,33 @@ class ClassScopeFunctionSpecializationDecl : public Decl {
|
||||
virtual void anchor();
|
||||
|
||||
ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
|
||||
CXXMethodDecl *FD)
|
||||
CXXMethodDecl *FD, bool Args,
|
||||
TemplateArgumentListInfo TemplArgs)
|
||||
: Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
|
||||
Specialization(FD) {}
|
||||
Specialization(FD), HasExplicitTemplateArgs(Args),
|
||||
TemplateArgs(TemplArgs) {}
|
||||
|
||||
ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
|
||||
: Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
|
||||
|
||||
CXXMethodDecl *Specialization;
|
||||
bool HasExplicitTemplateArgs;
|
||||
TemplateArgumentListInfo TemplateArgs;
|
||||
|
||||
public:
|
||||
CXXMethodDecl *getSpecialization() const { return Specialization; }
|
||||
bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
|
||||
const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
|
||||
|
||||
static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
|
||||
DeclContext *DC,
|
||||
SourceLocation Loc,
|
||||
CXXMethodDecl *FD) {
|
||||
return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD);
|
||||
CXXMethodDecl *FD,
|
||||
bool HasExplicitTemplateArgs,
|
||||
TemplateArgumentListInfo TemplateArgs) {
|
||||
return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD,
|
||||
HasExplicitTemplateArgs,
|
||||
TemplateArgs);
|
||||
}
|
||||
|
||||
static ClassScopeFunctionSpecializationDecl *
|
||||
|
@ -1283,7 +1283,13 @@ DEF_TRAVERSE_DECL(FriendTemplateDecl, {
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
|
||||
TRY_TO(TraverseDecl(D->getSpecialization()));
|
||||
TRY_TO(TraverseDecl(D->getSpecialization()));
|
||||
|
||||
if (D->hasExplicitTemplateArgs()) {
|
||||
const TemplateArgumentListInfo& args = D->templateArgs();
|
||||
TRY_TO(TraverseTemplateArgumentLocsHelper(
|
||||
args.getArgumentArray(), args.size()));
|
||||
}
|
||||
})
|
||||
|
||||
DEF_TRAVERSE_DECL(LinkageSpecDecl, { })
|
||||
|
@ -869,5 +869,6 @@ ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
|
||||
unsigned ID) {
|
||||
void *Mem = AllocateDeserializedDecl(C, ID,
|
||||
sizeof(ClassScopeFunctionSpecializationDecl));
|
||||
return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0);
|
||||
return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
|
||||
false, TemplateArgumentListInfo());
|
||||
}
|
||||
|
@ -5066,7 +5066,11 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
||||
FunctionTemplateDecl *FunctionTemplate = 0;
|
||||
bool isExplicitSpecialization = false;
|
||||
bool isFunctionTemplateSpecialization = false;
|
||||
|
||||
bool isDependentClassScopeExplicitSpecialization = false;
|
||||
bool HasExplicitTemplateArgs = false;
|
||||
TemplateArgumentListInfo TemplateArgs;
|
||||
|
||||
bool isVirtualOkay = false;
|
||||
|
||||
FunctionDecl *NewFD = CreateNewFunctionDecl(*this, D, DC, R, TInfo, SC,
|
||||
@ -5509,8 +5513,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
||||
} else {
|
||||
// If the declarator is a template-id, translate the parser's template
|
||||
// argument list into our AST format.
|
||||
bool HasExplicitTemplateArgs = false;
|
||||
TemplateArgumentListInfo TemplateArgs;
|
||||
if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
|
||||
TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
|
||||
TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
|
||||
@ -5814,8 +5816,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
||||
if (isDependentClassScopeExplicitSpecialization) {
|
||||
ClassScopeFunctionSpecializationDecl *NewSpec =
|
||||
ClassScopeFunctionSpecializationDecl::Create(
|
||||
Context, CurContext, SourceLocation(),
|
||||
cast<CXXMethodDecl>(NewFD));
|
||||
Context, CurContext, SourceLocation(),
|
||||
cast<CXXMethodDecl>(NewFD),
|
||||
HasExplicitTemplateArgs, TemplateArgs);
|
||||
CurContext->addDecl(NewSpec);
|
||||
AddToScope = false;
|
||||
}
|
||||
|
@ -1952,13 +1952,22 @@ Decl * TemplateDeclInstantiator
|
||||
Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl(
|
||||
ClassScopeFunctionSpecializationDecl *Decl) {
|
||||
CXXMethodDecl *OldFD = Decl->getSpecialization();
|
||||
CXXMethodDecl *NewFD = cast<CXXMethodDecl>(VisitCXXMethodDecl(OldFD, 0, true));
|
||||
CXXMethodDecl *NewFD = cast<CXXMethodDecl>(VisitCXXMethodDecl(OldFD,
|
||||
0, true));
|
||||
|
||||
LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName,
|
||||
Sema::ForRedeclaration);
|
||||
|
||||
TemplateArgumentListInfo TemplateArgs;
|
||||
TemplateArgumentListInfo* TemplateArgsPtr = 0;
|
||||
if (Decl->hasExplicitTemplateArgs()) {
|
||||
TemplateArgs = Decl->templateArgs();
|
||||
TemplateArgsPtr = &TemplateArgs;
|
||||
}
|
||||
|
||||
SemaRef.LookupQualifiedName(Previous, SemaRef.CurContext);
|
||||
if (SemaRef.CheckFunctionTemplateSpecialization(NewFD, 0, Previous)) {
|
||||
if (SemaRef.CheckFunctionTemplateSpecialization(NewFD, TemplateArgsPtr,
|
||||
Previous)) {
|
||||
NewFD->setInvalidDecl();
|
||||
return NewFD;
|
||||
}
|
||||
|
@ -69,3 +69,24 @@ void test2()
|
||||
b.f(100);
|
||||
}
|
||||
|
||||
|
||||
namespace PR12709 {
|
||||
|
||||
template<class T>
|
||||
class TemplateClass {
|
||||
void member_function() {
|
||||
specialized_member_template<false>();
|
||||
}
|
||||
|
||||
template<bool b>
|
||||
void specialized_member_template() {}
|
||||
|
||||
template<>
|
||||
void specialized_member_template<false>() {} // expected-warning{{explicit specialization of 'specialized_member_template' within class scope is a Microsoft extension}}
|
||||
};
|
||||
|
||||
void f() {
|
||||
TemplateClass<int> t;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user