зеркало из https://github.com/microsoft/clang-1.git
Provide a special-case diagnostic when two class member functions instantiate
to the same signature. Fix a bug in the type printer which would cause this diagnostic to print wonderful types like 'const const int *'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160161 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
d3d02dd0ae
Коммит
838925dc84
|
@ -3799,6 +3799,8 @@ def note_enum_specialized_here : Note<
|
|||
"enum %0 was explicitly specialized here">;
|
||||
|
||||
def err_member_redeclared : Error<"class member cannot be redeclared">;
|
||||
def err_member_redeclared_in_instantiation : Error<
|
||||
"multiple overloads of %0 instantiate to the same signature %1">;
|
||||
def err_member_name_of_class : Error<"member %0 has the same name as its class">;
|
||||
def err_member_def_undefined_record : Error<
|
||||
"out-of-line definition of %0 from class %1 without definition">;
|
||||
|
|
|
@ -226,9 +226,17 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
|
|||
return CanPrefixQualifiers;
|
||||
}
|
||||
|
||||
void TypePrinter::printBefore(QualType t, raw_ostream &OS) {
|
||||
SplitQualType split = t.split();
|
||||
printBefore(split.Ty, split.Quals, OS);
|
||||
void TypePrinter::printBefore(QualType T, raw_ostream &OS) {
|
||||
SplitQualType Split = T.split();
|
||||
|
||||
// If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
|
||||
// at this level.
|
||||
Qualifiers Quals = Split.Quals;
|
||||
if (const SubstTemplateTypeParmType *Subst =
|
||||
dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
|
||||
Quals -= QualType(Subst, 0).getQualifiers();
|
||||
|
||||
printBefore(Split.Ty, Quals, OS);
|
||||
}
|
||||
|
||||
/// \brief Prints the part of the type string before an identifier, e.g. for
|
||||
|
|
|
@ -2063,22 +2063,27 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) {
|
|||
Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// C++ [class.mem]p1:
|
||||
// [...] A member shall not be declared twice in the
|
||||
// member-specification, except that a nested class or member
|
||||
// class template can be declared and then later defined.
|
||||
unsigned NewDiag;
|
||||
if (isa<CXXConstructorDecl>(OldMethod))
|
||||
NewDiag = diag::err_constructor_redeclared;
|
||||
else if (isa<CXXDestructorDecl>(NewMethod))
|
||||
NewDiag = diag::err_destructor_redeclared;
|
||||
else if (isa<CXXConversionDecl>(NewMethod))
|
||||
NewDiag = diag::err_conv_function_redeclared;
|
||||
else
|
||||
NewDiag = diag::err_member_redeclared;
|
||||
if (ActiveTemplateInstantiations.empty()) {
|
||||
unsigned NewDiag;
|
||||
if (isa<CXXConstructorDecl>(OldMethod))
|
||||
NewDiag = diag::err_constructor_redeclared;
|
||||
else if (isa<CXXDestructorDecl>(NewMethod))
|
||||
NewDiag = diag::err_destructor_redeclared;
|
||||
else if (isa<CXXConversionDecl>(NewMethod))
|
||||
NewDiag = diag::err_conv_function_redeclared;
|
||||
else
|
||||
NewDiag = diag::err_member_redeclared;
|
||||
|
||||
Diag(New->getLocation(), NewDiag);
|
||||
Diag(New->getLocation(), NewDiag);
|
||||
} else {
|
||||
Diag(New->getLocation(), diag::err_member_redeclared_in_instantiation)
|
||||
<< New << New->getType();
|
||||
}
|
||||
Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
|
||||
|
||||
// Complain if this is an explicit declaration of a special
|
||||
|
|
|
@ -173,5 +173,12 @@ namespace PR7022 {
|
|||
typedef X2<> X2_type;
|
||||
X2_type c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace SameSignatureAfterInstantiation {
|
||||
template<typename T> struct S {
|
||||
void f(T *); // expected-note {{previous}}
|
||||
void f(const T*); // expected-error {{multiple overloads of 'f' instantiate to the same signature 'void (const int *)'}}
|
||||
};
|
||||
S<const int> s; // expected-note {{instantiation}}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче