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:
Francois Pichet 2011-05-14 17:46:46 +00:00
parent 6db38ae05c
commit 6744e14d9c
4 changed files with 22 additions and 5 deletions

View File

@ -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<

View File

@ -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.

View File

@ -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:

View File

@ -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}}
};