[cfe-commits] r83889 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaOverload.cpp test/SemaCXX/ambiguous-builtin-unary-operator.cpp

Fariborz Jahanian fjahanian at apple.com
Mon Oct 12 13:11:40 PDT 2009


Author: fjahanian
Date: Mon Oct 12 15:11:40 2009
New Revision: 83889

URL: http://llvm.org/viewvc/llvm-project?rev=83889&view=rev
Log:
Handle built-in unary operators when reporting ambiguities.
wip - To prune excessive reporting.


Added:
    cfe/trunk/test/SemaCXX/ambiguous-builtin-unary-operator.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaOverload.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=83889&r1=83888&r2=83889&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct 12 15:11:40 2009
@@ -786,7 +786,10 @@
   "candidate function template specialization %0">;
 def err_ovl_candidate_deleted : Note<
   "candidate function has been explicitly %select{made unavailable|deleted}0">;
-def err_ovl_builtin_candidate : Note<"built-in candidate operator %2 (%0, %1)">;
+def err_ovl_builtin_binary_candidate : Note<
+    "built-in candidate operator %0 (%1, %2)">;
+def err_ovl_builtin_unary_candidate : Note<
+    "built-in candidate operator %0 (%1)">;
 def err_ovl_no_viable_function_in_init : Error<
   "no matching constructor for initialization of %0">;
 def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">;

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=83889&r1=83888&r2=83889&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Oct 12 15:11:40 2009
@@ -916,7 +916,7 @@
                                        OverloadCandidateSet::iterator& Best);
   void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
                          bool OnlyViable,
-                         BinaryOperator::Opcode Opc=(BinaryOperator::Opcode)0,
+                         const char *Opc=0,
                          SourceLocation Loc=SourceLocation());
 
   FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=83889&r1=83888&r2=83889&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Oct 12 15:11:40 2009
@@ -3973,7 +3973,7 @@
 void
 Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
                               bool OnlyViable,
-                              BinaryOperator::Opcode Opc,
+                              const char *Opc,
                               SourceLocation OpLoc) {
   OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
                              LastCand = CandidateSet.end();
@@ -4048,20 +4048,22 @@
         Diag(Cand->Surrogate->getLocation(), diag::err_ovl_surrogate_cand)
           << FnType;
       } else if (OnlyViable) {
-        assert(Cand->Conversions.size() == 2 && 
+        assert(Cand->Conversions.size() <= 2 && 
                "builtin-binary-operator-not-binary");
-        Diag(OpLoc, diag::err_ovl_builtin_candidate) 
-          << Cand->BuiltinTypes.ParamTypes[0] 
-          << Cand->BuiltinTypes.ParamTypes[1] 
-          << BinaryOperator::getOpcodeStr(Opc);
+        if (Cand->Conversions.size() == 1)
+          Diag(OpLoc, diag::err_ovl_builtin_unary_candidate)
+                << Opc << Cand->BuiltinTypes.ParamTypes[0];
+        else
+          Diag(OpLoc, diag::err_ovl_builtin_binary_candidate)
+                << Opc << Cand->BuiltinTypes.ParamTypes[0]
+                << Cand->BuiltinTypes.ParamTypes[1];
       }
       else if (!Cand->Viable && !Reported) {
         // Non-viability might be due to ambiguous user-defined conversions,
         // needed for built-in operators. Report them as well, but only once
         // as we have typically many built-in candidates.
-        assert(Cand->Conversions.size() == 2 &&
-               "builtin-binary-operator-not-binary");
-        for (unsigned ArgIdx = 0; ArgIdx < 2; ++ArgIdx) {
+        unsigned NoOperands = Cand->Conversions.size();
+        for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) {
           const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx];
           if (ICS.ConversionKind != ImplicitConversionSequence::BadConversion ||
               ICS.ConversionFunctionSet.empty())
@@ -4559,7 +4561,8 @@
       Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
           << UnaryOperator::getOpcodeStr(Opc)
           << Input->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+      PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true, 
+                              UnaryOperator::getOpcodeStr(Opc), OpLoc);
       return ExprError();
 
     case OR_Deleted:
@@ -4733,7 +4736,8 @@
       assert(Result.isInvalid() && 
              "C++ binary operator overloading is missing candidates!");
       if (Result.isInvalid())
-        PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false, Opc, OpLoc);
+        PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false, 
+                                BinaryOperator::getOpcodeStr(Opc), OpLoc);
       return move(Result);
     }
 
@@ -4741,7 +4745,8 @@
       Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
           << BinaryOperator::getOpcodeStr(Opc)
           << Args[0]->getSourceRange() << Args[1]->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true, Opc, OpLoc);
+      PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true, 
+                              BinaryOperator::getOpcodeStr(Opc), OpLoc);
       return ExprError();
 
     case OR_Deleted:

Added: cfe/trunk/test/SemaCXX/ambiguous-builtin-unary-operator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/ambiguous-builtin-unary-operator.cpp?rev=83889&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/ambiguous-builtin-unary-operator.cpp (added)
+++ cfe/trunk/test/SemaCXX/ambiguous-builtin-unary-operator.cpp Mon Oct 12 15:11:40 2009
@@ -0,0 +1,18 @@
+// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x
+
+struct A {
+  operator int&();
+};
+
+struct B {
+  operator long&();
+};
+
+struct C : B, A { };
+
+void test(C c) {
+  ++c; // expected-error {{use of overloaded operator '++' is ambiguous}}\
+       // expected-note 4 {{built-in candidate operator ++ (}}
+}
+
+





More information about the cfe-commits mailing list