Diag(0) {
}
+ AccessedEntity(MemberNonce _,
+ CXXRecordDecl *NamingClass,
+ DeclAccessPair FoundDecl)
+ : Access(FoundDecl.getAccess()), IsMember(true),
+ Target(FoundDecl.getDecl()), NamingClass(NamingClass),
+ Diag(0) {
+ }
+
AccessedEntity(BaseNonce _,
CXXRecordDecl *BaseClass,
CXXRecordDecl *DerivedClass,
typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
void AddOverloadCandidate(NamedDecl *Function,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet &CandidateSet);
void AddOverloadCandidate(FunctionDecl *Function,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false);
- void AddMethodCandidate(NamedDecl *Decl, AccessSpecifier Access,
+ void AddMethodCandidate(DeclAccessPair FoundDecl,
QualType ObjectType,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversion = false,
bool ForceRValue = false);
- void AddMethodCandidate(CXXMethodDecl *Method, AccessSpecifier Access,
+ void AddMethodCandidate(CXXMethodDecl *Method,
+ DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext, QualType ObjectType,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
bool ForceRValue = false);
void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
const TemplateArgumentListInfo *ExplicitTemplateArgs,
QualType ObjectType,
bool SuppressUserConversions = false,
bool ForceRValue = false);
void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
const TemplateArgumentListInfo *ExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
bool ForceRValue = false);
void AddConversionCandidate(CXXConversionDecl *Conversion,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
Expr *From, QualType ToType,
OverloadCandidateSet& CandidateSet);
void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
Expr *From, QualType ToType,
OverloadCandidateSet &CandidateSet);
void AddSurrogateCandidate(CXXConversionDecl *Conversion,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
const FunctionProtoType *Proto,
QualType ObjectTy, Expr **Args, unsigned NumArgs,
AccessSpecifier LexicalAS);
AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
- NamedDecl *D,
- AccessSpecifier Access);
+ DeclAccessPair FoundDecl);
AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
- NamedDecl *D,
- AccessSpecifier Access);
+ DeclAccessPair FoundDecl);
AccessResult CheckAllocationAccess(SourceLocation OperatorLoc,
SourceRange PlacementRange,
CXXRecordDecl *NamingClass,
- NamedDecl *Allocator,
- AccessSpecifier Access);
+ DeclAccessPair FoundDecl);
AccessResult CheckConstructorAccess(SourceLocation Loc,
CXXConstructorDecl *D,
AccessSpecifier Access);
AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
Expr *ObjectExpr,
Expr *ArgExpr,
- NamedDecl *D,
- AccessSpecifier Access);
+ DeclAccessPair FoundDecl);
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc,
QualType Base, QualType Derived,
const CXXBasePath &Path,
S.Kind = SK_ResolveAddressOfOverloadedFunction;
S.Type = Function->getType();
// Access is currently ignored for these.
- S.Function = DeclAccessPair::make(Function, AccessSpecifier(0));
+ S.Function.Function = Function;
+ S.Function.FoundDecl = DeclAccessPair::make(Function, AS_none);
Steps.push_back(S);
}
}
void InitializationSequence::AddUserConversionStep(FunctionDecl *Function,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
QualType T) {
Step S;
S.Kind = SK_UserConversion;
S.Type = T;
- S.Function = DeclAccessPair::make(Function, Access);
+ S.Function.Function = Function;
+ S.Function.FoundDecl = FoundDecl;
Steps.push_back(S);
}
Step S;
S.Kind = SK_ConstructorInitialization;
S.Type = T;
- S.Function = DeclAccessPair::make(Constructor, Access);
+ S.Function.Function = Constructor;
+ S.Function.FoundDecl = DeclAccessPair::make(Constructor, Access);
Steps.push_back(S);
}
DeclContext::lookup_iterator Con, ConEnd;
for (llvm::tie(Con, ConEnd) = T1RecordDecl->lookup(ConstructorName);
Con != ConEnd; ++Con) {
+ NamedDecl *D = *Con;
+ DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
+
// Find the constructor (which may be a template).
CXXConstructorDecl *Constructor = 0;
- FunctionTemplateDecl *ConstructorTmpl
- = dyn_cast<FunctionTemplateDecl>(*Con);
+ FunctionTemplateDecl *ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D);
if (ConstructorTmpl)
Constructor = cast<CXXConstructorDecl>(
ConstructorTmpl->getTemplatedDecl());
else
- Constructor = cast<CXXConstructorDecl>(*Con);
+ Constructor = cast<CXXConstructorDecl>(D);
if (!Constructor->isInvalidDecl() &&
Constructor->isConvertingConstructor(AllowExplicit)) {
if (ConstructorTmpl)
- S.AddTemplateOverloadCandidate(ConstructorTmpl,
- ConstructorTmpl->getAccess(),
+ S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
/*ExplicitArgs*/ 0,
&Initializer, 1, CandidateSet);
else
- S.AddOverloadCandidate(Constructor, Constructor->getAccess(),
+ S.AddOverloadCandidate(Constructor, FoundDecl,
&Initializer, 1, CandidateSet);
}
}
if ((AllowExplicit || !Conv->isExplicit()) &&
(AllowRValues || Conv->getConversionType()->isLValueReferenceType())){
if (ConvTemplate)
- S.AddTemplateConversionCandidate(ConvTemplate, I.getAccess(),
+ S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
ActingDC, Initializer,
ToType, CandidateSet);
else
- S.AddConversionCandidate(Conv, I.getAccess(), ActingDC,
+ S.AddConversionCandidate(Conv, I.getPair(), ActingDC,
Initializer, ToType, CandidateSet);
}
}
T2 = cv1T1;
// Add the user-defined conversion step.
- Sequence.AddUserConversionStep(Function, Best->getAccess(),
+ Sequence.AddUserConversionStep(Function, Best->FoundDecl,
T2.getNonReferenceType());
// Determine whether we need to perform derived-to-base or
DeclContext::lookup_iterator Con, ConEnd;
for (llvm::tie(Con, ConEnd) = DestRecordDecl->lookup(ConstructorName);
Con != ConEnd; ++Con) {
+ NamedDecl *D = *Con;
+ DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
+
// Find the constructor (which may be a template).
CXXConstructorDecl *Constructor = 0;
- FunctionTemplateDecl *ConstructorTmpl
- = dyn_cast<FunctionTemplateDecl>(*Con);
+ FunctionTemplateDecl *ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D);
if (ConstructorTmpl)
Constructor = cast<CXXConstructorDecl>(
ConstructorTmpl->getTemplatedDecl());
else
- Constructor = cast<CXXConstructorDecl>(*Con);
+ Constructor = cast<CXXConstructorDecl>(D);
if (!Constructor->isInvalidDecl() &&
(AllowExplicit || !Constructor->isExplicit())) {
if (ConstructorTmpl)
- S.AddTemplateOverloadCandidate(ConstructorTmpl,
- ConstructorTmpl->getAccess(),
+ S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
/*ExplicitArgs*/ 0,
Args, NumArgs, CandidateSet);
else
- S.AddOverloadCandidate(Constructor, Constructor->getAccess(),
+ S.AddOverloadCandidate(Constructor, FoundDecl,
Args, NumArgs, CandidateSet);
}
}
// Add the constructor initialization step. Any cv-qualification conversion is
// subsumed by the initialization.
if (Kind.getKind() == InitializationKind::IK_Copy) {
- Sequence.AddUserConversionStep(Best->Function, Best->getAccess(), DestType);
+ Sequence.AddUserConversionStep(Best->Function, Best->FoundDecl, DestType);
} else {
Sequence.AddConstructorInitializationStep(
cast<CXXConstructorDecl>(Best->Function),
- Best->getAccess(),
+ Best->FoundDecl.getAccess(),
DestType);
}
}
DeclContext::lookup_iterator Con, ConEnd;
for (llvm::tie(Con, ConEnd) = DestRecordDecl->lookup(ConstructorName);
Con != ConEnd; ++Con) {
+ NamedDecl *D = *Con;
+ DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
+
// Find the constructor (which may be a template).
CXXConstructorDecl *Constructor = 0;
FunctionTemplateDecl *ConstructorTmpl
- = dyn_cast<FunctionTemplateDecl>(*Con);
+ = dyn_cast<FunctionTemplateDecl>(D);
if (ConstructorTmpl)
Constructor = cast<CXXConstructorDecl>(
ConstructorTmpl->getTemplatedDecl());
else
- Constructor = cast<CXXConstructorDecl>(*Con);
+ Constructor = cast<CXXConstructorDecl>(D);
if (!Constructor->isInvalidDecl() &&
Constructor->isConvertingConstructor(AllowExplicit)) {
if (ConstructorTmpl)
- S.AddTemplateOverloadCandidate(ConstructorTmpl,
- ConstructorTmpl->getAccess(),
+ S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
/*ExplicitArgs*/ 0,
&Initializer, 1, CandidateSet);
else
- S.AddOverloadCandidate(Constructor, Constructor->getAccess(),
+ S.AddOverloadCandidate(Constructor, FoundDecl,
&Initializer, 1, CandidateSet);
}
}
if (AllowExplicit || !Conv->isExplicit()) {
if (ConvTemplate)
- S.AddTemplateConversionCandidate(ConvTemplate, I.getAccess(),
+ S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
ActingDC, Initializer, DestType,
CandidateSet);
else
- S.AddConversionCandidate(Conv, I.getAccess(), ActingDC,
+ S.AddConversionCandidate(Conv, I.getPair(), ActingDC,
Initializer, DestType, CandidateSet);
}
}
if (isa<CXXConstructorDecl>(Function)) {
// Add the user-defined conversion step. Any cv-qualification conversion is
// subsumed by the initialization.
- Sequence.AddUserConversionStep(Function, Best->getAccess(), DestType);
+ Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType);
return;
}
// Add the user-defined conversion step that calls the conversion function.
QualType ConvType = Function->getResultType().getNonReferenceType();
- Sequence.AddUserConversionStep(Function, Best->getAccess(), ConvType);
+ Sequence.AddUserConversionStep(Function, Best->FoundDecl, ConvType);
// If the conversion following the call to the conversion function is
// interesting, add it as a separate step.
if (!Constructor || Constructor->isInvalidDecl() ||
!Constructor->isCopyConstructor())
continue;
-
- S.AddOverloadCandidate(Constructor, Constructor->getAccess(),
+
+ DeclAccessPair FoundDecl
+ = DeclAccessPair::make(Constructor, Constructor->getAccess());
+ S.AddOverloadCandidate(Constructor, FoundDecl,
&CurInitExpr, 1, CandidateSet);
}
return S.ExprError();
}
+ S.CheckConstructorAccess(Loc,
+ cast<CXXConstructorDecl>(Best->Function),
+ Best->FoundDecl.getAccess());
+
CurInit.release();
return S.BuildCXXConstructExpr(Loc, CurInitExpr->getType(),
cast<CXXConstructorDecl>(Best->Function),
// initializer to reflect that choice.
// Access control was done in overload resolution.
CurInit = S.FixOverloadedFunctionReference(move(CurInit),
- cast<FunctionDecl>(Step->Function.getDecl()));
+ Step->Function.Function);
break;
case SK_CastDerivedToBaseRValue:
// or a conversion function.
CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
bool IsCopy = false;
- FunctionDecl *Fn = cast<FunctionDecl>(Step->Function.getDecl());
- AccessSpecifier FnAccess = Step->Function.getAccess();
+ FunctionDecl *Fn = Step->Function.Function;
+ DeclAccessPair FoundFn = Step->Function.FoundDecl;
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Fn)) {
// Build a call to the selected constructor.
ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
if (CurInit.isInvalid())
return S.ExprError();
- S.CheckConstructorAccess(Kind.getLocation(), Constructor, FnAccess);
+ S.CheckConstructorAccess(Kind.getLocation(), Constructor,
+ FoundFn.getAccess());
CastKind = CastExpr::CK_ConstructorConversion;
QualType Class = S.Context.getTypeDeclType(Constructor->getParent());
CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
S.CheckMemberOperatorAccess(Kind.getLocation(), CurInitExpr, 0,
- Conversion, FnAccess);
+ FoundFn);
// FIXME: Should we move this initialization into a separate
// derived-to-base conversion? I believe the answer is "no", because
case SK_ConstructorInitialization: {
CXXConstructorDecl *Constructor
- = cast<CXXConstructorDecl>(Step->Function.getDecl());
+ = cast<CXXConstructorDecl>(Step->Function.Function);
// Build a call to the selected constructor.
ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
return S.ExprError();
// Only check access if all of that succeeded.
- S.CheckConstructorAccess(Loc, Constructor, Step->Function.getAccess());
+ S.CheckConstructorAccess(Loc, Constructor,
+ Step->Function.FoundDecl.getAccess());
bool Elidable
= cast<CXXConstructExpr>((Expr *)CurInit.get())->isElidable();
break;
case SK_UserConversion:
- OS << "user-defined conversion via " << S->Function->getNameAsString();
+ OS << "user-defined conversion via "
+ << S->Function.Function->getNameAsString();
break;
case SK_QualificationConversionRValue:
for (llvm::tie(Con, ConEnd)
= ToRecordDecl->lookup(ConstructorName);
Con != ConEnd; ++Con) {
+ NamedDecl *D = *Con;
+ DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
+
// Find the constructor (which may be a template).
CXXConstructorDecl *Constructor = 0;
FunctionTemplateDecl *ConstructorTmpl
- = dyn_cast<FunctionTemplateDecl>(*Con);
+ = dyn_cast<FunctionTemplateDecl>(D);
if (ConstructorTmpl)
Constructor
= cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl());
else
- Constructor = cast<CXXConstructorDecl>(*Con);
+ Constructor = cast<CXXConstructorDecl>(D);
if (!Constructor->isInvalidDecl() &&
Constructor->isConvertingConstructor(AllowExplicit)) {
if (ConstructorTmpl)
- AddTemplateOverloadCandidate(ConstructorTmpl,
- ConstructorTmpl->getAccess(),
+ AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
/*ExplicitArgs*/ 0,
&From, 1, CandidateSet,
SuppressUserConversions, ForceRValue);
else
// Allow one user-defined conversion when user specifies a
// From->ToType conversion via an static cast (c-style, etc).
- AddOverloadCandidate(Constructor, Constructor->getAccess(),
+ AddOverloadCandidate(Constructor, FoundDecl,
&From, 1, CandidateSet,
SuppressUserConversions, ForceRValue);
}
= FromRecordDecl->getVisibleConversionFunctions();
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
- NamedDecl *D = *I;
+ DeclAccessPair FoundDecl = I.getPair();
+ NamedDecl *D = FoundDecl.getDecl();
CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
if (isa<UsingShadowDecl>(D))
D = cast<UsingShadowDecl>(D)->getTargetDecl();
if (AllowExplicit || !Conv->isExplicit()) {
if (ConvTemplate)
- AddTemplateConversionCandidate(ConvTemplate, I.getAccess(),
+ AddTemplateConversionCandidate(ConvTemplate, FoundDecl,
ActingContext, From, ToType,
CandidateSet);
else
- AddConversionCandidate(Conv, I.getAccess(), ActingContext,
+ AddConversionCandidate(Conv, FoundDecl, ActingContext,
From, ToType, CandidateSet);
}
}
/// code completion.
void
Sema::AddOverloadCandidate(FunctionDecl *Function,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions,
// function, e.g., X::f(). We use an empty type for the implied
// object argument (C++ [over.call.func]p3), and the acting context
// is irrelevant.
- AddMethodCandidate(Method, Access, Method->getParent(),
+ AddMethodCandidate(Method, FoundDecl, Method->getParent(),
QualType(), Args, NumArgs, CandidateSet,
SuppressUserConversions, ForceRValue);
return;
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
+ Candidate.FoundDecl = FoundDecl;
Candidate.Function = Function;
- Candidate.Access = Access;
Candidate.Viable = true;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions) {
for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) {
- // FIXME: using declarations
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*F)) {
+ NamedDecl *D = F.getDecl()->getUnderlyingDecl();
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic())
- AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getAccess(),
+ AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(),
cast<CXXMethodDecl>(FD)->getParent(),
Args[0]->getType(), Args + 1, NumArgs - 1,
CandidateSet, SuppressUserConversions);
else
- AddOverloadCandidate(FD, AS_none, Args, NumArgs, CandidateSet,
+ AddOverloadCandidate(FD, F.getPair(), Args, NumArgs, CandidateSet,
SuppressUserConversions);
} else {
- FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(*F);
+ FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(D);
if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) &&
!cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic())
- AddMethodTemplateCandidate(FunTmpl, F.getAccess(),
+ AddMethodTemplateCandidate(FunTmpl, F.getPair(),
cast<CXXRecordDecl>(FunTmpl->getDeclContext()),
/*FIXME: explicit args */ 0,
Args[0]->getType(), Args + 1, NumArgs - 1,
CandidateSet,
SuppressUserConversions);
else
- AddTemplateOverloadCandidate(FunTmpl, AS_none,
+ AddTemplateOverloadCandidate(FunTmpl, F.getPair(),
/*FIXME: explicit args */ 0,
Args, NumArgs, CandidateSet,
SuppressUserConversions);
/// AddMethodCandidate - Adds a named decl (which is some kind of
/// method) as a method candidate to the given overload set.
-void Sema::AddMethodCandidate(NamedDecl *Decl,
- AccessSpecifier Access,
+void Sema::AddMethodCandidate(DeclAccessPair FoundDecl,
QualType ObjectType,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions, bool ForceRValue) {
+ NamedDecl *Decl = FoundDecl.getDecl();
CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(Decl->getDeclContext());
if (isa<UsingShadowDecl>(Decl))
if (FunctionTemplateDecl *TD = dyn_cast<FunctionTemplateDecl>(Decl)) {
assert(isa<CXXMethodDecl>(TD->getTemplatedDecl()) &&
"Expected a member function template");
- AddMethodTemplateCandidate(TD, Access, ActingContext, /*ExplicitArgs*/ 0,
+ AddMethodTemplateCandidate(TD, FoundDecl, ActingContext,
+ /*ExplicitArgs*/ 0,
ObjectType, Args, NumArgs,
CandidateSet,
SuppressUserConversions,
ForceRValue);
} else {
- AddMethodCandidate(cast<CXXMethodDecl>(Decl), Access, ActingContext,
+ AddMethodCandidate(cast<CXXMethodDecl>(Decl), FoundDecl, ActingContext,
ObjectType, Args, NumArgs,
CandidateSet, SuppressUserConversions, ForceRValue);
}
/// a slightly hacky way to implement the overloading rules for elidable copy
/// initialization in C++0x (C++0x 12.8p15).
void
-Sema::AddMethodCandidate(CXXMethodDecl *Method, AccessSpecifier Access,
+Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext, QualType ObjectType,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
+ Candidate.FoundDecl = FoundDecl;
Candidate.Function = Method;
- Candidate.Access = Access;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
/// function template specialization.
void
Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
const TemplateArgumentListInfo *ExplicitTemplateArgs,
QualType ObjectType,
assert(Specialization && "Missing member function template specialization?");
assert(isa<CXXMethodDecl>(Specialization) &&
"Specialization is not a member function?");
- AddMethodCandidate(cast<CXXMethodDecl>(Specialization), Access,
+ AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl,
ActingContext, ObjectType, Args, NumArgs,
CandidateSet, SuppressUserConversions, ForceRValue);
}
/// an appropriate function template specialization.
void
Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
const TemplateArgumentListInfo *ExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
Args, NumArgs, Specialization, Info)) {
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate &Candidate = CandidateSet.back();
+ Candidate.FoundDecl = FoundDecl;
Candidate.Function = FunctionTemplate->getTemplatedDecl();
- Candidate.Access = Access;
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_bad_deduction;
Candidate.IsSurrogate = false;
// Add the function template specialization produced by template argument
// deduction as a candidate.
assert(Specialization && "Missing function template specialization?");
- AddOverloadCandidate(Specialization, Access, Args, NumArgs, CandidateSet,
+ AddOverloadCandidate(Specialization, FoundDecl, Args, NumArgs, CandidateSet,
SuppressUserConversions, ForceRValue);
}
/// conversion function produces).
void
Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
Expr *From, QualType ToType,
OverloadCandidateSet& CandidateSet) {
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
+ Candidate.FoundDecl = FoundDecl;
Candidate.Function = Conversion;
- Candidate.Access = Access;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.FinalConversion.setAsIdentityConversion();
/// [temp.deduct.conv]).
void
Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
CXXRecordDecl *ActingDC,
Expr *From, QualType ToType,
OverloadCandidateSet &CandidateSet) {
// Add the conversion function template specialization produced by
// template argument deduction as a candidate.
assert(Specialization && "Missing function template specialization?");
- AddConversionCandidate(Specialization, Access, ActingDC, From, ToType,
+ AddConversionCandidate(Specialization, FoundDecl, ActingDC, From, ToType,
CandidateSet);
}
/// with the given arguments (C++ [over.call.object]p2-4). Proto is
/// the type of function that we'll eventually be calling.
void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
const FunctionProtoType *Proto,
QualType ObjectType,
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
+ Candidate.FoundDecl = FoundDecl;
Candidate.Function = 0;
- Candidate.Access = Access;
Candidate.Surrogate = Conversion;
Candidate.Viable = true;
Candidate.IsSurrogate = true;
OperEnd = Operators.end();
Oper != OperEnd;
++Oper)
- AddMethodCandidate(*Oper, Oper.getAccess(), Args[0]->getType(),
+ AddMethodCandidate(Oper.getPair(), Args[0]->getType(),
Args + 1, NumArgs - 1, CandidateSet,
/* SuppressUserConversions = */ false);
}
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
+ Candidate.FoundDecl = DeclAccessPair::make(0, AS_none);
Candidate.Function = 0;
- Candidate.Access = AS_none;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.BuiltinTypes.ResultTy = ResultTy;
// For each of the ADL candidates we found, add it to the overload
// set.
for (ADLResult::iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) {
+ DeclAccessPair FoundDecl = DeclAccessPair::make(*I, AS_none);
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
if (ExplicitTemplateArgs)
continue;
- AddOverloadCandidate(FD, AS_none, Args, NumArgs, CandidateSet,
+ AddOverloadCandidate(FD, FoundDecl, Args, NumArgs, CandidateSet,
false, false, PartialOverloading);
} else
AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*I),
- AS_none, ExplicitTemplateArgs,
+ FoundDecl, ExplicitTemplateArgs,
Args, NumArgs, CandidateSet);
}
}
}
}
-static bool CheckUnresolvedAccess(Sema &S, OverloadExpr *E, NamedDecl *D,
- AccessSpecifier AS) {
+static bool CheckUnresolvedAccess(Sema &S, OverloadExpr *E, DeclAccessPair D) {
if (isa<UnresolvedLookupExpr>(E))
- return S.CheckUnresolvedLookupAccess(cast<UnresolvedLookupExpr>(E), D, AS);
+ return S.CheckUnresolvedLookupAccess(cast<UnresolvedLookupExpr>(E), D);
- return S.CheckUnresolvedMemberAccess(cast<UnresolvedMemberExpr>(E), D, AS);
+ return S.CheckUnresolvedMemberAccess(cast<UnresolvedMemberExpr>(E), D);
}
/// ResolveAddressOfOverloadedFunction - Try to resolve the address of
// Look through all of the overloaded functions, searching for one
// whose type matches exactly.
- UnresolvedSet<4> Matches; // contains only FunctionDecls
+ llvm::SmallVector<std::pair<DeclAccessPair, FunctionDecl*>, 4> Matches;
bool FoundNonTemplateFunction = false;
for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
E = OvlExpr->decls_end(); I != E; ++I) {
// a candidate? Find a testcase before changing the code.
assert(FunctionType
== Context.getCanonicalType(Specialization->getType()));
- Matches.addDecl(cast<FunctionDecl>(Specialization->getCanonicalDecl()),
- I.getAccess());
+ Matches.push_back(std::make_pair(I.getPair(),
+ cast<FunctionDecl>(Specialization->getCanonicalDecl())));
}
continue;
if (Context.hasSameUnqualifiedType(FunctionType, FunDecl->getType()) ||
IsNoReturnConversion(Context, FunDecl->getType(), FunctionType,
ResultTy)) {
- Matches.addDecl(cast<FunctionDecl>(FunDecl->getCanonicalDecl()),
- I.getAccess());
+ Matches.push_back(std::make_pair(I.getPair(),
+ cast<FunctionDecl>(FunDecl->getCanonicalDecl())));
FoundNonTemplateFunction = true;
}
}
if (Matches.empty())
return 0;
else if (Matches.size() == 1) {
- FunctionDecl *Result = cast<FunctionDecl>(*Matches.begin());
+ FunctionDecl *Result = Matches[0].second;
MarkDeclarationReferenced(From->getLocStart(), Result);
if (Complain)
- CheckUnresolvedAccess(*this, OvlExpr, Result, Matches.begin().getAccess());
+ CheckUnresolvedAccess(*this, OvlExpr, Matches[0].first);
return Result;
}
// two-pass algorithm (similar to the one used to identify the
// best viable function in an overload set) that identifies the
// best function template (if it exists).
+
+ UnresolvedSet<4> MatchesCopy; // TODO: avoid!
+ for (unsigned I = 0, E = Matches.size(); I != E; ++I)
+ MatchesCopy.addDecl(Matches[I].second, Matches[I].first.getAccess());
UnresolvedSetIterator Result =
- getMostSpecialized(Matches.begin(), Matches.end(),
+ getMostSpecialized(MatchesCopy.begin(), MatchesCopy.end(),
TPOC_Other, From->getLocStart(),
PDiag(),
PDiag(diag::err_addr_ovl_ambiguous)
- << Matches[0]->getDeclName(),
+ << Matches[0].second->getDeclName(),
PDiag(diag::note_ovl_candidate)
<< (unsigned) oc_function_template);
- assert(Result != Matches.end() && "no most-specialized template");
+ assert(Result != MatchesCopy.end() && "no most-specialized template");
MarkDeclarationReferenced(From->getLocStart(), *Result);
- if (Complain)
- CheckUnresolvedAccess(*this, OvlExpr, *Result, Result.getAccess());
+ if (Complain) {
+ DeclAccessPair FoundDecl = Matches[Result - MatchesCopy.begin()].first;
+ CheckUnresolvedAccess(*this, OvlExpr, FoundDecl);
+ }
return cast<FunctionDecl>(*Result);
}
// [...] any function template specializations in the set are
// eliminated if the set also contains a non-template function, [...]
for (unsigned I = 0, N = Matches.size(); I != N; ) {
- if (cast<FunctionDecl>(Matches[I].getDecl())->getPrimaryTemplate() == 0)
+ if (Matches[I].second->getPrimaryTemplate() == 0)
++I;
else {
- Matches.erase(I);
- --N;
+ Matches[I] = Matches[--N];
+ Matches.set_size(N);
}
}
// [...] After such eliminations, if any, there shall remain exactly one
// selected function.
if (Matches.size() == 1) {
- UnresolvedSetIterator Match = Matches.begin();
- MarkDeclarationReferenced(From->getLocStart(), *Match);
+ MarkDeclarationReferenced(From->getLocStart(), Matches[0].second);
if (Complain)
- CheckUnresolvedAccess(*this, OvlExpr, *Match, Match.getAccess());
- return cast<FunctionDecl>(*Match);
+ CheckUnresolvedAccess(*this, OvlExpr, Matches[0].first);
+ return cast<FunctionDecl>(Matches[0].second);
}
// FIXME: We should probably return the same thing that BestViableFunction
// returns (even if we issue the diagnostics here).
Diag(From->getLocStart(), diag::err_addr_ovl_ambiguous)
- << Matches[0]->getDeclName();
- for (UnresolvedSetIterator I = Matches.begin(),
- E = Matches.end(); I != E; ++I)
- NoteOverloadCandidate(cast<FunctionDecl>(*I));
+ << Matches[0].second->getDeclName();
+ for (unsigned I = 0, E = Matches.size(); I != E; ++I)
+ NoteOverloadCandidate(Matches[I].second);
return 0;
}
/// \brief Add a single candidate to the overload set.
static void AddOverloadedCallCandidate(Sema &S,
- NamedDecl *Callee,
- AccessSpecifier Access,
+ DeclAccessPair FoundDecl,
const TemplateArgumentListInfo *ExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet &CandidateSet,
bool PartialOverloading) {
+ NamedDecl *Callee = FoundDecl.getDecl();
if (isa<UsingShadowDecl>(Callee))
Callee = cast<UsingShadowDecl>(Callee)->getTargetDecl();
if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Callee)) {
assert(!ExplicitTemplateArgs && "Explicit template arguments?");
- S.AddOverloadCandidate(Func, Access, Args, NumArgs, CandidateSet,
+ S.AddOverloadCandidate(Func, FoundDecl, Args, NumArgs, CandidateSet,
false, false, PartialOverloading);
return;
}
if (FunctionTemplateDecl *FuncTemplate
= dyn_cast<FunctionTemplateDecl>(Callee)) {
- S.AddTemplateOverloadCandidate(FuncTemplate, Access, ExplicitTemplateArgs,
+ S.AddTemplateOverloadCandidate(FuncTemplate, FoundDecl,
+ ExplicitTemplateArgs,
Args, NumArgs, CandidateSet);
return;
}
for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(),
E = ULE->decls_end(); I != E; ++I)
- AddOverloadedCallCandidate(*this, *I, I.getAccess(), ExplicitTemplateArgs,
+ AddOverloadedCallCandidate(*this, I.getPair(), ExplicitTemplateArgs,
Args, NumArgs, CandidateSet,
PartialOverloading);
switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) {
case OR_Success: {
FunctionDecl *FDecl = Best->Function;
- CheckUnresolvedLookupAccess(ULE, FDecl, Best->getAccess());
+ CheckUnresolvedLookupAccess(ULE, Best->FoundDecl);
Fn = FixOverloadedFunctionReference(Fn, FDecl);
return BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs, RParenLoc);
}
// Convert the arguments.
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
- CheckMemberOperatorAccess(OpLoc, Args[0], 0, Method, Best->getAccess());
+ CheckMemberOperatorAccess(OpLoc, Args[0], 0, Best->FoundDecl);
if (PerformObjectArgumentInitialization(Input, /*Qualifier=*/0, Method))
return ExprError();
// Convert the arguments.
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
// Best->Access is only meaningful for class members.
- CheckMemberOperatorAccess(OpLoc, Args[0], Args[1], Method,
- Best->getAccess());
+ CheckMemberOperatorAccess(OpLoc, Args[0], Args[1], Best->FoundDecl);
OwningExprResult Arg1
= PerformCopyInitialization(
// We matched an overloaded operator. Build a call to that
// operator.
- CheckMemberOperatorAccess(LLoc, Args[0], Args[1], FnDecl,
- Best->getAccess());
+ CheckMemberOperatorAccess(LLoc, Args[0], Args[1], Best->FoundDecl);
// Convert the arguments.
CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
if (TemplateArgs)
continue;
- AddMethodCandidate(Method, I.getAccess(), ActingDC, ObjectType,
+ AddMethodCandidate(Method, I.getPair(), ActingDC, ObjectType,
Args, NumArgs,
CandidateSet, /*SuppressUserConversions=*/false);
} else {
AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(Func),
- I.getAccess(), ActingDC, TemplateArgs,
+ I.getPair(), ActingDC, TemplateArgs,
ObjectType, Args, NumArgs,
CandidateSet,
/*SuppressUsedConversions=*/false);
switch (BestViableFunction(CandidateSet, UnresExpr->getLocStart(), Best)) {
case OR_Success:
Method = cast<CXXMethodDecl>(Best->Function);
- CheckUnresolvedMemberAccess(UnresExpr, Method, Best->getAccess());
+ CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
break;
case OR_No_Viable_Function:
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper) {
- AddMethodCandidate(*Oper, Oper.getAccess(), Object->getType(),
+ AddMethodCandidate(Oper.getPair(), Object->getType(),
Args, NumArgs, CandidateSet,
/*SuppressUserConversions=*/ false);
}
ConvType = ConvPtrType->getPointeeType();
if (const FunctionProtoType *Proto = ConvType->getAs<FunctionProtoType>())
- AddSurrogateCandidate(Conv, I.getAccess(), ActingContext, Proto,
+ AddSurrogateCandidate(Conv, I.getPair(), ActingContext, Proto,
Object->getType(), Args, NumArgs,
CandidateSet);
}
= cast<CXXConversionDecl>(
Best->Conversions[0].UserDefined.ConversionFunction);
- CheckMemberOperatorAccess(LParenLoc, Object, 0, Conv, Best->getAccess());
+ CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
// We selected one of the surrogate functions that converts the
// object parameter to a function pointer. Perform the conversion
CommaLocs, RParenLoc).release();
}
- CheckMemberOperatorAccess(LParenLoc, Object, 0,
- Best->Function, Best->getAccess());
+ CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
// We found an overloaded operator(). Build a CXXOperatorCallExpr
// that calls this method, using Object for the implicit object
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper) {
- NamedDecl *D = *Oper;
- CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
- if (isa<UsingShadowDecl>(D))
- D = cast<UsingShadowDecl>(D)->getTargetDecl();
-
- AddMethodCandidate(cast<CXXMethodDecl>(D), Oper.getAccess(), ActingContext,
- Base->getType(), 0, 0, CandidateSet,
+ AddMethodCandidate(Oper.getPair(), Base->getType(), 0, 0, CandidateSet,
/*SuppressUserConversions=*/false);
}
return ExprError();
}
+ CheckMemberOperatorAccess(OpLoc, Base, 0, Best->FoundDecl);
+
// Convert the object parameter.
CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
if (PerformObjectArgumentInitialization(Base, /*Qualifier=*/0, Method))