Fix a corner case with argument-dependent lookup and overloaded function sets.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74999 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2009-07-08 10:57:20 +00:00
Родитель 4668509630
Коммит daa439a6c4
4 изменённых файлов: 110 добавлений и 9 удалений

Просмотреть файл

@ -132,6 +132,56 @@ public:
}
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.
///

Просмотреть файл

@ -451,6 +451,39 @@ void OverloadedFunctionDecl::addOverload(AnyFunctionDecl F) {
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,

Просмотреть файл

@ -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 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
// 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;

Просмотреть файл

@ -14,3 +14,14 @@ namespace N3 {
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));
}