Home | History | Annotate | Download | only in Sema
      1 //===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file provides Sema routines for C++ access control semantics.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "clang/Sema/SemaInternal.h"
     15 #include "clang/Sema/DelayedDiagnostic.h"
     16 #include "clang/Sema/Initialization.h"
     17 #include "clang/Sema/Lookup.h"
     18 #include "clang/AST/ASTContext.h"
     19 #include "clang/AST/CXXInheritance.h"
     20 #include "clang/AST/DeclCXX.h"
     21 #include "clang/AST/DeclFriend.h"
     22 #include "clang/AST/DeclObjC.h"
     23 #include "clang/AST/DependentDiagnostic.h"
     24 #include "clang/AST/ExprCXX.h"
     25 
     26 using namespace clang;
     27 using namespace sema;
     28 
     29 /// A copy of Sema's enum without AR_delayed.
     30 enum AccessResult {
     31   AR_accessible,
     32   AR_inaccessible,
     33   AR_dependent
     34 };
     35 
     36 /// SetMemberAccessSpecifier - Set the access specifier of a member.
     37 /// Returns true on error (when the previous member decl access specifier
     38 /// is different from the new member decl access specifier).
     39 bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
     40                                     NamedDecl *PrevMemberDecl,
     41                                     AccessSpecifier LexicalAS) {
     42   if (!PrevMemberDecl) {
     43     // Use the lexical access specifier.
     44     MemberDecl->setAccess(LexicalAS);
     45     return false;
     46   }
     47 
     48   // C++ [class.access.spec]p3: When a member is redeclared its access
     49   // specifier must be same as its initial declaration.
     50   if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
     51     Diag(MemberDecl->getLocation(),
     52          diag::err_class_redeclared_with_different_access)
     53       << MemberDecl << LexicalAS;
     54     Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
     55       << PrevMemberDecl << PrevMemberDecl->getAccess();
     56 
     57     MemberDecl->setAccess(LexicalAS);
     58     return true;
     59   }
     60 
     61   MemberDecl->setAccess(PrevMemberDecl->getAccess());
     62   return false;
     63 }
     64 
     65 static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) {
     66   DeclContext *DC = D->getDeclContext();
     67 
     68   // This can only happen at top: enum decls only "publish" their
     69   // immediate members.
     70   if (isa<EnumDecl>(DC))
     71     DC = cast<EnumDecl>(DC)->getDeclContext();
     72 
     73   CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
     74   while (DeclaringClass->isAnonymousStructOrUnion())
     75     DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
     76   return DeclaringClass;
     77 }
     78 
     79 namespace {
     80 struct EffectiveContext {
     81   EffectiveContext() : Inner(0), Dependent(false) {}
     82 
     83   explicit EffectiveContext(DeclContext *DC)
     84     : Inner(DC),
     85       Dependent(DC->isDependentContext()) {
     86 
     87     // C++ [class.access.nest]p1:
     88     //   A nested class is a member and as such has the same access
     89     //   rights as any other member.
     90     // C++ [class.access]p2:
     91     //   A member of a class can also access all the names to which
     92     //   the class has access.  A local class of a member function
     93     //   may access the same names that the member function itself
     94     //   may access.
     95     // This almost implies that the privileges of nesting are transitive.
     96     // Technically it says nothing about the local classes of non-member
     97     // functions (which can gain privileges through friendship), but we
     98     // take that as an oversight.
     99     while (true) {
    100       // We want to add canonical declarations to the EC lists for
    101       // simplicity of checking, but we need to walk up through the
    102       // actual current DC chain.  Otherwise, something like a local
    103       // extern or friend which happens to be the canonical
    104       // declaration will really mess us up.
    105 
    106       if (isa<CXXRecordDecl>(DC)) {
    107         CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
    108         Records.push_back(Record->getCanonicalDecl());
    109         DC = Record->getDeclContext();
    110       } else if (isa<FunctionDecl>(DC)) {
    111         FunctionDecl *Function = cast<FunctionDecl>(DC);
    112         Functions.push_back(Function->getCanonicalDecl());
    113         if (Function->getFriendObjectKind())
    114           DC = Function->getLexicalDeclContext();
    115         else
    116           DC = Function->getDeclContext();
    117       } else if (DC->isFileContext()) {
    118         break;
    119       } else {
    120         DC = DC->getParent();
    121       }
    122     }
    123   }
    124 
    125   bool isDependent() const { return Dependent; }
    126 
    127   bool includesClass(const CXXRecordDecl *R) const {
    128     R = R->getCanonicalDecl();
    129     return std::find(Records.begin(), Records.end(), R)
    130              != Records.end();
    131   }
    132 
    133   /// Retrieves the innermost "useful" context.  Can be null if we're
    134   /// doing access-control without privileges.
    135   DeclContext *getInnerContext() const {
    136     return Inner;
    137   }
    138 
    139   typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
    140 
    141   DeclContext *Inner;
    142   SmallVector<FunctionDecl*, 4> Functions;
    143   SmallVector<CXXRecordDecl*, 4> Records;
    144   bool Dependent;
    145 };
    146 
    147 /// Like sema::AccessedEntity, but kindly lets us scribble all over
    148 /// it.
    149 struct AccessTarget : public AccessedEntity {
    150   AccessTarget(const AccessedEntity &Entity)
    151     : AccessedEntity(Entity) {
    152     initialize();
    153   }
    154 
    155   AccessTarget(ASTContext &Context,
    156                MemberNonce _,
    157                CXXRecordDecl *NamingClass,
    158                DeclAccessPair FoundDecl,
    159                QualType BaseObjectType)
    160     : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,
    161                      FoundDecl, BaseObjectType) {
    162     initialize();
    163   }
    164 
    165   AccessTarget(ASTContext &Context,
    166                BaseNonce _,
    167                CXXRecordDecl *BaseClass,
    168                CXXRecordDecl *DerivedClass,
    169                AccessSpecifier Access)
    170     : AccessedEntity(Context.getDiagAllocator(), Base, BaseClass, DerivedClass,
    171                      Access) {
    172     initialize();
    173   }
    174 
    175   bool isInstanceMember() const {
    176     return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
    177   }
    178 
    179   bool hasInstanceContext() const {
    180     return HasInstanceContext;
    181   }
    182 
    183   class SavedInstanceContext {
    184   public:
    185     ~SavedInstanceContext() {
    186       Target.HasInstanceContext = Has;
    187     }
    188 
    189   private:
    190     friend struct AccessTarget;
    191     explicit SavedInstanceContext(AccessTarget &Target)
    192       : Target(Target), Has(Target.HasInstanceContext) {}
    193     AccessTarget &Target;
    194     bool Has;
    195   };
    196 
    197   SavedInstanceContext saveInstanceContext() {
    198     return SavedInstanceContext(*this);
    199   }
    200 
    201   void suppressInstanceContext() {
    202     HasInstanceContext = false;
    203   }
    204 
    205   const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
    206     assert(HasInstanceContext);
    207     if (CalculatedInstanceContext)
    208       return InstanceContext;
    209 
    210     CalculatedInstanceContext = true;
    211     DeclContext *IC = S.computeDeclContext(getBaseObjectType());
    212     InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl() : 0);
    213     return InstanceContext;
    214   }
    215 
    216   const CXXRecordDecl *getDeclaringClass() const {
    217     return DeclaringClass;
    218   }
    219 
    220 private:
    221   void initialize() {
    222     HasInstanceContext = (isMemberAccess() &&
    223                           !getBaseObjectType().isNull() &&
    224                           getTargetDecl()->isCXXInstanceMember());
    225     CalculatedInstanceContext = false;
    226     InstanceContext = 0;
    227 
    228     if (isMemberAccess())
    229       DeclaringClass = FindDeclaringClass(getTargetDecl());
    230     else
    231       DeclaringClass = getBaseClass();
    232     DeclaringClass = DeclaringClass->getCanonicalDecl();
    233   }
    234 
    235   bool HasInstanceContext : 1;
    236   mutable bool CalculatedInstanceContext : 1;
    237   mutable const CXXRecordDecl *InstanceContext;
    238   const CXXRecordDecl *DeclaringClass;
    239 };
    240 
    241 }
    242 
    243 /// Checks whether one class might instantiate to the other.
    244 static bool MightInstantiateTo(const CXXRecordDecl *From,
    245                                const CXXRecordDecl *To) {
    246   // Declaration names are always preserved by instantiation.
    247   if (From->getDeclName() != To->getDeclName())
    248     return false;
    249 
    250   const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
    251   const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
    252   if (FromDC == ToDC) return true;
    253   if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
    254 
    255   // Be conservative.
    256   return true;
    257 }
    258 
    259 /// Checks whether one class is derived from another, inclusively.
    260 /// Properly indicates when it couldn't be determined due to
    261 /// dependence.
    262 ///
    263 /// This should probably be donated to AST or at least Sema.
    264 static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived,
    265                                            const CXXRecordDecl *Target) {
    266   assert(Derived->getCanonicalDecl() == Derived);
    267   assert(Target->getCanonicalDecl() == Target);
    268 
    269   if (Derived == Target) return AR_accessible;
    270 
    271   bool CheckDependent = Derived->isDependentContext();
    272   if (CheckDependent && MightInstantiateTo(Derived, Target))
    273     return AR_dependent;
    274 
    275   AccessResult OnFailure = AR_inaccessible;
    276   SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
    277 
    278   while (true) {
    279     if (Derived->isDependentContext() && !Derived->hasDefinition())
    280       return AR_dependent;
    281 
    282     for (CXXRecordDecl::base_class_const_iterator
    283            I = Derived->bases_begin(), E = Derived->bases_end(); I != E; ++I) {
    284 
    285       const CXXRecordDecl *RD;
    286 
    287       QualType T = I->getType();
    288       if (const RecordType *RT = T->getAs<RecordType>()) {
    289         RD = cast<CXXRecordDecl>(RT->getDecl());
    290       } else if (const InjectedClassNameType *IT
    291                    = T->getAs<InjectedClassNameType>()) {
    292         RD = IT->getDecl();
    293       } else {
    294         assert(T->isDependentType() && "non-dependent base wasn't a record?");
    295         OnFailure = AR_dependent;
    296         continue;
    297       }
    298 
    299       RD = RD->getCanonicalDecl();
    300       if (RD == Target) return AR_accessible;
    301       if (CheckDependent && MightInstantiateTo(RD, Target))
    302         OnFailure = AR_dependent;
    303 
    304       Queue.push_back(RD);
    305     }
    306 
    307     if (Queue.empty()) break;
    308 
    309     Derived = Queue.back();
    310     Queue.pop_back();
    311   }
    312 
    313   return OnFailure;
    314 }
    315 
    316 
    317 static bool MightInstantiateTo(Sema &S, DeclContext *Context,
    318                                DeclContext *Friend) {
    319   if (Friend == Context)
    320     return true;
    321 
    322   assert(!Friend->isDependentContext() &&
    323          "can't handle friends with dependent contexts here");
    324 
    325   if (!Context->isDependentContext())
    326     return false;
    327 
    328   if (Friend->isFileContext())
    329     return false;
    330 
    331   // TODO: this is very conservative
    332   return true;
    333 }
    334 
    335 // Asks whether the type in 'context' can ever instantiate to the type
    336 // in 'friend'.
    337 static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) {
    338   if (Friend == Context)
    339     return true;
    340 
    341   if (!Friend->isDependentType() && !Context->isDependentType())
    342     return false;
    343 
    344   // TODO: this is very conservative.
    345   return true;
    346 }
    347 
    348 static bool MightInstantiateTo(Sema &S,
    349                                FunctionDecl *Context,
    350                                FunctionDecl *Friend) {
    351   if (Context->getDeclName() != Friend->getDeclName())
    352     return false;
    353 
    354   if (!MightInstantiateTo(S,
    355                           Context->getDeclContext(),
    356                           Friend->getDeclContext()))
    357     return false;
    358 
    359   CanQual<FunctionProtoType> FriendTy
    360     = S.Context.getCanonicalType(Friend->getType())
    361          ->getAs<FunctionProtoType>();
    362   CanQual<FunctionProtoType> ContextTy
    363     = S.Context.getCanonicalType(Context->getType())
    364          ->getAs<FunctionProtoType>();
    365 
    366   // There isn't any way that I know of to add qualifiers
    367   // during instantiation.
    368   if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
    369     return false;
    370 
    371   if (FriendTy->getNumArgs() != ContextTy->getNumArgs())
    372     return false;
    373 
    374   if (!MightInstantiateTo(S,
    375                           ContextTy->getResultType(),
    376                           FriendTy->getResultType()))
    377     return false;
    378 
    379   for (unsigned I = 0, E = FriendTy->getNumArgs(); I != E; ++I)
    380     if (!MightInstantiateTo(S,
    381                             ContextTy->getArgType(I),
    382                             FriendTy->getArgType(I)))
    383       return false;
    384 
    385   return true;
    386 }
    387 
    388 static bool MightInstantiateTo(Sema &S,
    389                                FunctionTemplateDecl *Context,
    390                                FunctionTemplateDecl *Friend) {
    391   return MightInstantiateTo(S,
    392                             Context->getTemplatedDecl(),
    393                             Friend->getTemplatedDecl());
    394 }
    395 
    396 static AccessResult MatchesFriend(Sema &S,
    397                                   const EffectiveContext &EC,
    398                                   const CXXRecordDecl *Friend) {
    399   if (EC.includesClass(Friend))
    400     return AR_accessible;
    401 
    402   if (EC.isDependent()) {
    403     CanQualType FriendTy
    404       = S.Context.getCanonicalType(S.Context.getTypeDeclType(Friend));
    405 
    406     for (EffectiveContext::record_iterator
    407            I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
    408       CanQualType ContextTy
    409         = S.Context.getCanonicalType(S.Context.getTypeDeclType(*I));
    410       if (MightInstantiateTo(S, ContextTy, FriendTy))
    411         return AR_dependent;
    412     }
    413   }
    414 
    415   return AR_inaccessible;
    416 }
    417 
    418 static AccessResult MatchesFriend(Sema &S,
    419                                   const EffectiveContext &EC,
    420                                   CanQualType Friend) {
    421   if (const RecordType *RT = Friend->getAs<RecordType>())
    422     return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
    423 
    424   // TODO: we can do better than this
    425   if (Friend->isDependentType())
    426     return AR_dependent;
    427 
    428   return AR_inaccessible;
    429 }
    430 
    431 /// Determines whether the given friend class template matches
    432 /// anything in the effective context.
    433 static AccessResult MatchesFriend(Sema &S,
    434                                   const EffectiveContext &EC,
    435                                   ClassTemplateDecl *Friend) {
    436   AccessResult OnFailure = AR_inaccessible;
    437 
    438   // Check whether the friend is the template of a class in the
    439   // context chain.
    440   for (SmallVectorImpl<CXXRecordDecl*>::const_iterator
    441          I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
    442     CXXRecordDecl *Record = *I;
    443 
    444     // Figure out whether the current class has a template:
    445     ClassTemplateDecl *CTD;
    446 
    447     // A specialization of the template...
    448     if (isa<ClassTemplateSpecializationDecl>(Record)) {
    449       CTD = cast<ClassTemplateSpecializationDecl>(Record)
    450         ->getSpecializedTemplate();
    451 
    452     // ... or the template pattern itself.
    453     } else {
    454       CTD = Record->getDescribedClassTemplate();
    455       if (!CTD) continue;
    456     }
    457 
    458     // It's a match.
    459     if (Friend == CTD->getCanonicalDecl())
    460       return AR_accessible;
    461 
    462     // If the context isn't dependent, it can't be a dependent match.
    463     if (!EC.isDependent())
    464       continue;
    465 
    466     // If the template names don't match, it can't be a dependent
    467     // match.
    468     if (CTD->getDeclName() != Friend->getDeclName())
    469       continue;
    470 
    471     // If the class's context can't instantiate to the friend's
    472     // context, it can't be a dependent match.
    473     if (!MightInstantiateTo(S, CTD->getDeclContext(),
    474                             Friend->getDeclContext()))
    475       continue;
    476 
    477     // Otherwise, it's a dependent match.
    478     OnFailure = AR_dependent;
    479   }
    480 
    481   return OnFailure;
    482 }
    483 
    484 /// Determines whether the given friend function matches anything in
    485 /// the effective context.
    486 static AccessResult MatchesFriend(Sema &S,
    487                                   const EffectiveContext &EC,
    488                                   FunctionDecl *Friend) {
    489   AccessResult OnFailure = AR_inaccessible;
    490 
    491   for (SmallVectorImpl<FunctionDecl*>::const_iterator
    492          I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
    493     if (Friend == *I)
    494       return AR_accessible;
    495 
    496     if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
    497       OnFailure = AR_dependent;
    498   }
    499 
    500   return OnFailure;
    501 }
    502 
    503 /// Determines whether the given friend function template matches
    504 /// anything in the effective context.
    505 static AccessResult MatchesFriend(Sema &S,
    506                                   const EffectiveContext &EC,
    507                                   FunctionTemplateDecl *Friend) {
    508   if (EC.Functions.empty()) return AR_inaccessible;
    509 
    510   AccessResult OnFailure = AR_inaccessible;
    511 
    512   for (SmallVectorImpl<FunctionDecl*>::const_iterator
    513          I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
    514 
    515     FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
    516     if (!FTD)
    517       FTD = (*I)->getDescribedFunctionTemplate();
    518     if (!FTD)
    519       continue;
    520 
    521     FTD = FTD->getCanonicalDecl();
    522 
    523     if (Friend == FTD)
    524       return AR_accessible;
    525 
    526     if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
    527       OnFailure = AR_dependent;
    528   }
    529 
    530   return OnFailure;
    531 }
    532 
    533 /// Determines whether the given friend declaration matches anything
    534 /// in the effective context.
    535 static AccessResult MatchesFriend(Sema &S,
    536                                   const EffectiveContext &EC,
    537                                   FriendDecl *FriendD) {
    538   // Whitelist accesses if there's an invalid or unsupported friend
    539   // declaration.
    540   if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend())
    541     return AR_accessible;
    542 
    543   if (TypeSourceInfo *T = FriendD->getFriendType())
    544     return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
    545 
    546   NamedDecl *Friend
    547     = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
    548 
    549   // FIXME: declarations with dependent or templated scope.
    550 
    551   if (isa<ClassTemplateDecl>(Friend))
    552     return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
    553 
    554   if (isa<FunctionTemplateDecl>(Friend))
    555     return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
    556 
    557   if (isa<CXXRecordDecl>(Friend))
    558     return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
    559 
    560   assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
    561   return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
    562 }
    563 
    564 static AccessResult GetFriendKind(Sema &S,
    565                                   const EffectiveContext &EC,
    566                                   const CXXRecordDecl *Class) {
    567   AccessResult OnFailure = AR_inaccessible;
    568 
    569   // Okay, check friends.
    570   for (CXXRecordDecl::friend_iterator I = Class->friend_begin(),
    571          E = Class->friend_end(); I != E; ++I) {
    572     FriendDecl *Friend = *I;
    573 
    574     switch (MatchesFriend(S, EC, Friend)) {
    575     case AR_accessible:
    576       return AR_accessible;
    577 
    578     case AR_inaccessible:
    579       continue;
    580 
    581     case AR_dependent:
    582       OnFailure = AR_dependent;
    583       break;
    584     }
    585   }
    586 
    587   // That's it, give up.
    588   return OnFailure;
    589 }
    590 
    591 namespace {
    592 
    593 /// A helper class for checking for a friend which will grant access
    594 /// to a protected instance member.
    595 struct ProtectedFriendContext {
    596   Sema &S;
    597   const EffectiveContext &EC;
    598   const CXXRecordDecl *NamingClass;
    599   bool CheckDependent;
    600   bool EverDependent;
    601 
    602   /// The path down to the current base class.
    603   SmallVector<const CXXRecordDecl*, 20> CurPath;
    604 
    605   ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
    606                          const CXXRecordDecl *InstanceContext,
    607                          const CXXRecordDecl *NamingClass)
    608     : S(S), EC(EC), NamingClass(NamingClass),
    609       CheckDependent(InstanceContext->isDependentContext() ||
    610                      NamingClass->isDependentContext()),
    611       EverDependent(false) {}
    612 
    613   /// Check classes in the current path for friendship, starting at
    614   /// the given index.
    615   bool checkFriendshipAlongPath(unsigned I) {
    616     assert(I < CurPath.size());
    617     for (unsigned E = CurPath.size(); I != E; ++I) {
    618       switch (GetFriendKind(S, EC, CurPath[I])) {
    619       case AR_accessible:   return true;
    620       case AR_inaccessible: continue;
    621       case AR_dependent:    EverDependent = true; continue;
    622       }
    623     }
    624     return false;
    625   }
    626 
    627   /// Perform a search starting at the given class.
    628   ///
    629   /// PrivateDepth is the index of the last (least derived) class
    630   /// along the current path such that a notional public member of
    631   /// the final class in the path would have access in that class.
    632   bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
    633     // If we ever reach the naming class, check the current path for
    634     // friendship.  We can also stop recursing because we obviously
    635     // won't find the naming class there again.
    636     if (Cur == NamingClass)
    637       return checkFriendshipAlongPath(PrivateDepth);
    638 
    639     if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
    640       EverDependent = true;
    641 
    642     // Recurse into the base classes.
    643     for (CXXRecordDecl::base_class_const_iterator
    644            I = Cur->bases_begin(), E = Cur->bases_end(); I != E; ++I) {
    645 
    646       // If this is private inheritance, then a public member of the
    647       // base will not have any access in classes derived from Cur.
    648       unsigned BasePrivateDepth = PrivateDepth;
    649       if (I->getAccessSpecifier() == AS_private)
    650         BasePrivateDepth = CurPath.size() - 1;
    651 
    652       const CXXRecordDecl *RD;
    653 
    654       QualType T = I->getType();
    655       if (const RecordType *RT = T->getAs<RecordType>()) {
    656         RD = cast<CXXRecordDecl>(RT->getDecl());
    657       } else if (const InjectedClassNameType *IT
    658                    = T->getAs<InjectedClassNameType>()) {
    659         RD = IT->getDecl();
    660       } else {
    661         assert(T->isDependentType() && "non-dependent base wasn't a record?");
    662         EverDependent = true;
    663         continue;
    664       }
    665 
    666       // Recurse.  We don't need to clean up if this returns true.
    667       CurPath.push_back(RD);
    668       if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
    669         return true;
    670       CurPath.pop_back();
    671     }
    672 
    673     return false;
    674   }
    675 
    676   bool findFriendship(const CXXRecordDecl *Cur) {
    677     assert(CurPath.empty());
    678     CurPath.push_back(Cur);
    679     return findFriendship(Cur, 0);
    680   }
    681 };
    682 }
    683 
    684 /// Search for a class P that EC is a friend of, under the constraint
    685 ///   InstanceContext <= P
    686 /// if InstanceContext exists, or else
    687 ///   NamingClass <= P
    688 /// and with the additional restriction that a protected member of
    689 /// NamingClass would have some natural access in P, which implicitly
    690 /// imposes the constraint that P <= NamingClass.
    691 ///
    692 /// This isn't quite the condition laid out in the standard.
    693 /// Instead of saying that a notional protected member of NamingClass
    694 /// would have to have some natural access in P, it says the actual
    695 /// target has to have some natural access in P, which opens up the
    696 /// possibility that the target (which is not necessarily a member
    697 /// of NamingClass) might be more accessible along some path not
    698 /// passing through it.  That's really a bad idea, though, because it
    699 /// introduces two problems:
    700 ///   - Most importantly, it breaks encapsulation because you can
    701 ///     access a forbidden base class's members by directly subclassing
    702 ///     it elsewhere.
    703 ///   - It also makes access substantially harder to compute because it
    704 ///     breaks the hill-climbing algorithm: knowing that the target is
    705 ///     accessible in some base class would no longer let you change
    706 ///     the question solely to whether the base class is accessible,
    707 ///     because the original target might have been more accessible
    708 ///     because of crazy subclassing.
    709 /// So we don't implement that.
    710 static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
    711                                            const CXXRecordDecl *InstanceContext,
    712                                            const CXXRecordDecl *NamingClass) {
    713   assert(InstanceContext == 0 ||
    714          InstanceContext->getCanonicalDecl() == InstanceContext);
    715   assert(NamingClass->getCanonicalDecl() == NamingClass);
    716 
    717   // If we don't have an instance context, our constraints give us
    718   // that NamingClass <= P <= NamingClass, i.e. P == NamingClass.
    719   // This is just the usual friendship check.
    720   if (!InstanceContext) return GetFriendKind(S, EC, NamingClass);
    721 
    722   ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
    723   if (PRC.findFriendship(InstanceContext)) return AR_accessible;
    724   if (PRC.EverDependent) return AR_dependent;
    725   return AR_inaccessible;
    726 }
    727 
    728 static AccessResult HasAccess(Sema &S,
    729                               const EffectiveContext &EC,
    730                               const CXXRecordDecl *NamingClass,
    731                               AccessSpecifier Access,
    732                               const AccessTarget &Target) {
    733   assert(NamingClass->getCanonicalDecl() == NamingClass &&
    734          "declaration should be canonicalized before being passed here");
    735 
    736   if (Access == AS_public) return AR_accessible;
    737   assert(Access == AS_private || Access == AS_protected);
    738 
    739   AccessResult OnFailure = AR_inaccessible;
    740 
    741   for (EffectiveContext::record_iterator
    742          I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
    743     // All the declarations in EC have been canonicalized, so pointer
    744     // equality from this point on will work fine.
    745     const CXXRecordDecl *ECRecord = *I;
    746 
    747     // [B2] and [M2]
    748     if (Access == AS_private) {
    749       if (ECRecord == NamingClass)
    750         return AR_accessible;
    751 
    752       if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
    753         OnFailure = AR_dependent;
    754 
    755     // [B3] and [M3]
    756     } else {
    757       assert(Access == AS_protected);
    758       switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
    759       case AR_accessible: break;
    760       case AR_inaccessible: continue;
    761       case AR_dependent: OnFailure = AR_dependent; continue;
    762       }
    763 
    764       // C++ [class.protected]p1:
    765       //   An additional access check beyond those described earlier in
    766       //   [class.access] is applied when a non-static data member or
    767       //   non-static member function is a protected member of its naming
    768       //   class.  As described earlier, access to a protected member is
    769       //   granted because the reference occurs in a friend or member of
    770       //   some class C.  If the access is to form a pointer to member,
    771       //   the nested-name-specifier shall name C or a class derived from
    772       //   C. All other accesses involve a (possibly implicit) object
    773       //   expression. In this case, the class of the object expression
    774       //   shall be C or a class derived from C.
    775       //
    776       // We interpret this as a restriction on [M3].
    777 
    778       // In this part of the code, 'C' is just our context class ECRecord.
    779 
    780       // These rules are different if we don't have an instance context.
    781       if (!Target.hasInstanceContext()) {
    782         // If it's not an instance member, these restrictions don't apply.
    783         if (!Target.isInstanceMember()) return AR_accessible;
    784 
    785         // If it's an instance member, use the pointer-to-member rule
    786         // that the naming class has to be derived from the effective
    787         // context.
    788 
    789         // Emulate a MSVC bug where the creation of pointer-to-member
    790         // to protected member of base class is allowed but only from
    791         // static member functions.
    792         if (S.getLangOpts().MicrosoftMode && !EC.Functions.empty())
    793           if (CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
    794             if (MD->isStatic()) return AR_accessible;
    795 
    796         // Despite the standard's confident wording, there is a case
    797         // where you can have an instance member that's neither in a
    798         // pointer-to-member expression nor in a member access:  when
    799         // it names a field in an unevaluated context that can't be an
    800         // implicit member.  Pending clarification, we just apply the
    801         // same naming-class restriction here.
    802         //   FIXME: we're probably not correctly adding the
    803         //   protected-member restriction when we retroactively convert
    804         //   an expression to being evaluated.
    805 
    806         // We know that ECRecord derives from NamingClass.  The
    807         // restriction says to check whether NamingClass derives from
    808         // ECRecord, but that's not really necessary: two distinct
    809         // classes can't be recursively derived from each other.  So
    810         // along this path, we just need to check whether the classes
    811         // are equal.
    812         if (NamingClass == ECRecord) return AR_accessible;
    813 
    814         // Otherwise, this context class tells us nothing;  on to the next.
    815         continue;
    816       }
    817 
    818       assert(Target.isInstanceMember());
    819 
    820       const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
    821       if (!InstanceContext) {
    822         OnFailure = AR_dependent;
    823         continue;
    824       }
    825 
    826       switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
    827       case AR_accessible: return AR_accessible;
    828       case AR_inaccessible: continue;
    829       case AR_dependent: OnFailure = AR_dependent; continue;
    830       }
    831     }
    832   }
    833 
    834   // [M3] and [B3] say that, if the target is protected in N, we grant
    835   // access if the access occurs in a friend or member of some class P
    836   // that's a subclass of N and where the target has some natural
    837   // access in P.  The 'member' aspect is easy to handle because P
    838   // would necessarily be one of the effective-context records, and we
    839   // address that above.  The 'friend' aspect is completely ridiculous
    840   // to implement because there are no restrictions at all on P
    841   // *unless* the [class.protected] restriction applies.  If it does,
    842   // however, we should ignore whether the naming class is a friend,
    843   // and instead rely on whether any potential P is a friend.
    844   if (Access == AS_protected && Target.isInstanceMember()) {
    845     // Compute the instance context if possible.
    846     const CXXRecordDecl *InstanceContext = 0;
    847     if (Target.hasInstanceContext()) {
    848       InstanceContext = Target.resolveInstanceContext(S);
    849       if (!InstanceContext) return AR_dependent;
    850     }
    851 
    852     switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
    853     case AR_accessible: return AR_accessible;
    854     case AR_inaccessible: return OnFailure;
    855     case AR_dependent: return AR_dependent;
    856     }
    857     llvm_unreachable("impossible friendship kind");
    858   }
    859 
    860   switch (GetFriendKind(S, EC, NamingClass)) {
    861   case AR_accessible: return AR_accessible;
    862   case AR_inaccessible: return OnFailure;
    863   case AR_dependent: return AR_dependent;
    864   }
    865 
    866   // Silence bogus warnings
    867   llvm_unreachable("impossible friendship kind");
    868 }
    869 
    870 /// Finds the best path from the naming class to the declaring class,
    871 /// taking friend declarations into account.
    872 ///
    873 /// C++0x [class.access.base]p5:
    874 ///   A member m is accessible at the point R when named in class N if
    875 ///   [M1] m as a member of N is public, or
    876 ///   [M2] m as a member of N is private, and R occurs in a member or
    877 ///        friend of class N, or
    878 ///   [M3] m as a member of N is protected, and R occurs in a member or
    879 ///        friend of class N, or in a member or friend of a class P
    880 ///        derived from N, where m as a member of P is public, private,
    881 ///        or protected, or
    882 ///   [M4] there exists a base class B of N that is accessible at R, and
    883 ///        m is accessible at R when named in class B.
    884 ///
    885 /// C++0x [class.access.base]p4:
    886 ///   A base class B of N is accessible at R, if
    887 ///   [B1] an invented public member of B would be a public member of N, or
    888 ///   [B2] R occurs in a member or friend of class N, and an invented public
    889 ///        member of B would be a private or protected member of N, or
    890 ///   [B3] R occurs in a member or friend of a class P derived from N, and an
    891 ///        invented public member of B would be a private or protected member
    892 ///        of P, or
    893 ///   [B4] there exists a class S such that B is a base class of S accessible
    894 ///        at R and S is a base class of N accessible at R.
    895 ///
    896 /// Along a single inheritance path we can restate both of these
    897 /// iteratively:
    898 ///
    899 /// First, we note that M1-4 are equivalent to B1-4 if the member is
    900 /// treated as a notional base of its declaring class with inheritance
    901 /// access equivalent to the member's access.  Therefore we need only
    902 /// ask whether a class B is accessible from a class N in context R.
    903 ///
    904 /// Let B_1 .. B_n be the inheritance path in question (i.e. where
    905 /// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
    906 /// B_i).  For i in 1..n, we will calculate ACAB(i), the access to the
    907 /// closest accessible base in the path:
    908 ///   Access(a, b) = (* access on the base specifier from a to b *)
    909 ///   Merge(a, forbidden) = forbidden
    910 ///   Merge(a, private) = forbidden
    911 ///   Merge(a, b) = min(a,b)
    912 ///   Accessible(c, forbidden) = false
    913 ///   Accessible(c, private) = (R is c) || IsFriend(c, R)
    914 ///   Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
    915 ///   Accessible(c, public) = true
    916 ///   ACAB(n) = public
    917 ///   ACAB(i) =
    918 ///     let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
    919 ///     if Accessible(B_i, AccessToBase) then public else AccessToBase
    920 ///
    921 /// B is an accessible base of N at R iff ACAB(1) = public.
    922 ///
    923 /// \param FinalAccess the access of the "final step", or AS_public if
    924 ///   there is no final step.
    925 /// \return null if friendship is dependent
    926 static CXXBasePath *FindBestPath(Sema &S,
    927                                  const EffectiveContext &EC,
    928                                  AccessTarget &Target,
    929                                  AccessSpecifier FinalAccess,
    930                                  CXXBasePaths &Paths) {
    931   // Derive the paths to the desired base.
    932   const CXXRecordDecl *Derived = Target.getNamingClass();
    933   const CXXRecordDecl *Base = Target.getDeclaringClass();
    934 
    935   // FIXME: fail correctly when there are dependent paths.
    936   bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
    937                                           Paths);
    938   assert(isDerived && "derived class not actually derived from base");
    939   (void) isDerived;
    940 
    941   CXXBasePath *BestPath = 0;
    942 
    943   assert(FinalAccess != AS_none && "forbidden access after declaring class");
    944 
    945   bool AnyDependent = false;
    946 
    947   // Derive the friend-modified access along each path.
    948   for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
    949          PI != PE; ++PI) {
    950     AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
    951 
    952     // Walk through the path backwards.
    953     AccessSpecifier PathAccess = FinalAccess;
    954     CXXBasePath::iterator I = PI->end(), E = PI->begin();
    955     while (I != E) {
    956       --I;
    957 
    958       assert(PathAccess != AS_none);
    959 
    960       // If the declaration is a private member of a base class, there
    961       // is no level of friendship in derived classes that can make it
    962       // accessible.
    963       if (PathAccess == AS_private) {
    964         PathAccess = AS_none;
    965         break;
    966       }
    967 
    968       const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
    969 
    970       AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
    971       PathAccess = std::max(PathAccess, BaseAccess);
    972 
    973       switch (HasAccess(S, EC, NC, PathAccess, Target)) {
    974       case AR_inaccessible: break;
    975       case AR_accessible:
    976         PathAccess = AS_public;
    977 
    978         // Future tests are not against members and so do not have
    979         // instance context.
    980         Target.suppressInstanceContext();
    981         break;
    982       case AR_dependent:
    983         AnyDependent = true;
    984         goto Next;
    985       }
    986     }
    987 
    988     // Note that we modify the path's Access field to the
    989     // friend-modified access.
    990     if (BestPath == 0 || PathAccess < BestPath->Access) {
    991       BestPath = &*PI;
    992       BestPath->Access = PathAccess;
    993 
    994       // Short-circuit if we found a public path.
    995       if (BestPath->Access == AS_public)
    996         return BestPath;
    997     }
    998 
    999   Next: ;
   1000   }
   1001 
   1002   assert((!BestPath || BestPath->Access != AS_public) &&
   1003          "fell out of loop with public path");
   1004 
   1005   // We didn't find a public path, but at least one path was subject
   1006   // to dependent friendship, so delay the check.
   1007   if (AnyDependent)
   1008     return 0;
   1009 
   1010   return BestPath;
   1011 }
   1012 
   1013 /// Given that an entity has protected natural access, check whether
   1014 /// access might be denied because of the protected member access
   1015 /// restriction.
   1016 ///
   1017 /// \return true if a note was emitted
   1018 static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
   1019                                        AccessTarget &Target) {
   1020   // Only applies to instance accesses.
   1021   if (!Target.isInstanceMember())
   1022     return false;
   1023 
   1024   assert(Target.isMemberAccess());
   1025 
   1026   const CXXRecordDecl *NamingClass = Target.getNamingClass();
   1027   NamingClass = NamingClass->getCanonicalDecl();
   1028 
   1029   for (EffectiveContext::record_iterator
   1030          I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
   1031     const CXXRecordDecl *ECRecord = *I;
   1032     switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
   1033     case AR_accessible: break;
   1034     case AR_inaccessible: continue;
   1035     case AR_dependent: continue;
   1036     }
   1037 
   1038     // The effective context is a subclass of the declaring class.
   1039     // Check whether the [class.protected] restriction is limiting
   1040     // access.
   1041 
   1042     // To get this exactly right, this might need to be checked more
   1043     // holistically;  it's not necessarily the case that gaining
   1044     // access here would grant us access overall.
   1045 
   1046     NamedDecl *D = Target.getTargetDecl();
   1047 
   1048     // If we don't have an instance context, [class.protected] says the
   1049     // naming class has to equal the context class.
   1050     if (!Target.hasInstanceContext()) {
   1051       // If it does, the restriction doesn't apply.
   1052       if (NamingClass == ECRecord) continue;
   1053 
   1054       // TODO: it would be great to have a fixit here, since this is
   1055       // such an obvious error.
   1056       S.Diag(D->getLocation(), diag::note_access_protected_restricted_noobject)
   1057         << S.Context.getTypeDeclType(ECRecord);
   1058       return true;
   1059     }
   1060 
   1061     const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
   1062     assert(InstanceContext && "diagnosing dependent access");
   1063 
   1064     switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
   1065     case AR_accessible: continue;
   1066     case AR_dependent: continue;
   1067     case AR_inaccessible:
   1068       break;
   1069     }
   1070 
   1071     // Okay, the restriction seems to be what's limiting us.
   1072 
   1073     // Use a special diagnostic for constructors and destructors.
   1074     if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
   1075         (isa<FunctionTemplateDecl>(D) &&
   1076          isa<CXXConstructorDecl>(
   1077                 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
   1078       S.Diag(D->getLocation(), diag::note_access_protected_restricted_ctordtor)
   1079         << isa<CXXDestructorDecl>(D);
   1080       return true;
   1081     }
   1082 
   1083     // Otherwise, use the generic diagnostic.
   1084     S.Diag(D->getLocation(), diag::note_access_protected_restricted_object)
   1085       << S.Context.getTypeDeclType(ECRecord);
   1086     return true;
   1087   }
   1088 
   1089   return false;
   1090 }
   1091 
   1092 /// Diagnose the path which caused the given declaration or base class
   1093 /// to become inaccessible.
   1094 static void DiagnoseAccessPath(Sema &S,
   1095                                const EffectiveContext &EC,
   1096                                AccessTarget &Entity) {
   1097   AccessSpecifier Access = Entity.getAccess();
   1098 
   1099   NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);
   1100   const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
   1101 
   1102   // Easy case: the decl's natural access determined its path access.
   1103   // We have to check against AS_private here in case Access is AS_none,
   1104   // indicating a non-public member of a private base class.
   1105   if (D && (Access == D->getAccess() || D->getAccess() == AS_private)) {
   1106     switch (HasAccess(S, EC, DeclaringClass, D->getAccess(), Entity)) {
   1107     case AR_inaccessible: {
   1108       if (Access == AS_protected &&
   1109           TryDiagnoseProtectedAccess(S, EC, Entity))
   1110         return;
   1111 
   1112       // Find an original declaration.
   1113       while (D->isOutOfLine()) {
   1114         NamedDecl *PrevDecl = 0;
   1115         if (VarDecl *VD = dyn_cast<VarDecl>(D))
   1116           PrevDecl = VD->getPreviousDecl();
   1117         else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
   1118           PrevDecl = FD->getPreviousDecl();
   1119         else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
   1120           PrevDecl = TND->getPreviousDecl();
   1121         else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
   1122           if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
   1123             break;
   1124           PrevDecl = TD->getPreviousDecl();
   1125         }
   1126         if (!PrevDecl) break;
   1127         D = PrevDecl;
   1128       }
   1129 
   1130       CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
   1131       Decl *ImmediateChild;
   1132       if (D->getDeclContext() == DeclaringClass)
   1133         ImmediateChild = D;
   1134       else {
   1135         DeclContext *DC = D->getDeclContext();
   1136         while (DC->getParent() != DeclaringClass)
   1137           DC = DC->getParent();
   1138         ImmediateChild = cast<Decl>(DC);
   1139       }
   1140 
   1141       // Check whether there's an AccessSpecDecl preceding this in the
   1142       // chain of the DeclContext.
   1143       bool Implicit = true;
   1144       for (CXXRecordDecl::decl_iterator
   1145              I = DeclaringClass->decls_begin(), E = DeclaringClass->decls_end();
   1146            I != E; ++I) {
   1147         if (*I == ImmediateChild) break;
   1148         if (isa<AccessSpecDecl>(*I)) {
   1149           Implicit = false;
   1150           break;
   1151         }
   1152       }
   1153 
   1154       S.Diag(D->getLocation(), diag::note_access_natural)
   1155         << (unsigned) (Access == AS_protected)
   1156         << Implicit;
   1157       return;
   1158     }
   1159 
   1160     case AR_accessible: break;
   1161 
   1162     case AR_dependent:
   1163       llvm_unreachable("can't diagnose dependent access failures");
   1164     }
   1165   }
   1166 
   1167   CXXBasePaths Paths;
   1168   CXXBasePath &Path = *FindBestPath(S, EC, Entity, AS_public, Paths);
   1169 
   1170   CXXBasePath::iterator I = Path.end(), E = Path.begin();
   1171   while (I != E) {
   1172     --I;
   1173 
   1174     const CXXBaseSpecifier *BS = I->Base;
   1175     AccessSpecifier BaseAccess = BS->getAccessSpecifier();
   1176 
   1177     // If this is public inheritance, or the derived class is a friend,
   1178     // skip this step.
   1179     if (BaseAccess == AS_public)
   1180       continue;
   1181 
   1182     switch (GetFriendKind(S, EC, I->Class)) {
   1183     case AR_accessible: continue;
   1184     case AR_inaccessible: break;
   1185     case AR_dependent:
   1186       llvm_unreachable("can't diagnose dependent access failures");
   1187     }
   1188 
   1189     // Check whether this base specifier is the tighest point
   1190     // constraining access.  We have to check against AS_private for
   1191     // the same reasons as above.
   1192     if (BaseAccess == AS_private || BaseAccess >= Access) {
   1193 
   1194       // We're constrained by inheritance, but we want to say
   1195       // "declared private here" if we're diagnosing a hierarchy
   1196       // conversion and this is the final step.
   1197       unsigned diagnostic;
   1198       if (D) diagnostic = diag::note_access_constrained_by_path;
   1199       else if (I + 1 == Path.end()) diagnostic = diag::note_access_natural;
   1200       else diagnostic = diag::note_access_constrained_by_path;
   1201 
   1202       S.Diag(BS->getSourceRange().getBegin(), diagnostic)
   1203         << BS->getSourceRange()
   1204         << (BaseAccess == AS_protected)
   1205         << (BS->getAccessSpecifierAsWritten() == AS_none);
   1206 
   1207       if (D)
   1208         S.Diag(D->getLocation(), diag::note_field_decl);
   1209 
   1210       return;
   1211     }
   1212   }
   1213 
   1214   llvm_unreachable("access not apparently constrained by path");
   1215 }
   1216 
   1217 static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
   1218                               const EffectiveContext &EC,
   1219                               AccessTarget &Entity) {
   1220   const CXXRecordDecl *NamingClass = Entity.getNamingClass();
   1221   const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
   1222   NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);
   1223 
   1224   S.Diag(Loc, Entity.getDiag())
   1225     << (Entity.getAccess() == AS_protected)
   1226     << (D ? D->getDeclName() : DeclarationName())
   1227     << S.Context.getTypeDeclType(NamingClass)
   1228     << S.Context.getTypeDeclType(DeclaringClass);
   1229   DiagnoseAccessPath(S, EC, Entity);
   1230 }
   1231 
   1232 /// MSVC has a bug where if during an using declaration name lookup,
   1233 /// the declaration found is unaccessible (private) and that declaration
   1234 /// was bring into scope via another using declaration whose target
   1235 /// declaration is accessible (public) then no error is generated.
   1236 /// Example:
   1237 ///   class A {
   1238 ///   public:
   1239 ///     int f();
   1240 ///   };
   1241 ///   class B : public A {
   1242 ///   private:
   1243 ///     using A::f;
   1244 ///   };
   1245 ///   class C : public B {
   1246 ///   private:
   1247 ///     using B::f;
   1248 ///   };
   1249 ///
   1250 /// Here, B::f is private so this should fail in Standard C++, but
   1251 /// because B::f refers to A::f which is public MSVC accepts it.
   1252 static bool IsMicrosoftUsingDeclarationAccessBug(Sema& S,
   1253                                                  SourceLocation AccessLoc,
   1254                                                  AccessTarget &Entity) {
   1255   if (UsingShadowDecl *Shadow =
   1256                          dyn_cast<UsingShadowDecl>(Entity.getTargetDecl())) {
   1257     const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
   1258     if (Entity.getTargetDecl()->getAccess() == AS_private &&
   1259         (OrigDecl->getAccess() == AS_public ||
   1260          OrigDecl->getAccess() == AS_protected)) {
   1261       S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
   1262         << Shadow->getUsingDecl()->getQualifiedNameAsString()
   1263         << OrigDecl->getQualifiedNameAsString();
   1264       return true;
   1265     }
   1266   }
   1267   return false;
   1268 }
   1269 
   1270 /// Determines whether the accessed entity is accessible.  Public members
   1271 /// have been weeded out by this point.
   1272 static AccessResult IsAccessible(Sema &S,
   1273                                  const EffectiveContext &EC,
   1274                                  AccessTarget &Entity) {
   1275   // Determine the actual naming class.
   1276   CXXRecordDecl *NamingClass = Entity.getNamingClass();
   1277   while (NamingClass->isAnonymousStructOrUnion())
   1278     NamingClass = cast<CXXRecordDecl>(NamingClass->getParent());
   1279   NamingClass = NamingClass->getCanonicalDecl();
   1280 
   1281   AccessSpecifier UnprivilegedAccess = Entity.getAccess();
   1282   assert(UnprivilegedAccess != AS_public && "public access not weeded out");
   1283 
   1284   // Before we try to recalculate access paths, try to white-list
   1285   // accesses which just trade in on the final step, i.e. accesses
   1286   // which don't require [M4] or [B4]. These are by far the most
   1287   // common forms of privileged access.
   1288   if (UnprivilegedAccess != AS_none) {
   1289     switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
   1290     case AR_dependent:
   1291       // This is actually an interesting policy decision.  We don't
   1292       // *have* to delay immediately here: we can do the full access
   1293       // calculation in the hope that friendship on some intermediate
   1294       // class will make the declaration accessible non-dependently.
   1295       // But that's not cheap, and odds are very good (note: assertion
   1296       // made without data) that the friend declaration will determine
   1297       // access.
   1298       return AR_dependent;
   1299 
   1300     case AR_accessible: return AR_accessible;
   1301     case AR_inaccessible: break;
   1302     }
   1303   }
   1304 
   1305   AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
   1306 
   1307   // We lower member accesses to base accesses by pretending that the
   1308   // member is a base class of its declaring class.
   1309   AccessSpecifier FinalAccess;
   1310 
   1311   if (Entity.isMemberAccess()) {
   1312     // Determine if the declaration is accessible from EC when named
   1313     // in its declaring class.
   1314     NamedDecl *Target = Entity.getTargetDecl();
   1315     const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
   1316 
   1317     FinalAccess = Target->getAccess();
   1318     switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
   1319     case AR_accessible:
   1320       FinalAccess = AS_public;
   1321       break;
   1322     case AR_inaccessible: break;
   1323     case AR_dependent: return AR_dependent; // see above
   1324     }
   1325 
   1326     if (DeclaringClass == NamingClass)
   1327       return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
   1328 
   1329     Entity.suppressInstanceContext();
   1330   } else {
   1331     FinalAccess = AS_public;
   1332   }
   1333 
   1334   assert(Entity.getDeclaringClass() != NamingClass);
   1335 
   1336   // Append the declaration's access if applicable.
   1337   CXXBasePaths Paths;
   1338   CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
   1339   if (!Path)
   1340     return AR_dependent;
   1341 
   1342   assert(Path->Access <= UnprivilegedAccess &&
   1343          "access along best path worse than direct?");
   1344   if (Path->Access == AS_public)
   1345     return AR_accessible;
   1346   return AR_inaccessible;
   1347 }
   1348 
   1349 static void DelayDependentAccess(Sema &S,
   1350                                  const EffectiveContext &EC,
   1351                                  SourceLocation Loc,
   1352                                  const AccessTarget &Entity) {
   1353   assert(EC.isDependent() && "delaying non-dependent access");
   1354   DeclContext *DC = EC.getInnerContext();
   1355   assert(DC->isDependentContext() && "delaying non-dependent access");
   1356   DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access,
   1357                               Loc,
   1358                               Entity.isMemberAccess(),
   1359                               Entity.getAccess(),
   1360                               Entity.getTargetDecl(),
   1361                               Entity.getNamingClass(),
   1362                               Entity.getBaseObjectType(),
   1363                               Entity.getDiag());
   1364 }
   1365 
   1366 /// Checks access to an entity from the given effective context.
   1367 static AccessResult CheckEffectiveAccess(Sema &S,
   1368                                          const EffectiveContext &EC,
   1369                                          SourceLocation Loc,
   1370                                          AccessTarget &Entity) {
   1371   assert(Entity.getAccess() != AS_public && "called for public access!");
   1372 
   1373   if (S.getLangOpts().MicrosoftMode &&
   1374       IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity))
   1375     return AR_accessible;
   1376 
   1377   switch (IsAccessible(S, EC, Entity)) {
   1378   case AR_dependent:
   1379     DelayDependentAccess(S, EC, Loc, Entity);
   1380     return AR_dependent;
   1381 
   1382   case AR_inaccessible:
   1383     if (!Entity.isQuiet())
   1384       DiagnoseBadAccess(S, Loc, EC, Entity);
   1385     return AR_inaccessible;
   1386 
   1387   case AR_accessible:
   1388     return AR_accessible;
   1389   }
   1390 
   1391   // silence unnecessary warning
   1392   llvm_unreachable("invalid access result");
   1393 }
   1394 
   1395 static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
   1396                                       AccessTarget &Entity) {
   1397   // If the access path is public, it's accessible everywhere.
   1398   if (Entity.getAccess() == AS_public)
   1399     return Sema::AR_accessible;
   1400 
   1401   // If we're currently parsing a declaration, we may need to delay
   1402   // access control checking, because our effective context might be
   1403   // different based on what the declaration comes out as.
   1404   //
   1405   // For example, we might be parsing a declaration with a scope
   1406   // specifier, like this:
   1407   //   A::private_type A::foo() { ... }
   1408   //
   1409   // Or we might be parsing something that will turn out to be a friend:
   1410   //   void foo(A::private_type);
   1411   //   void B::foo(A::private_type);
   1412   if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
   1413     S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
   1414     return Sema::AR_delayed;
   1415   }
   1416 
   1417   EffectiveContext EC(S.CurContext);
   1418   switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
   1419   case AR_accessible: return Sema::AR_accessible;
   1420   case AR_inaccessible: return Sema::AR_inaccessible;
   1421   case AR_dependent: return Sema::AR_dependent;
   1422   }
   1423   llvm_unreachable("falling off end");
   1424 }
   1425 
   1426 void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *decl) {
   1427   // Access control for names used in the declarations of functions
   1428   // and function templates should normally be evaluated in the context
   1429   // of the declaration, just in case it's a friend of something.
   1430   // However, this does not apply to local extern declarations.
   1431 
   1432   DeclContext *DC = decl->getDeclContext();
   1433   if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
   1434     if (!DC->isFunctionOrMethod()) DC = fn;
   1435   } else if (FunctionTemplateDecl *fnt = dyn_cast<FunctionTemplateDecl>(decl)) {
   1436     // Never a local declaration.
   1437     DC = fnt->getTemplatedDecl();
   1438   }
   1439 
   1440   EffectiveContext EC(DC);
   1441 
   1442   AccessTarget Target(DD.getAccessData());
   1443 
   1444   if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
   1445     DD.Triggered = true;
   1446 }
   1447 
   1448 void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD,
   1449                         const MultiLevelTemplateArgumentList &TemplateArgs) {
   1450   SourceLocation Loc = DD.getAccessLoc();
   1451   AccessSpecifier Access = DD.getAccess();
   1452 
   1453   Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
   1454                                        TemplateArgs);
   1455   if (!NamingD) return;
   1456   Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
   1457                                        TemplateArgs);
   1458   if (!TargetD) return;
   1459 
   1460   if (DD.isAccessToMember()) {
   1461     CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
   1462     NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
   1463     QualType BaseObjectType = DD.getAccessBaseObjectType();
   1464     if (!BaseObjectType.isNull()) {
   1465       BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
   1466                                  DeclarationName());
   1467       if (BaseObjectType.isNull()) return;
   1468     }
   1469 
   1470     AccessTarget Entity(Context,
   1471                         AccessTarget::Member,
   1472                         NamingClass,
   1473                         DeclAccessPair::make(TargetDecl, Access),
   1474                         BaseObjectType);
   1475     Entity.setDiag(DD.getDiagnostic());
   1476     CheckAccess(*this, Loc, Entity);
   1477   } else {
   1478     AccessTarget Entity(Context,
   1479                         AccessTarget::Base,
   1480                         cast<CXXRecordDecl>(TargetD),
   1481                         cast<CXXRecordDecl>(NamingD),
   1482                         Access);
   1483     Entity.setDiag(DD.getDiagnostic());
   1484     CheckAccess(*this, Loc, Entity);
   1485   }
   1486 }
   1487 
   1488 Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
   1489                                                      DeclAccessPair Found) {
   1490   if (!getLangOpts().AccessControl ||
   1491       !E->getNamingClass() ||
   1492       Found.getAccess() == AS_public)
   1493     return AR_accessible;
   1494 
   1495   AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
   1496                       Found, QualType());
   1497   Entity.setDiag(diag::err_access) << E->getSourceRange();
   1498 
   1499   return CheckAccess(*this, E->getNameLoc(), Entity);
   1500 }
   1501 
   1502 /// Perform access-control checking on a previously-unresolved member
   1503 /// access which has now been resolved to a member.
   1504 Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
   1505                                                      DeclAccessPair Found) {
   1506   if (!getLangOpts().AccessControl ||
   1507       Found.getAccess() == AS_public)
   1508     return AR_accessible;
   1509 
   1510   QualType BaseType = E->getBaseType();
   1511   if (E->isArrow())
   1512     BaseType = BaseType->getAs<PointerType>()->getPointeeType();
   1513 
   1514   AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
   1515                       Found, BaseType);
   1516   Entity.setDiag(diag::err_access) << E->getSourceRange();
   1517 
   1518   return CheckAccess(*this, E->getMemberLoc(), Entity);
   1519 }
   1520 
   1521 /// Is the given special member function accessible for the purposes of
   1522 /// deciding whether to define a special member function as deleted?
   1523 bool Sema::isSpecialMemberAccessibleForDeletion(CXXMethodDecl *decl,
   1524                                                 AccessSpecifier access,
   1525                                                 QualType objectType) {
   1526   // Fast path.
   1527   if (access == AS_public || !getLangOpts().AccessControl) return true;
   1528 
   1529   AccessTarget entity(Context, AccessTarget::Member, decl->getParent(),
   1530                       DeclAccessPair::make(decl, access), objectType);
   1531 
   1532   // Suppress diagnostics.
   1533   entity.setDiag(PDiag());
   1534 
   1535   switch (CheckAccess(*this, SourceLocation(), entity)) {
   1536   case AR_accessible: return true;
   1537   case AR_inaccessible: return false;
   1538   case AR_dependent: llvm_unreachable("dependent for =delete computation");
   1539   case AR_delayed: llvm_unreachable("cannot delay =delete computation");
   1540   }
   1541   llvm_unreachable("bad access result");
   1542 }
   1543 
   1544 Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
   1545                                                CXXDestructorDecl *Dtor,
   1546                                                const PartialDiagnostic &PDiag,
   1547                                                QualType ObjectTy) {
   1548   if (!getLangOpts().AccessControl)
   1549     return AR_accessible;
   1550 
   1551   // There's never a path involved when checking implicit destructor access.
   1552   AccessSpecifier Access = Dtor->getAccess();
   1553   if (Access == AS_public)
   1554     return AR_accessible;
   1555 
   1556   CXXRecordDecl *NamingClass = Dtor->getParent();
   1557   if (ObjectTy.isNull()) ObjectTy = Context.getTypeDeclType(NamingClass);
   1558 
   1559   AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
   1560                       DeclAccessPair::make(Dtor, Access),
   1561                       ObjectTy);
   1562   Entity.setDiag(PDiag); // TODO: avoid copy
   1563 
   1564   return CheckAccess(*this, Loc, Entity);
   1565 }
   1566 
   1567 /// Checks access to a constructor.
   1568 Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
   1569                                                 CXXConstructorDecl *Constructor,
   1570                                                 const InitializedEntity &Entity,
   1571                                                 AccessSpecifier Access,
   1572                                                 bool IsCopyBindingRefToTemp) {
   1573   if (!getLangOpts().AccessControl || Access == AS_public)
   1574     return AR_accessible;
   1575 
   1576   PartialDiagnostic PD(PDiag());
   1577   switch (Entity.getKind()) {
   1578   default:
   1579     PD = PDiag(IsCopyBindingRefToTemp
   1580                  ? diag::ext_rvalue_to_reference_access_ctor
   1581                  : diag::err_access_ctor);
   1582 
   1583     break;
   1584 
   1585   case InitializedEntity::EK_Base:
   1586     PD = PDiag(diag::err_access_base_ctor);
   1587     PD << Entity.isInheritedVirtualBase()
   1588        << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor);
   1589     break;
   1590 
   1591   case InitializedEntity::EK_Member: {
   1592     const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
   1593     PD = PDiag(diag::err_access_field_ctor);
   1594     PD << Field->getType() << getSpecialMember(Constructor);
   1595     break;
   1596   }
   1597 
   1598   case InitializedEntity::EK_LambdaCapture: {
   1599     const VarDecl *Var = Entity.getCapturedVar();
   1600     PD = PDiag(diag::err_access_lambda_capture);
   1601     PD << Var->getName() << Entity.getType() << getSpecialMember(Constructor);
   1602     break;
   1603   }
   1604 
   1605   }
   1606 
   1607   return CheckConstructorAccess(UseLoc, Constructor, Entity, Access, PD);
   1608 }
   1609 
   1610 /// Checks access to a constructor.
   1611 Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
   1612                                                 CXXConstructorDecl *Constructor,
   1613                                                 const InitializedEntity &Entity,
   1614                                                 AccessSpecifier Access,
   1615                                                 const PartialDiagnostic &PD) {
   1616   if (!getLangOpts().AccessControl ||
   1617       Access == AS_public)
   1618     return AR_accessible;
   1619 
   1620   CXXRecordDecl *NamingClass = Constructor->getParent();
   1621 
   1622   // Initializing a base sub-object is an instance method call on an
   1623   // object of the derived class.  Otherwise, we have an instance method
   1624   // call on an object of the constructed type.
   1625   CXXRecordDecl *ObjectClass;
   1626   if (Entity.getKind() == InitializedEntity::EK_Base) {
   1627     ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
   1628   } else {
   1629     ObjectClass = NamingClass;
   1630   }
   1631 
   1632   AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass,
   1633                             DeclAccessPair::make(Constructor, Access),
   1634                             Context.getTypeDeclType(ObjectClass));
   1635   AccessEntity.setDiag(PD);
   1636 
   1637   return CheckAccess(*this, UseLoc, AccessEntity);
   1638 }
   1639 
   1640 /// Checks access to an overloaded operator new or delete.
   1641 Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
   1642                                                SourceRange PlacementRange,
   1643                                                CXXRecordDecl *NamingClass,
   1644                                                DeclAccessPair Found,
   1645                                                bool Diagnose) {
   1646   if (!getLangOpts().AccessControl ||
   1647       !NamingClass ||
   1648       Found.getAccess() == AS_public)
   1649     return AR_accessible;
   1650 
   1651   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
   1652                       QualType());
   1653   if (Diagnose)
   1654     Entity.setDiag(diag::err_access)
   1655       << PlacementRange;
   1656 
   1657   return CheckAccess(*this, OpLoc, Entity);
   1658 }
   1659 
   1660 /// Checks access to an overloaded member operator, including
   1661 /// conversion operators.
   1662 Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
   1663                                                    Expr *ObjectExpr,
   1664                                                    Expr *ArgExpr,
   1665                                                    DeclAccessPair Found) {
   1666   if (!getLangOpts().AccessControl ||
   1667       Found.getAccess() == AS_public)
   1668     return AR_accessible;
   1669 
   1670   const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
   1671   CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
   1672 
   1673   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
   1674                       ObjectExpr->getType());
   1675   Entity.setDiag(diag::err_access)
   1676     << ObjectExpr->getSourceRange()
   1677     << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange());
   1678 
   1679   return CheckAccess(*this, OpLoc, Entity);
   1680 }
   1681 
   1682 /// Checks access to the target of a friend declaration.
   1683 Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
   1684   assert(isa<CXXMethodDecl>(target) ||
   1685          (isa<FunctionTemplateDecl>(target) &&
   1686           isa<CXXMethodDecl>(cast<FunctionTemplateDecl>(target)
   1687                                ->getTemplatedDecl())));
   1688 
   1689   // Friendship lookup is a redeclaration lookup, so there's never an
   1690   // inheritance path modifying access.
   1691   AccessSpecifier access = target->getAccess();
   1692 
   1693   if (!getLangOpts().AccessControl || access == AS_public)
   1694     return AR_accessible;
   1695 
   1696   CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(target);
   1697   if (!method)
   1698     method = cast<CXXMethodDecl>(
   1699                      cast<FunctionTemplateDecl>(target)->getTemplatedDecl());
   1700   assert(method->getQualifier());
   1701 
   1702   AccessTarget entity(Context, AccessTarget::Member,
   1703                       cast<CXXRecordDecl>(target->getDeclContext()),
   1704                       DeclAccessPair::make(target, access),
   1705                       /*no instance context*/ QualType());
   1706   entity.setDiag(diag::err_access_friend_function)
   1707     << method->getQualifierLoc().getSourceRange();
   1708 
   1709   // We need to bypass delayed-diagnostics because we might be called
   1710   // while the ParsingDeclarator is active.
   1711   EffectiveContext EC(CurContext);
   1712   switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
   1713   case AR_accessible: return Sema::AR_accessible;
   1714   case AR_inaccessible: return Sema::AR_inaccessible;
   1715   case AR_dependent: return Sema::AR_dependent;
   1716   }
   1717   llvm_unreachable("falling off end");
   1718 }
   1719 
   1720 Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
   1721                                                     DeclAccessPair Found) {
   1722   if (!getLangOpts().AccessControl ||
   1723       Found.getAccess() == AS_none ||
   1724       Found.getAccess() == AS_public)
   1725     return AR_accessible;
   1726 
   1727   OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
   1728   CXXRecordDecl *NamingClass = Ovl->getNamingClass();
   1729 
   1730   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
   1731                       /*no instance context*/ QualType());
   1732   Entity.setDiag(diag::err_access)
   1733     << Ovl->getSourceRange();
   1734 
   1735   return CheckAccess(*this, Ovl->getNameLoc(), Entity);
   1736 }
   1737 
   1738 /// Checks access for a hierarchy conversion.
   1739 ///
   1740 /// \param ForceCheck true if this check should be performed even if access
   1741 ///     control is disabled;  some things rely on this for semantics
   1742 /// \param ForceUnprivileged true if this check should proceed as if the
   1743 ///     context had no special privileges
   1744 Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
   1745                                               QualType Base,
   1746                                               QualType Derived,
   1747                                               const CXXBasePath &Path,
   1748                                               unsigned DiagID,
   1749                                               bool ForceCheck,
   1750                                               bool ForceUnprivileged) {
   1751   if (!ForceCheck && !getLangOpts().AccessControl)
   1752     return AR_accessible;
   1753 
   1754   if (Path.Access == AS_public)
   1755     return AR_accessible;
   1756 
   1757   CXXRecordDecl *BaseD, *DerivedD;
   1758   BaseD = cast<CXXRecordDecl>(Base->getAs<RecordType>()->getDecl());
   1759   DerivedD = cast<CXXRecordDecl>(Derived->getAs<RecordType>()->getDecl());
   1760 
   1761   AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
   1762                       Path.Access);
   1763   if (DiagID)
   1764     Entity.setDiag(DiagID) << Derived << Base;
   1765 
   1766   if (ForceUnprivileged) {
   1767     switch (CheckEffectiveAccess(*this, EffectiveContext(),
   1768                                  AccessLoc, Entity)) {
   1769     case ::AR_accessible: return Sema::AR_accessible;
   1770     case ::AR_inaccessible: return Sema::AR_inaccessible;
   1771     case ::AR_dependent: return Sema::AR_dependent;
   1772     }
   1773     llvm_unreachable("unexpected result from CheckEffectiveAccess");
   1774   }
   1775   return CheckAccess(*this, AccessLoc, Entity);
   1776 }
   1777 
   1778 /// Checks access to all the declarations in the given result set.
   1779 void Sema::CheckLookupAccess(const LookupResult &R) {
   1780   assert(getLangOpts().AccessControl
   1781          && "performing access check without access control");
   1782   assert(R.getNamingClass() && "performing access check without naming class");
   1783 
   1784   for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
   1785     if (I.getAccess() != AS_public) {
   1786       AccessTarget Entity(Context, AccessedEntity::Member,
   1787                           R.getNamingClass(), I.getPair(),
   1788                           R.getBaseObjectType());
   1789       Entity.setDiag(diag::err_access);
   1790       CheckAccess(*this, R.getNameLoc(), Entity);
   1791     }
   1792   }
   1793 }
   1794 
   1795 /// Checks access to Decl from the given class. The check will take access
   1796 /// specifiers into account, but no member access expressions and such.
   1797 ///
   1798 /// \param Decl the declaration to check if it can be accessed
   1799 /// \param Ctx the class/context from which to start the search
   1800 /// \return true if the Decl is accessible from the Class, false otherwise.
   1801 bool Sema::IsSimplyAccessible(NamedDecl *Decl, DeclContext *Ctx) {
   1802   if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx)) {
   1803     if (!Decl->isCXXClassMember())
   1804       return true;
   1805 
   1806     QualType qType = Class->getTypeForDecl()->getCanonicalTypeInternal();
   1807     AccessTarget Entity(Context, AccessedEntity::Member, Class,
   1808                         DeclAccessPair::make(Decl, Decl->getAccess()),
   1809                         qType);
   1810     if (Entity.getAccess() == AS_public)
   1811       return true;
   1812 
   1813     EffectiveContext EC(CurContext);
   1814     return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
   1815   }
   1816 
   1817   if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Decl)) {
   1818     // @public and @package ivars are always accessible.
   1819     if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public ||
   1820         Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package)
   1821       return true;
   1822 
   1823 
   1824 
   1825     // If we are inside a class or category implementation, determine the
   1826     // interface we're in.
   1827     ObjCInterfaceDecl *ClassOfMethodDecl = 0;
   1828     if (ObjCMethodDecl *MD = getCurMethodDecl())
   1829       ClassOfMethodDecl =  MD->getClassInterface();
   1830     else if (FunctionDecl *FD = getCurFunctionDecl()) {
   1831       if (ObjCImplDecl *Impl
   1832             = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
   1833         if (ObjCImplementationDecl *IMPD
   1834               = dyn_cast<ObjCImplementationDecl>(Impl))
   1835           ClassOfMethodDecl = IMPD->getClassInterface();
   1836         else if (ObjCCategoryImplDecl* CatImplClass
   1837                    = dyn_cast<ObjCCategoryImplDecl>(Impl))
   1838           ClassOfMethodDecl = CatImplClass->getClassInterface();
   1839       }
   1840     }
   1841 
   1842     // If we're not in an interface, this ivar is inaccessible.
   1843     if (!ClassOfMethodDecl)
   1844       return false;
   1845 
   1846     // If we're inside the same interface that owns the ivar, we're fine.
   1847     if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))
   1848       return true;
   1849 
   1850     // If the ivar is private, it's inaccessible.
   1851     if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private)
   1852       return false;
   1853 
   1854     return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);
   1855   }
   1856 
   1857   return true;
   1858 }
   1859