]> granicus.if.org Git - clang/commitdiff
Remember the "found declaration" for an overload candidate, which is the
authorJohn McCall <rjmccall@apple.com>
Fri, 19 Mar 2010 07:35:19 +0000 (07:35 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 19 Mar 2010 07:35:19 +0000 (07:35 +0000)
entity (if applicable) which was actually looked up.  If a candidate was found
via a using declaration, this is the UsingShadowDecl;  otherwise, if
the candidate is template specialization, this is the template;  otherwise,
this is the function.

The point of this exercise is that "found declarations" are the entities
we do access control for, not their underlying declarations.  Broadly speaking,
this patch fixes access control for using declarations.

There is a *lot* of redundant code calling into the overload-resolution APIs;
we really ought to clean that up.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98945 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/UnresolvedSet.h
lib/Sema/Sema.h
lib/Sema/SemaAccess.cpp
lib/Sema/SemaCodeComplete.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaInit.cpp
lib/Sema/SemaInit.h
lib/Sema/SemaOverload.cpp
lib/Sema/SemaOverload.h

index 9c59229e3134dee0927a361b41701250592c326f..553f04d76aec1d1b050a2452e421c4638cd97648 100644 (file)
@@ -94,6 +94,7 @@ public:
 
   NamedDecl *getDecl() const { return ir->getDecl(); }
   AccessSpecifier getAccess() const { return ir->getAccess(); }
+  DeclAccessPair getPair() const { return *ir; }
 
   NamedDecl *operator*() const { return getDecl(); }
   
index 6c655e55b460be372f5f1629ebf060ec2e19153f..747fd889786f3e2d500f47aac71d76b757476e3e 100644 (file)
@@ -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,
index 171ed3783e45dbbc4627a9fa665ae3a40fce2531..40b320c1be5e4f25684449daea39b95712b7fcc5 100644 (file)
@@ -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);
index 4693fa974edb1a4319b7b203742eaf4ffccd740b..317eef8d60fcddc21adfdbc7972f63eff30de6fb 100644 (file)
@@ -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);
     }
   }
index c0b699a518161d23d75a9a219a451f43d557e20d..13a7ead76bdff804ce26f2b935ce0ba0d932a0ec 100644 (file)
@@ -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);
       }
     }
index 2a55894f22a40760173051c9169c9732f9f76168..366089f2ab633770fb7490eeb953559c299aef21 100644 (file)
@@ -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;
   }
 
index 98a7eec232f6db846bccb5c148b7fa3fa1bf132c..f86ae51c28061f77ecf33235dc6cda8c3df54aaa 100644 (file)
@@ -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:
index 2b49df28fe8647f89de9e64926cd3672acf1cd02..18a0938f7c095a5fc6dc72e77a920b78142b289d 100644 (file)
@@ -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
index f73ec9cb61c5d696b74b412e484b935d14d120f0..410bf9a7c1e9f4fb1253c08bc56f55c40de53f72 100644 (file)
@@ -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,
-                           AccessSpecifier Access,
+                           DeclAccessPair FoundDecl,
                            Expr **Args, unsigned NumArgs,
                            OverloadCandidateSet& CandidateSet,
                            bool SuppressUserConversions,
@@ -2404,7 +2407,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
       // 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;
@@ -2434,8 +2437,8 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
   // 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;
@@ -2500,28 +2503,28 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,
                                  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);
@@ -2531,12 +2534,12 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,
 
 /// 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))
@@ -2545,13 +2548,14 @@ void Sema::AddMethodCandidate(NamedDecl *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);
   }
@@ -2567,7 +2571,7 @@ void Sema::AddMethodCandidate(NamedDecl *Decl,
 /// 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,
@@ -2587,8 +2591,8 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, AccessSpecifier Access,
   // 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;
 
@@ -2666,7 +2670,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, AccessSpecifier Access,
 /// function template specialization.
 void
 Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
-                                 AccessSpecifier Access,
+                                 DeclAccessPair FoundDecl,
                                  CXXRecordDecl *ActingContext,
                         const TemplateArgumentListInfo *ExplicitTemplateArgs,
                                  QualType ObjectType,
@@ -2702,7 +2706,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
   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);
 }
@@ -2712,7 +2716,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
 /// an appropriate function template specialization.
 void
 Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
