[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