зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
4668509630
Коммит
daa439a6c4
|
@ -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));
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче