[cfe-commits] r160161 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/AST/TypePrinter.cpp lib/Sema/SemaDecl.cpp test/SemaTemplate/instantiate-method.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Thu Jul 12 21:12:04 PDT 2012
Author: rsmith
Date: Thu Jul 12 23:12:04 2012
New Revision: 160161
URL: http://llvm.org/viewvc/llvm-project?rev=160161&view=rev
Log:
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 *'.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/TypePrinter.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/SemaTemplate/instantiate-method.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=160161&r1=160160&r2=160161&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jul 12 23:12:04 2012
@@ -3799,6 +3799,8 @@
"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">;
Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=160161&r1=160160&r2=160161&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Thu Jul 12 23:12:04 2012
@@ -226,9 +226,17 @@
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
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=160161&r1=160160&r2=160161&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jul 12 23:12:04 2012
@@ -2063,22 +2063,27 @@
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
Modified: cfe/trunk/test/SemaTemplate/instantiate-method.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-method.cpp?rev=160161&r1=160160&r2=160161&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-method.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-method.cpp Thu Jul 12 23:12:04 2012
@@ -173,5 +173,12 @@
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}}
}
More information about the cfe-commits
mailing list