]> granicus.if.org Git - clang/commitdiff
Provide a special-case diagnostic when two class member functions instantiate
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 13 Jul 2012 04:12:04 +0000 (04:12 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 13 Jul 2012 04:12:04 +0000 (04:12 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
lib/AST/TypePrinter.cpp
lib/Sema/SemaDecl.cpp
test/SemaTemplate/instantiate-method.cpp

index 769285a0b8d9fd80d9f65b40386daf82a10739b9..b08b3428194f3c9c8e976d0fd67c8ebb28ec37d4 100644 (file)
@@ -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">;
index 7567a7331113ec8fca6da2f35824c408bab4b1d8..c42117c82bf5a36b265f81f844c67c8810c1facf 100644 (file)
@@ -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
index f00ed8279be4ec1e8f92f963347969fe859115a0..cbf2368f7123b0008ab795afd3375d9dafba7ba8 100644 (file)
@@ -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
index 363115d1844e5069b02d171b04bc5011e9eff0b7..5e9da3f688e8b910d0ea8be2949c188762490dda 100644 (file)
@@ -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}}
 }