-                                   AccessSpecifier Access,
+                                   DeclAccessPair FoundDecl,
                         const TemplateArgumentListInfo *ExplicitTemplateArgs,
                                    Expr **Args, unsigned NumArgs,
                                    OverloadCandidateSet& CandidateSet,
@@ -2737,8 +2741,8 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
                                   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;
@@ -2753,7 +2757,7 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
   // 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);
 }
 
@@ -2765,7 +2769,7 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
 /// conversion function produces).
 void
 Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
-                             AccessSpecifier Access,
+                             DeclAccessPair FoundDecl,
                              CXXRecordDecl *ActingContext,
                              Expr *From, QualType ToType,
                              OverloadCandidateSet& CandidateSet) {
@@ -2781,8 +2785,8 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
   // 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();
@@ -2869,7 +2873,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
 /// [temp.deduct.conv]).
 void
 Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
-                                     AccessSpecifier Access,
+                                     DeclAccessPair FoundDecl,
                                      CXXRecordDecl *ActingDC,
                                      Expr *From, QualType ToType,
                                      OverloadCandidateSet &CandidateSet) {
@@ -2893,7 +2897,7 @@ Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
   // 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);
 }
 
@@ -2903,7 +2907,7 @@ Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
 /// 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,
@@ -2917,8 +2921,8 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
 
   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;
@@ -3066,7 +3070,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
                              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);
   }
@@ -3091,8 +3095,8 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
   // 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;
@@ -4179,15 +4183,16 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
   // 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);
   }
 }
@@ -4951,12 +4956,11 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& 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
@@ -5013,7 +5017,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
 
   // 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) {
@@ -5057,8 +5061,8 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
         // 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;
@@ -5081,8 +5085,8 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
       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;
       }
     }
@@ -5092,10 +5096,10 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
   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;
   }
 
@@ -5112,50 +5116,54 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
     // 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;
 }
 
@@ -5227,25 +5235,26 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From) {
     
 /// \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;
   }
@@ -5301,7 +5310,7 @@ void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
 
   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);
 
@@ -5423,7 +5432,7 @@ Sema::BuildOverloadedCallExpr(Expr *Fn, UnresolvedLookupExpr *ULE,
   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);
   }
@@ -5549,7 +5558,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
 
       // 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();
@@ -5733,8 +5742,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
         // 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(
@@ -5908,8 +5916,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
         // 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);
@@ -6054,12 +6061,12 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
         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);
@@ -6072,7 +6079,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
     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:
@@ -6176,7 +6183,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
 
   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);
   }
@@ -6221,7 +6228,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
       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);
   }
@@ -6278,7 +6285,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
       = 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
@@ -6293,8 +6300,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
                          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
@@ -6429,13 +6435,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
 
   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);
   }
 
@@ -6470,6 +6470,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
     return ExprError();
   }
 
+  CheckMemberOperatorAccess(OpLoc, Base, 0, Best->FoundDecl);
+
   // Convert the object parameter.
   CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
   if (PerformObjectArgumentInitialization(Base, /*Qualifier=*/0, Method))
index 58e416c87e591e587685e9fcc649b7762e30e775..cff4774fba27bf0d09b0bcff22004667bb9ceb9d 100644 (file)
@@ -18,6 +18,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/UnresolvedSet.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 
@@ -450,6 +451,11 @@ namespace clang {
     /// function pointer or reference (C++ [over.call.object]).
     FunctionDecl *Function;
 
+    /// FoundDecl - The original declaration that was looked up /
+    /// invented / otherwise found, together with its access.
+    /// Might be a UsingShadowDecl or a FunctionTemplateDecl.
+    DeclAccessPair FoundDecl;
+
     // BuiltinTypes - Provides the return and parameter types of a
     // built-in overload candidate. Only valid when Function is NULL.
     struct {
@@ -486,14 +492,6 @@ namespace clang {
     /// Actually an OverloadFailureKind.
     unsigned char FailureKind;
 
-    /// PathAccess - The 'path access' to the given function/conversion.
-    /// Actually an AccessSpecifier.
-    unsigned Access;
-
-    AccessSpecifier getAccess() const {
-      return AccessSpecifier(Access);
-    }
-
     /// A structure used to record information about a failed
     /// template argument deduction.
     struct DeductionFailureInfo {