[cfe-commits] r98945 - in /cfe/trunk: 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

John McCall rjmccall at apple.com
Fri Mar 19 00:35:20 PDT 2010


Author: rjmccall
Date: Fri Mar 19 02:35:19 2010
New Revision: 98945

URL: http://llvm.org/viewvc/llvm-project?rev=98945&view=rev
Log:
Remember the "found declaration" for an overload candidate, which is the
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.


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

Modified: cfe/trunk/include/clang/AST/UnresolvedSet.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/UnresolvedSet.h?rev=98945&r1=98944&r2=98945&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/UnresolvedSet.h (original)
+++ cfe/trunk/include/clang/AST/UnresolvedSet.h Fri Mar 19 02:35:19 2010
@@ -94,6 +94,7 @@
 
   NamedDecl *getDecl() const { return ir->getDecl(); }
   AccessSpecifier getAccess() const { return ir->getAccess(); }
+  DeclAccessPair getPair() const { return *ir; }
 
   NamedDecl *operator*() const { return getDecl(); }
   

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=98945&r1=98944&r2=98945&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Mar 19 02:35:19 2010
@@ -321,6 +321,14 @@
         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 @@
   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 @@
                              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 @@
                                   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 @@
                                 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 @@
   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,

Modified: cfe/trunk/lib/Sema/SemaAccess.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=98945&r1=98944&r2=98945&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAccess.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAccess.cpp Fri Mar 19 02:35:19 2010
@@ -527,15 +527,13 @@
 }
 
 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 @@
 /// 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 @@
     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 @@
     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 @@
     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::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::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 @@
   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);

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=98945&r1=98944&r2=98945&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Fri Mar 19 02:35:19 2010
@@ -2253,7 +2253,8 @@
         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);
     }
   }

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=98945&r1=98944&r2=98945&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Mar 19 02:35:19 2010
@@ -4204,6 +4204,8 @@
   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 @@
         ((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 @@
       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);
       }
     }

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=98945&r1=98944&r2=98945&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Mar 19 02:35:19 2010
@@ -921,7 +921,9 @@
   }
 
   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 @@
         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 @@
          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 @@
   //   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 @@
         << DeleteName;
     } else {
       CheckAllocationAccess(StartLoc, Range, FoundDelete.getNamingClass(),
-                            Matches[0].getDecl(), Matches[0].getAccess());
+                            Matches[0].first);
     }
   }
 
@@ -1033,18 +1035,18 @@
        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 @@
         return true;
     }
     Operator = FnDecl;
-    CheckAllocationAccess(StartLoc, Range, R.getNamingClass(),
-                          FnDecl, Best->getAccess());
+    CheckAllocationAccess(StartLoc, Range, R.getNamingClass(), Best->FoundDecl);
     return false;
   }
 

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=98945&r1=98944&r2=98945&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Mar 19 02:35:19 2010
@@ -2007,7 +2007,8 @@
   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::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 @@
   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 @@
     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 @@
       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 @@
     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 @@
   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 @@
   // 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 @@
     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 @@
         
         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 @@
   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 @@
     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 @@
     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 @@
       // 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 @@
       // 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 @@
         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 @@
         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 @@
 
     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 @@
         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 @@
       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:

Modified: cfe/trunk/lib/Sema/SemaInit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.h?rev=98945&r1=98944&r2=98945&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.h (original)
+++ cfe/trunk/lib/Sema/SemaInit.h Fri Mar 19 02:35:19 2010
@@ -454,7 +454,10 @@
       /// 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 @@
   /// \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

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=98945&r1=98944&r2=98945&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Mar 19 02:35:19 2010
@@ -1525,28 +1525,30 @@
       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 @@
         = 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 @@
 
         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 @@
 /// code completion.
 void
 Sema::AddOverloadCandidate(FunctionDecl *Function,
-                           AccessSpecifier Access,
+                           DeclAccessPair FoundDecl,
                            Expr **Args, unsigned NumArgs,
                            OverloadCandidateSet& CandidateSet,
                            bool SuppressUserConversions,
@@ -2404,7 +2407,7 @@
       // 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 @@
   // 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 @@
                                  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 @@
 
 /// 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 @@
   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 @@
 /// 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 @@
   // 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 @@
 /// function template specialization.
 void
 Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
-                                 AccessSpecifier Access,
+                                 DeclAccessPair FoundDecl,
                                  CXXRecordDecl *ActingContext,
                         const TemplateArgumentListInfo *ExplicitTemplateArgs,
                                  QualType ObjectType,
@@ -2702,7 +2706,7 @@
   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 @@
 /// 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 @@
                                   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 @@
   // 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 @@
 /// conversion function produces).
 void
 Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
-                             AccessSpecifier Access,
+                             DeclAccessPair FoundDecl,
                              CXXRecordDecl *ActingContext,
                              Expr *From, QualType ToType,
                              OverloadCandidateSet& CandidateSet) {
@@ -2781,8 +2785,8 @@
   // 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 @@
 /// [temp.deduct.conv]).
 void
 Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
-                                     AccessSpecifier Access,
+                                     DeclAccessPair FoundDecl,
                                      CXXRecordDecl *ActingDC,
                                      Expr *From, QualType ToType,
                                      OverloadCandidateSet &CandidateSet) {
@@ -2893,7 +2897,7 @@
   // 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 @@
 /// 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 @@
 
   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 @@
                              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 @@
   // 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 @@
   // 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 @@
   }
 }
 
-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 @@
 
   // 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 @@
         // 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 @@
       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 @@
   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 @@
     // 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 @@
     
 /// \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 @@
 
   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 @@
   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 @@
 
       // 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 @@
         // 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 @@
         // 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 @@
         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 @@
     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 @@
 
   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 @@
       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 @@
       = 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 @@
                          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 @@
 
   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 @@
     return ExprError();
   }
 
+  CheckMemberOperatorAccess(OpLoc, Base, 0, Best->FoundDecl);
+
   // Convert the object parameter.
   CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
   if (PerformObjectArgumentInitialization(Base, /*Qualifier=*/0, Method))

Modified: cfe/trunk/lib/Sema/SemaOverload.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.h?rev=98945&r1=98944&r2=98945&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.h (original)
+++ cfe/trunk/lib/Sema/SemaOverload.h Fri Mar 19 02:35:19 2010
@@ -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 @@
     /// 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 @@
     /// 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 {





More information about the cfe-commits mailing list