forked from OSchip/llvm-project
In Microsoft mode, allow template function explicit specialization at class scope.
Necessary to parse MFC and MSVC standard lib code. Example: struct X { template<class T> void f(T) { } template<> void f(int) { } } llvm-svn: 131347
This commit is contained in:
parent
6db38ae05c
commit
6744e14d9c
|
@ -1775,6 +1775,9 @@ def err_template_spec_decl_function_scope : Error<
|
|||
"explicit specialization of %0 in function scope">;
|
||||
def err_template_spec_decl_class_scope : Error<
|
||||
"explicit specialization of %0 in class scope">;
|
||||
def war_template_spec_decl_class_scope : ExtWarn<
|
||||
"Allowing explicit specialization of %0 in class scope is a Microsoft "
|
||||
"extension">, InGroup<Microsoft>;
|
||||
def err_template_spec_decl_friend : Error<
|
||||
"cannot declare an explicit specialization in a friend">;
|
||||
def err_template_spec_decl_out_of_scope_global : Error<
|
||||
|
|
|
@ -1685,10 +1685,14 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
|
|||
if (OldMethod && NewMethod) {
|
||||
// Preserve triviality.
|
||||
NewMethod->setTrivial(OldMethod->isTrivial());
|
||||
|
||||
|
||||
// MSVC allows explicit template specialization at class scope.
|
||||
bool IsMSExplicitSpecialization = getLangOptions().Microsoft &&
|
||||
NewMethod->isFunctionTemplateSpecialization();
|
||||
bool isFriend = NewMethod->getFriendObjectKind();
|
||||
|
||||
if (!isFriend && NewMethod->getLexicalDeclContext()->isRecord()) {
|
||||
if (!isFriend && NewMethod->getLexicalDeclContext()->isRecord() &&
|
||||
!IsMSExplicitSpecialization) {
|
||||
// -- Member function declarations with the same name and the
|
||||
// same parameter types cannot be overloaded if any of them
|
||||
// is a static member function declaration.
|
||||
|
|
|
@ -4401,9 +4401,12 @@ static bool CheckTemplateSpecializationScope(Sema &S,
|
|||
}
|
||||
|
||||
if (S.CurContext->isRecord() && !IsPartialSpecialization) {
|
||||
S.Diag(Loc, diag::err_template_spec_decl_class_scope)
|
||||
<< Specialized;
|
||||
return true;
|
||||
if (S.getLangOptions().Microsoft)
|
||||
S.Diag(Loc, diag::war_template_spec_decl_class_scope) << Specialized;
|
||||
else {
|
||||
S.Diag(Loc, diag::err_template_spec_decl_class_scope) << Specialized;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// C++ [temp.class.spec]p6:
|
||||
|
|
|
@ -197,3 +197,10 @@ void pointer_to_integral_type_conv(char* ptr) {
|
|||
ch = (char)ptr;
|
||||
sh = (short)ptr;
|
||||
}
|
||||
|
||||
|
||||
struct X1 {
|
||||
template<typename T> void f(T);
|
||||
|
||||
template<> void f(int) { } // expected-warning{{Allowing explicit specialization of 'f' in class scope is a Microsoft extension}}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue