[cfe-commits] r74390 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/Sema/Sema.h lib/Sema/SemaLookup.cpp lib/Sema/SemaOverload.cpp test/SemaTemplate/operator-template.cpp

Douglas Gregor dgregor at apple.com
Sat Jun 27 14:05:07 PDT 2009


Author: dgregor
Date: Sat Jun 27 16:05:07 2009
New Revision: 74390

URL: http://llvm.org/viewvc/llvm-project?rev=74390&view=rev
Log:
Improve support for overloaded operator templates.

Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaTemplate/operator-template.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=74390&r1=74389&r2=74390&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Sat Jun 27 16:05:07 2009
@@ -32,6 +32,8 @@
 class AnyFunctionDecl {
   NamedDecl *Function;
   
+  AnyFunctionDecl(NamedDecl *ND) : Function(ND) { }
+  
 public:
   AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { }
   AnyFunctionDecl(FunctionTemplateDecl *FTD);
@@ -42,6 +44,10 @@
   
   /// \brief Retrieve the underlying function or function template.
   NamedDecl *get() const { return Function; }
+  
+  static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) { 
+    return AnyFunctionDecl(ND);
+  }
 };
   
 } // end namespace clang
@@ -57,6 +63,22 @@
   };
   template<> struct simplify_type< ::clang::AnyFunctionDecl>
   : public simplify_type<const ::clang::AnyFunctionDecl> {};
+  
+  // Provide PointerLikeTypeTraits for non-cvr pointers.
+  template<>
+  class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> {
+  public:
+    static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) {
+      return F.get(); 
+    }
+    static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) {
+      return ::clang::AnyFunctionDecl::getFromNamedDecl(
+                                      static_cast< ::clang::NamedDecl*>(P));
+    }
+    
+    enum { NumLowBitsAvailable = 2 };
+  };
+  
 } // end namespace llvm
 
 namespace clang {
@@ -91,24 +113,10 @@
   static OverloadedFunctionDecl *Create(ASTContext &C, DeclContext *DC,
                                         DeclarationName N);
 
-  /// addOverload - Add an overloaded function FD to this set of
-  /// overloaded functions.
-  void addOverload(FunctionDecl *FD) {
-    assert((FD->getDeclName() == getDeclName() ||
-            isa<CXXConversionDecl>(FD) || isa<CXXConstructorDecl>(FD)) &&
-           "Overloaded functions must have the same name");
-    Functions.push_back(FD);
-
-    // An overloaded function declaration always has the location of
-    // the most-recently-added function declaration.
-    if (FD->getLocation().isValid())
-      this->setLocation(FD->getLocation());
-  }
-
-  /// addOverload - Add an overloaded function template FTD to this set of
-  /// overloaded functions.
-  void addOverload(FunctionTemplateDecl *FTD);
-  
+  /// \brief Add a new overloaded function or function template to the set
+  /// of overloaded function templates.
+  void addOverload(AnyFunctionDecl F);
+
   function_iterator function_begin() { return Functions.begin(); }
   function_iterator function_end() { return Functions.end(); }
   function_const_iterator function_begin() const { return Functions.begin(); }

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=74390&r1=74389&r2=74390&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Sat Jun 27 16:05:07 2009
@@ -420,13 +420,9 @@
   return new (C) OverloadedFunctionDecl(DC, N);
 }
 
-void OverloadedFunctionDecl::addOverload(FunctionTemplateDecl *FTD) {
-  Functions.push_back(FTD);
-  
-  // An overloaded function declaration always has the location of
-  // the most-recently-added function declaration.
-  if (FTD->getLocation().isValid())
-    this->setLocation(FTD->getLocation());  
+void OverloadedFunctionDecl::addOverload(AnyFunctionDecl F) {
+  Functions.push_back(F);
+  this->setLocation(F.get()->getLocation());
 }
 
 LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Jun 27 16:05:07 2009
@@ -679,7 +679,7 @@
     OR_Deleted              ///< Overload resoltuion refers to a deleted function.
   };
 
-  typedef llvm::SmallPtrSet<FunctionDecl *, 16> FunctionSet;
+  typedef llvm::SmallPtrSet<AnyFunctionDecl, 16> FunctionSet;
   typedef llvm::SmallPtrSet<NamespaceDecl *, 16> AssociatedNamespaceSet;
   typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Sat Jun 27 16:05:07 2009
@@ -1604,9 +1604,17 @@
 
   for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end();
        Op != OpEnd; ++Op) {
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Op))
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Op)) {
       if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
         Functions.insert(FD); // FIXME: canonical FD
+    } else if (FunctionTemplateDecl *FunTmpl 
+                 = dyn_cast<FunctionTemplateDecl>(*Op)) {
+      // FIXME: friend operators?
+      // FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate, 
+      // later?
+      if (!FunTmpl->getDeclContext()->isRecord())
+        Functions.insert(FunTmpl);
+    }
   }
 }
 
@@ -1649,11 +1657,10 @@
     //        lookup (11.4).
     DeclContext::lookup_iterator I, E;
     for (llvm::tie(I, E) = (*NS)->lookup(Context, Name); I != E; ++I) {
-      FunctionDecl *Func = dyn_cast<FunctionDecl>(*I);
-      if (!Func)
-        break;
-
-      Functions.insert(Func);
+      if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*I))
+        Functions.insert(Func);
+      else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*I))
+        Functions.insert(FunTmpl);
     }
   }
   
@@ -1662,11 +1669,10 @@
     for (llvm::tie(I, E) 
            = Context.getTranslationUnitDecl()->lookup(Context, Name); 
          I != E; ++I) {
-      FunctionDecl *Func = dyn_cast<FunctionDecl>(*I);
-      if (!Func)
-        break;
-      
-      Functions.insert(Func);
+      if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*I))
+        Functions.insert(Func);
+      else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*I))
+        Functions.insert(FunTmpl);
     }
   }
 }

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Jun 27 16:05:07 2009
@@ -2161,9 +2161,15 @@
                                  bool SuppressUserConversions) {
   for (FunctionSet::const_iterator F = Functions.begin(), 
                                 FEnd = Functions.end();
-       F != FEnd; ++F)
-    AddOverloadCandidate(*F, Args, NumArgs, CandidateSet, 
-                         SuppressUserConversions);
+       F != FEnd; ++F) {
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*F))
+      AddOverloadCandidate(FD, Args, NumArgs, CandidateSet, 
+                           SuppressUserConversions);
+    else
+      AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*F), Args, 
+                                   NumArgs, CandidateSet, 
+                                   SuppressUserConversions);
+  }
 }
 
 /// AddMethodCandidate - Adds the given C++ member function to the set
@@ -3405,8 +3411,11 @@
   for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
                                    CandEnd = CandidateSet.end();
        Cand != CandEnd; ++Cand)
-    if (Cand->Function)
+    if (Cand->Function) {
       Functions.insert(Cand->Function);
+      if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate())
+        Functions.insert(FunTmpl);
+    }
 
   ArgumentDependentLookup(Name, Args, NumArgs, Functions);
 
@@ -3415,15 +3424,23 @@
   for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
                                    CandEnd = CandidateSet.end();
        Cand != CandEnd; ++Cand)
-    if (Cand->Function)
+    if (Cand->Function) {
       Functions.erase(Cand->Function);
+      if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate())
+        Functions.erase(FunTmpl);
+    }
 
   // For each of the ADL candidates we found, add it to the overload
   // set.
   for (FunctionSet::iterator Func = Functions.begin(),
                           FuncEnd = Functions.end();
-       Func != FuncEnd; ++Func)
-    AddOverloadCandidate(*Func, Args, NumArgs, CandidateSet);
+       Func != FuncEnd; ++Func) {
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func))
+      AddOverloadCandidate(FD, Args, NumArgs, CandidateSet);
+    else
+      AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func), Args, 
+                                   NumArgs, CandidateSet);
+  }
 }
 
 /// isBetterOverloadCandidate - Determines whether the first overload

Modified: cfe/trunk/test/SemaTemplate/operator-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/operator-template.cpp?rev=74390&r1=74389&r2=74390&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/operator-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/operator-template.cpp Sat Jun 27 16:05:07 2009
@@ -5,6 +5,8 @@
 template<class X>bool operator==(A<X>,typename A<X>::Y);
 int a(A<int> x) { return operator==(x,1); }
 
+int a0(A<int> x) { return x == 1; }
+
 // FIXME: The diagnostic here is a bit messed up
 template<class X>struct B{typedef X Y;};
 template<class X>bool operator==(B<X>*,typename B<X>::Y); // \





More information about the cfe-commits mailing list