[cfe-commits] r90939 - in /cfe/trunk/lib/Sema: Sema.h SemaDecl.cpp SemaOverload.cpp

John McCall rjmccall at apple.com
Tue Dec 8 19:35:25 PST 2009


Author: rjmccall
Date: Tue Dec  8 21:35:25 2009
New Revision: 90939

URL: http://llvm.org/viewvc/llvm-project?rev=90939&view=rev
Log:
Rename Sema::IsOverload to Sema::CheckOverload.  Teach it to ignore unresolved
using value decls;  we optimistically assume they won't turn into conflicts.
Teach it to tell the caller *why* the function doesn't overload with the returned
decl;  this will be useful for using hiding.


Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Dec  8 21:35:25 2009
@@ -832,8 +832,22 @@
   bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
 
   /// C++ Overloading.
-  bool IsOverload(FunctionDecl *New, LookupResult &OldDecls,
-                  NamedDecl *&OldDecl);
+  enum OverloadKind {
+    /// This is a legitimate overload: the existing declarations are
+    /// functions or function templates with different signatures.
+    Ovl_Overload,
+
+    /// This is not an overload because the signature exactly matches
+    /// an existing declaration.
+    Ovl_Match,
+
+    /// This is not an overload because the lookup results contain a
+    /// non-function.
+    Ovl_NonFunction
+  };
+  OverloadKind CheckOverload(FunctionDecl *New,
+                             LookupResult &OldDecls,
+                             NamedDecl *&OldDecl);
   bool IsOverload(FunctionDecl *New, FunctionDecl *Old);
 
   ImplicitConversionSequence

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Dec  8 21:35:25 2009
@@ -3165,34 +3165,44 @@
     // there's no more work to do here; we'll just add the new
     // function to the scope.
 
-    if (!getLangOptions().CPlusPlus &&
-        AllowOverloadingOfFunction(Previous, Context)) {
-      OverloadableAttrRequired = true;
-
-      // Functions marked "overloadable" must have a prototype (that
-      // we can't get through declaration merging).
-      if (!NewFD->getType()->getAs<FunctionProtoType>()) {
-        Diag(NewFD->getLocation(), diag::err_attribute_overloadable_no_prototype)
-          << NewFD;
-        Redeclaration = true;
+    NamedDecl *OldDecl = 0;
+    if (!AllowOverloadingOfFunction(Previous, Context)) {
+      Redeclaration = true;
+      OldDecl = Previous.getFoundDecl();
+    } else {
+      if (!getLangOptions().CPlusPlus) {
+        OverloadableAttrRequired = true;
 
-        // Turn this into a variadic function with no parameters.
-        QualType R = Context.getFunctionType(
-                       NewFD->getType()->getAs<FunctionType>()->getResultType(),
-                       0, 0, true, 0);
-        NewFD->setType(R);
-        return NewFD->setInvalidDecl();
+        // Functions marked "overloadable" must have a prototype (that
+        // we can't get through declaration merging).
+        if (!NewFD->getType()->getAs<FunctionProtoType>()) {
+          Diag(NewFD->getLocation(),
+               diag::err_attribute_overloadable_no_prototype)
+            << NewFD;
+          Redeclaration = true;
+
+          // Turn this into a variadic function with no parameters.
+          QualType R = Context.getFunctionType(
+                     NewFD->getType()->getAs<FunctionType>()->getResultType(),
+                     0, 0, true, 0);
+          NewFD->setType(R);
+          return NewFD->setInvalidDecl();
+        }
       }
-    }
 
-    NamedDecl *OldDecl = 0;
-    if (!Previous.empty()) {
-      if (!AllowOverloadingOfFunction(Previous, Context)) {
+      switch (CheckOverload(NewFD, Previous, OldDecl)) {
+      case Ovl_Match:
+        // FIXME: hide or conflict with using shadow decls as appropriate
+        Redeclaration = !isa<UsingShadowDecl>(OldDecl);
+        break;
+
+      case Ovl_NonFunction:
         Redeclaration = true;
-        OldDecl = Previous.getFoundDecl();
-      } else if (!IsOverload(NewFD, Previous, OldDecl)) {
-        if (!isUsingDecl(OldDecl))
-          Redeclaration = true;
+        break;
+
+      case Ovl_Overload:
+        Redeclaration = false;
+        break;
       }
     }
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Dec  8 21:35:25 2009
@@ -262,9 +262,9 @@
 // New and Old cannot be overloaded, e.g., if New has the same
 // signature as some function in Old (C++ 1.3.10) or if the Old
 // declarations aren't functions (or function templates) at all. When
-// it does return false and Old is an overload set, MatchedDecl will
-// be set to point to the FunctionDecl that New cannot be overloaded
-// with.
+// it does return false, MatchedDecl will point to the decl that New
+// cannot be overloaded with.  This decl may be a UsingShadowDecl on
+// top of the underlying declaration.
 //
 // Example: Given the following input:
 //
@@ -286,31 +286,33 @@
 // identical (return types of functions are not part of the
 // signature), IsOverload returns false and MatchedDecl will be set to
 // point to the FunctionDecl for #2.
-bool
-Sema::IsOverload(FunctionDecl *New, LookupResult &Old, NamedDecl *&Match) {
+Sema::OverloadKind
+Sema::CheckOverload(FunctionDecl *New, LookupResult &Old, NamedDecl *&Match) {
   for (LookupResult::iterator I = Old.begin(), E = Old.end();
          I != E; ++I) {
     NamedDecl *OldD = (*I)->getUnderlyingDecl();
     if (FunctionTemplateDecl *OldT = dyn_cast<FunctionTemplateDecl>(OldD)) {
       if (!IsOverload(New, OldT->getTemplatedDecl())) {
-        Match = OldT;
-        return false;
+        Match = *I;
+        return Ovl_Match;
       }
     } else if (FunctionDecl *OldF = dyn_cast<FunctionDecl>(OldD)) {
       if (!IsOverload(New, OldF)) {
-        Match = OldF;
-        return false;
+        Match = *I;
+        return Ovl_Match;
       }
-    } else {
+    } else if (!isa<UnresolvedUsingValueDecl>(OldD)) {
       // (C++ 13p1):
       //   Only function declarations can be overloaded; object and type
       //   declarations cannot be overloaded.
-      Match = OldD;
-      return false;
+      // But we permit unresolved using value decls and diagnose the error
+      // during template instantiation.
+      Match = *I;
+      return Ovl_NonFunction;
     }
   }
 
-  return true;
+  return Ovl_Overload;
 }
 
 bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old) {





More information about the cfe-commits mailing list