class AnyFunctionDecl {
NamedDecl *Function;
+ AnyFunctionDecl(NamedDecl *ND) : Function(ND) { }
+
public:
AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { }
AnyFunctionDecl(FunctionTemplateDecl *FTD);
/// \brief Retrieve the underlying function or function template.
NamedDecl *get() const { return Function; }
+
+ static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) {
+ return AnyFunctionDecl(ND);
+ }
};
} // end namespace clang
};
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 {
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());
- }
+ /// \brief Add a new overloaded function or function template to the set
+ /// of overloaded function templates.
+ void addOverload(AnyFunctionDecl F);
- /// addOverload - Add an overloaded function template FTD to this set of
- /// overloaded functions.
- void addOverload(FunctionTemplateDecl *FTD);
-
function_iterator function_begin() { return Functions.begin(); }
function_iterator function_end() { return Functions.end(); }
function_const_iterator function_begin() const { return Functions.begin(); }
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,
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;
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);
+ }
}
}
// 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);
}
}
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);
}
}
}
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
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);
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
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); // \