[cfe-commits] r74999 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/Sema/SemaLookup.cpp test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp

Douglas Gregor dgregor at apple.com
Wed Jul 8 03:57:37 PDT 2009


Author: dgregor
Date: Wed Jul  8 05:57:20 2009
New Revision: 74999

URL: http://llvm.org/viewvc/llvm-project?rev=74999&view=rev
Log:
Fix a corner case with argument-dependent lookup and overloaded function sets.

Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Wed Jul  8 05:57:20 2009
@@ -132,6 +132,56 @@
   }
   static bool classof(const OverloadedFunctionDecl *D) { return true; }
 };
+  
+/// \brief Provides uniform iteration syntax for an overload set, function, 
+/// or function template.
+class OverloadIterator {
+  /// \brief An overloaded function set, function declaration, or
+  /// function template declaration.
+  NamedDecl *D;
+  
+  /// \brief If the declaration is an overloaded function set, this is the
+  /// iterator pointing to the current position within that overloaded
+  /// function set.
+  OverloadedFunctionDecl::function_iterator Iter;
+  
+public:
+  typedef AnyFunctionDecl value_type;
+  typedef value_type      reference;
+  typedef NamedDecl      *pointer;
+  typedef int             difference_type;
+  typedef std::forward_iterator_tag iterator_category;
+  
+  OverloadIterator() : D(0) { }
+  
+  OverloadIterator(FunctionDecl *FD) : D(FD) { }
+  OverloadIterator(FunctionTemplateDecl *FTD) 
+    : D(reinterpret_cast<NamedDecl*>(FTD)) { }
+  OverloadIterator(OverloadedFunctionDecl *Ovl) 
+    : D(Ovl), Iter(Ovl->function_begin()) { }
+  
+  reference operator*() const;
+  
+  pointer operator->() const { return (**this).get(); }
+  
+  OverloadIterator &operator++();
+  
+  OverloadIterator operator++(int) {
+    OverloadIterator Temp(*this);
+    ++(*this);
+    return Temp;
+  }
+  
+  bool Equals(const OverloadIterator &Other) const;
+};
+  
+inline bool operator==(const OverloadIterator &X, const OverloadIterator &Y) {
+  return X.Equals(Y);
+}
+
+inline bool operator!=(const OverloadIterator &X, const OverloadIterator &Y) {
+  return !(X == Y);
+}
 
 /// CXXBaseSpecifier - A base class of a C++ class.
 ///

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

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Jul  8 05:57:20 2009
@@ -451,6 +451,39 @@
   this->setLocation(F.get()->getLocation());
 }
 
+OverloadIterator::reference OverloadIterator::operator*() const {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+    return FD;
+  
+  if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
+    return FTD;
+  
+  assert(isa<OverloadedFunctionDecl>(D));
+  return *Iter;
+}
+
+OverloadIterator &OverloadIterator::operator++() {
+  if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) {
+    D = 0;
+    return *this;
+  }
+  
+  if (++Iter == cast<OverloadedFunctionDecl>(D)->function_end())
+    D = 0;
+  
+  return *this;
+}
+
+bool OverloadIterator::Equals(const OverloadIterator &Other) const {
+  if (!D || !Other.D)
+    return D == Other.D;
+  
+  if (D != Other.D)
+    return false;
+  
+  return !isa<OverloadedFunctionDecl>(D) || Iter == Other.Iter;
+}
+
 LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
                                          DeclContext *DC, 
                                          SourceLocation L,

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Jul  8 05:57:20 2009
@@ -19,6 +19,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/LangOptions.h"
@@ -1579,18 +1580,24 @@
     // classes and namespaces associated with its (non-dependent)
     // parameter types and return type.
     DeclRefExpr *DRE = 0;
+    TemplateIdRefExpr *TIRE = 0;
+    Arg = Arg->IgnoreParens();
     if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg)) {
-      if (unaryOp->getOpcode() == UnaryOperator::AddrOf)
+      if (unaryOp->getOpcode() == UnaryOperator::AddrOf) {
         DRE = dyn_cast<DeclRefExpr>(unaryOp->getSubExpr());
-    } else
+        TIRE = dyn_cast<TemplateIdRefExpr>(unaryOp->getSubExpr());
+      }
+    } else {
       DRE = dyn_cast<DeclRefExpr>(Arg);
-    if (!DRE)
-      continue;
-
-    // FIXME: The declaration might be a FunctionTemplateDecl (by itself)
-    // or might be buried in a TemplateIdRefExpr.
-    OverloadedFunctionDecl *Ovl 
-      = dyn_cast<OverloadedFunctionDecl>(DRE->getDecl());
+      TIRE = dyn_cast<TemplateIdRefExpr>(Arg);
+    }
+    
+    OverloadedFunctionDecl *Ovl = 0;
+    if (DRE)
+      Ovl = dyn_cast<OverloadedFunctionDecl>(DRE->getDecl());
+    else if (TIRE)
+      Ovl = dyn_cast_or_null<OverloadedFunctionDecl>(
+                                  TIRE->getTemplateName().getAsTemplateDecl());
     if (!Ovl)
       continue;
 

Modified: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp?rev=74999&r1=74998&r2=74999&view=diff

==============================================================================
--- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp (original)
+++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-template-id.cpp Wed Jul  8 05:57:20 2009
@@ -14,3 +14,14 @@
     int &ir = f((N2::Y<N1::X>*)0);
   }
 }
+
+int g(void *);
+long g(N1::X);
+
+namespace N1 {
+  void h(int (*)(void *));
+}
+
+void test() {
+  h((&g));
+}





More information about the cfe-commits mailing list