diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/Sema.h | 39 | ||||
-rw-r--r-- | lib/Sema/SemaAccess.cpp | 44 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 25 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 96 | ||||
-rw-r--r-- | lib/Sema/SemaInit.h | 7 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 186 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.h | 14 |
9 files changed, 224 insertions, 201 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 6c655e55b4..747fd88978 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -321,6 +321,14 @@ public: 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, @@ -1131,12 +1139,12 @@ public: 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, @@ -1146,20 +1154,21 @@ public: 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, @@ -1168,24 +1177,24 @@ public: 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, @@ -2623,16 +2632,13 @@ public: 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); @@ -2645,8 +2651,7 @@ public: 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, diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index 171ed3783e..40b320c1be 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -527,15 +527,13 @@ void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *Ctx) { } Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, - NamedDecl *D, - AccessSpecifier Access) { + DeclAccessPair Found) { if (!getLangOptions().AccessControl || !E->getNamingClass() || - Access == AS_public) + Found.getAccess() == AS_public) return AR_accessible; - AccessedEntity Entity(AccessedEntity::Member, - E->getNamingClass(), Access, D); + AccessedEntity Entity(AccessedEntity::Member, E->getNamingClass(), Found); Entity.setDiag(diag::err_access) << E->getSourceRange(); return CheckAccess(*this, E->getNameLoc(), Entity); @@ -544,14 +542,12 @@ Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, /// Perform access-control checking on a previously-unresolved member /// access which has now been resolved to a member. Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, - NamedDecl *D, - AccessSpecifier Access) { + DeclAccessPair Found) { if (!getLangOptions().AccessControl || - Access == AS_public) + Found.getAccess() == AS_public) return AR_accessible; - AccessedEntity Entity(AccessedEntity::Member, - E->getNamingClass(), Access, D); + AccessedEntity Entity(AccessedEntity::Member, E->getNamingClass(), Found); Entity.setDiag(diag::err_access) << E->getSourceRange(); return CheckAccess(*this, E->getMemberLoc(), Entity); @@ -569,7 +565,8 @@ Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc, return AR_accessible; CXXRecordDecl *NamingClass = Dtor->getParent(); - AccessedEntity Entity(AccessedEntity::Member, NamingClass, Access, Dtor); + AccessedEntity Entity(AccessedEntity::Member, NamingClass, + DeclAccessPair::make(Dtor, Access)); Entity.setDiag(PDiag); // TODO: avoid copy return CheckAccess(*this, Loc, Entity); @@ -584,8 +581,8 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc, return AR_accessible; CXXRecordDecl *NamingClass = Constructor->getParent(); - AccessedEntity Entity(AccessedEntity::Member, - NamingClass, Access, Constructor); + AccessedEntity Entity(AccessedEntity::Member, NamingClass, + DeclAccessPair::make(Constructor, Access)); Entity.setDiag(diag::err_access_ctor); return CheckAccess(*this, UseLoc, Entity); @@ -602,7 +599,8 @@ Sema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc, return AR_accessible; CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Target->getDeclContext()); - AccessedEntity Entity(AccessedEntity::Member, NamingClass, Access, Target); + AccessedEntity Entity(AccessedEntity::Member, NamingClass, + DeclAccessPair::make(Target, Access)); Entity.setDiag(Diag); return CheckAccess(*this, UseLoc, Entity); } @@ -612,14 +610,13 @@ Sema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc, Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc, SourceRange PlacementRange, CXXRecordDecl *NamingClass, - NamedDecl *Fn, - AccessSpecifier Access) { + DeclAccessPair Found) { if (!getLangOptions().AccessControl || !NamingClass || - Access == AS_public) + Found.getAccess() == AS_public) return AR_accessible; - AccessedEntity Entity(AccessedEntity::Member, NamingClass, Access, Fn); + AccessedEntity Entity(AccessedEntity::Member, NamingClass, Found); Entity.setDiag(diag::err_access) << PlacementRange; @@ -631,18 +628,16 @@ Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc, Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, Expr *ObjectExpr, Expr *ArgExpr, - NamedDecl *MemberOperator, - AccessSpecifier Access) { + DeclAccessPair Found) { if (!getLangOptions().AccessControl || - Access == AS_public) + Found.getAccess() == AS_public) return AR_accessible; const RecordType *RT = ObjectExpr->getType()->getAs<RecordType>(); assert(RT && "found member operator but object expr not of record type"); CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl()); - AccessedEntity Entity(AccessedEntity::Member, - NamingClass, Access, MemberOperator); + AccessedEntity Entity(AccessedEntity::Member, NamingClass, Found); Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange()); @@ -694,7 +689,8 @@ void Sema::CheckLookupAccess(const LookupResult &R) { for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { if (I.getAccess() != AS_public) { AccessedEntity Entity(AccessedEntity::Member, - R.getNamingClass(), I.getAccess(), *I); + R.getNamingClass(), + I.getPair()); Entity.setDiag(diag::err_access); CheckAccess(*this, R.getNameLoc(), Entity); diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 4693fa974e..317eef8d60 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -2253,7 +2253,8 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn, Results.push_back(ResultCandidate(FDecl)); else // FIXME: access? - AddOverloadCandidate(FDecl, AS_none, Args, NumArgs, CandidateSet, + AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none), + Args, NumArgs, CandidateSet, false, false, /*PartialOverloading*/ true); } } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index c0b699a518..13a7ead76b 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -4204,6 +4204,8 @@ static void AddConstructorInitializationCandidates(Sema &SemaRef, DeclContext::lookup_const_iterator Con, ConEnd; for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(ConstructorName); Con != ConEnd; ++Con) { + DeclAccessPair FoundDecl = DeclAccessPair::make(*Con, (*Con)->getAccess()); + // Find the constructor (which may be a template). CXXConstructorDecl *Constructor = 0; FunctionTemplateDecl *ConstructorTmpl= dyn_cast<FunctionTemplateDecl>(*Con); @@ -4220,12 +4222,11 @@ static void AddConstructorInitializationCandidates(Sema &SemaRef, ((Kind.getKind() == InitializationKind::IK_Default) && Constructor->isDefaultConstructor())) { if (ConstructorTmpl) - SemaRef.AddTemplateOverloadCandidate(ConstructorTmpl, - ConstructorTmpl->getAccess(), + SemaRef.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, /*ExplicitArgs*/ 0, Args, NumArgs, CandidateSet); else - SemaRef.AddOverloadCandidate(Constructor, Constructor->getAccess(), + SemaRef.AddOverloadCandidate(Constructor, FoundDecl, Args, NumArgs, CandidateSet); } } @@ -4535,10 +4536,10 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, if (Conv->getConversionType()->isLValueReferenceType() && (AllowExplicit || !Conv->isExplicit())) { if (ConvTemplate) - AddTemplateConversionCandidate(ConvTemplate, I.getAccess(), ActingDC, + AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC, Init, DeclType, CandidateSet); else - AddConversionCandidate(Conv, I.getAccess(), ActingDC, Init, + AddConversionCandidate(Conv, I.getPair(), ActingDC, Init, DeclType, CandidateSet); } } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 2a55894f22..366089f2ab 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -921,7 +921,9 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, } FoundDelete.suppressDiagnostics(); - UnresolvedSet<4> Matches; + + llvm::SmallVector<std::pair<DeclAccessPair,FunctionDecl*>, 2> Matches; + if (NumPlaceArgs > 0) { // C++ [expr.new]p20: // A declaration of a placement deallocation function matches the @@ -964,7 +966,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, Fn = cast<FunctionDecl>((*D)->getUnderlyingDecl()); if (Context.hasSameType(Fn->getType(), ExpectedFunctionType)) - Matches.addDecl(Fn, D.getAccess()); + Matches.push_back(std::make_pair(D.getPair(), Fn)); } } else { // C++ [expr.new]p20: @@ -975,7 +977,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, D != DEnd; ++D) { if (FunctionDecl *Fn = dyn_cast<FunctionDecl>((*D)->getUnderlyingDecl())) if (isNonPlacementDeallocationFunction(Fn)) - Matches.addDecl(D.getDecl(), D.getAccess()); + Matches.push_back(std::make_pair(D.getPair(), Fn)); } } @@ -984,7 +986,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, // function, that function will be called; otherwise, no // deallocation function will be called. if (Matches.size() == 1) { - OperatorDelete = cast<FunctionDecl>(Matches[0]->getUnderlyingDecl()); + OperatorDelete = Matches[0].second; // C++0x [expr.new]p20: // If the lookup finds the two-parameter form of a usual @@ -1001,7 +1003,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, << DeleteName; } else { CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(), - Matches[0].getDecl(), Matches[0].getAccess()); + Matches[0].first); } } @@ -1033,18 +1035,18 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, Alloc != AllocEnd; ++Alloc) { // Even member operator new/delete are implicitly treated as // static, so don't use AddMemberCandidate. + NamedDecl *D = (*Alloc)->getUnderlyingDecl(); - if (FunctionTemplateDecl *FnTemplate = - dyn_cast<FunctionTemplateDecl>((*Alloc)->getUnderlyingDecl())) { - AddTemplateOverloadCandidate(FnTemplate, Alloc.getAccess(), + if (FunctionTemplateDecl *FnTemplate = dyn_cast<FunctionTemplateDecl>(D)) { + AddTemplateOverloadCandidate(FnTemplate, Alloc.getPair(), /*ExplicitTemplateArgs=*/0, Args, NumArgs, Candidates, /*SuppressUserConversions=*/false); continue; } - FunctionDecl *Fn = cast<FunctionDecl>((*Alloc)->getUnderlyingDecl()); - AddOverloadCandidate(Fn, Alloc.getAccess(), Args, NumArgs, Candidates, + FunctionDecl *Fn = cast<FunctionDecl>(D); + AddOverloadCandidate(Fn, Alloc.getPair(), Args, NumArgs, Candidates, /*SuppressUserConversions=*/false); } @@ -1066,8 +1068,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, return true; } Operator = FnDecl; - CheckAllocationAccess(StartLoc, Range, R.getNamingClass(), - FnDecl, Best->getAccess()); + CheckAllocationAccess(StartLoc, Range, R.getNamingClass(), Best->FoundDecl); return false; } diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 98a7eec232..f86ae51c28 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2007,7 +2007,8 @@ void InitializationSequence::AddAddressOverloadResolutionStep( 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); } @@ -2028,12 +2029,13 @@ void InitializationSequence::AddReferenceBindingStep(QualType T, } 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); } @@ -2071,7 +2073,8 @@ InitializationSequence::AddConstructorInitializationStep( 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); } @@ -2198,25 +2201,26 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &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); } } @@ -2257,11 +2261,11 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, 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); } } @@ -2284,7 +2288,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, 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 @@ -2574,25 +2578,26 @@ static void TryConstructorInitialization(Sema &S, 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); } } @@ -2623,11 +2628,11 @@ static void TryConstructorInitialization(Sema &S, // 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); } } @@ -2744,25 +2749,27 @@ static void TryUserDefinedConversion(Sema &S, 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); } } @@ -2799,11 +2806,11 @@ static void TryUserDefinedConversion(Sema &S, 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); } } @@ -2825,13 +2832,13 @@ static void TryUserDefinedConversion(Sema &S, 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. @@ -3135,8 +3142,10 @@ static Sema::OwningExprResult CopyIfRequiredForEntity(Sema &S, 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); } @@ -3170,6 +3179,10 @@ static Sema::OwningExprResult CopyIfRequiredForEntity(Sema &S, 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), @@ -3303,7 +3316,7 @@ InitializationSequence::Perform(Sema &S, // 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: @@ -3367,8 +3380,8 @@ InitializationSequence::Perform(Sema &S, // 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); @@ -3390,7 +3403,8 @@ InitializationSequence::Perform(Sema &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()); @@ -3402,7 +3416,7 @@ InitializationSequence::Perform(Sema &S, 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 @@ -3469,7 +3483,7 @@ InitializationSequence::Perform(Sema &S, 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); @@ -3506,7 +3520,8 @@ InitializationSequence::Perform(Sema &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(); @@ -3972,7 +3987,8 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const { 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: diff --git a/lib/Sema/SemaInit.h b/lib/Sema/SemaInit.h index 2b49df28fe..18a0938f7c 100644 --- a/lib/Sema/SemaInit.h +++ b/lib/Sema/SemaInit.h @@ -454,7 +454,10 @@ public: /// Always a FunctionDecl. /// For conversion decls, the naming class is the source type. /// For construct decls, the naming class is the target type. - DeclAccessPair Function; + struct { + FunctionDecl *Function; + DeclAccessPair FoundDecl; + } Function; /// \brief When Kind = SK_ConversionSequence, the implicit conversion /// sequence @@ -622,7 +625,7 @@ public: /// \brief Add a new step invoking a conversion function, which is either /// a constructor or a conversion function. void AddUserConversionStep(FunctionDecl *Function, - AccessSpecifier Access, + DeclAccessPair FoundDecl, QualType T); /// \brief Add a new step that performs a qualification conversion to the diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index f73ec9cb61..410bf9a7c1 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1525,28 +1525,30 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType, 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); } @@ -1569,7 +1571,8 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType, = 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(); @@ -1583,11 +1586,11 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType, 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); } } @@ -2383,7 +2386,7 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) { /// code completion. void Sema::AddOverloadCandidate(FunctionDecl *Function, - Acc |