clang API Documentation

SemaAccess.cpp
Go to the documentation of this file.
00001 //===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file provides Sema routines for C++ access control semantics.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/Sema/SemaInternal.h"
00015 #include "clang/AST/ASTContext.h"
00016 #include "clang/AST/CXXInheritance.h"
00017 #include "clang/AST/DeclCXX.h"
00018 #include "clang/AST/DeclFriend.h"
00019 #include "clang/AST/DeclObjC.h"
00020 #include "clang/AST/DependentDiagnostic.h"
00021 #include "clang/AST/ExprCXX.h"
00022 #include "clang/Sema/DelayedDiagnostic.h"
00023 #include "clang/Sema/Initialization.h"
00024 #include "clang/Sema/Lookup.h"
00025 
00026 using namespace clang;
00027 using namespace sema;
00028 
00029 /// A copy of Sema's enum without AR_delayed.
00030 enum AccessResult {
00031   AR_accessible,
00032   AR_inaccessible,
00033   AR_dependent
00034 };
00035 
00036 /// SetMemberAccessSpecifier - Set the access specifier of a member.
00037 /// Returns true on error (when the previous member decl access specifier
00038 /// is different from the new member decl access specifier).
00039 bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
00040                                     NamedDecl *PrevMemberDecl,
00041                                     AccessSpecifier LexicalAS) {
00042   if (!PrevMemberDecl) {
00043     // Use the lexical access specifier.
00044     MemberDecl->setAccess(LexicalAS);
00045     return false;
00046   }
00047 
00048   // C++ [class.access.spec]p3: When a member is redeclared its access
00049   // specifier must be same as its initial declaration.
00050   if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
00051     Diag(MemberDecl->getLocation(),
00052          diag::err_class_redeclared_with_different_access)
00053       << MemberDecl << LexicalAS;
00054     Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
00055       << PrevMemberDecl << PrevMemberDecl->getAccess();
00056 
00057     MemberDecl->setAccess(LexicalAS);
00058     return true;
00059   }
00060 
00061   MemberDecl->setAccess(PrevMemberDecl->getAccess());
00062   return false;
00063 }
00064 
00065 static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) {
00066   DeclContext *DC = D->getDeclContext();
00067 
00068   // This can only happen at top: enum decls only "publish" their
00069   // immediate members.
00070   if (isa<EnumDecl>(DC))
00071     DC = cast<EnumDecl>(DC)->getDeclContext();
00072 
00073   CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
00074   while (DeclaringClass->isAnonymousStructOrUnion())
00075     DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
00076   return DeclaringClass;
00077 }
00078 
00079 namespace {
00080 struct EffectiveContext {
00081   EffectiveContext() : Inner(nullptr), Dependent(false) {}
00082 
00083   explicit EffectiveContext(DeclContext *DC)
00084     : Inner(DC),
00085       Dependent(DC->isDependentContext()) {
00086 
00087     // C++11 [class.access.nest]p1:
00088     //   A nested class is a member and as such has the same access
00089     //   rights as any other member.
00090     // C++11 [class.access]p2:
00091     //   A member of a class can also access all the names to which
00092     //   the class has access.  A local class of a member function
00093     //   may access the same names that the member function itself
00094     //   may access.
00095     // This almost implies that the privileges of nesting are transitive.
00096     // Technically it says nothing about the local classes of non-member
00097     // functions (which can gain privileges through friendship), but we
00098     // take that as an oversight.
00099     while (true) {
00100       // We want to add canonical declarations to the EC lists for
00101       // simplicity of checking, but we need to walk up through the
00102       // actual current DC chain.  Otherwise, something like a local
00103       // extern or friend which happens to be the canonical
00104       // declaration will really mess us up.
00105 
00106       if (isa<CXXRecordDecl>(DC)) {
00107         CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
00108         Records.push_back(Record->getCanonicalDecl());
00109         DC = Record->getDeclContext();
00110       } else if (isa<FunctionDecl>(DC)) {
00111         FunctionDecl *Function = cast<FunctionDecl>(DC);
00112         Functions.push_back(Function->getCanonicalDecl());
00113         if (Function->getFriendObjectKind())
00114           DC = Function->getLexicalDeclContext();
00115         else
00116           DC = Function->getDeclContext();
00117       } else if (DC->isFileContext()) {
00118         break;
00119       } else {
00120         DC = DC->getParent();
00121       }
00122     }
00123   }
00124 
00125   bool isDependent() const { return Dependent; }
00126 
00127   bool includesClass(const CXXRecordDecl *R) const {
00128     R = R->getCanonicalDecl();
00129     return std::find(Records.begin(), Records.end(), R)
00130              != Records.end();
00131   }
00132 
00133   /// Retrieves the innermost "useful" context.  Can be null if we're
00134   /// doing access-control without privileges.
00135   DeclContext *getInnerContext() const {
00136     return Inner;
00137   }
00138 
00139   typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
00140 
00141   DeclContext *Inner;
00142   SmallVector<FunctionDecl*, 4> Functions;
00143   SmallVector<CXXRecordDecl*, 4> Records;
00144   bool Dependent;
00145 };
00146 
00147 /// Like sema::AccessedEntity, but kindly lets us scribble all over
00148 /// it.
00149 struct AccessTarget : public AccessedEntity {
00150   AccessTarget(const AccessedEntity &Entity)
00151     : AccessedEntity(Entity) {
00152     initialize();
00153   }
00154     
00155   AccessTarget(ASTContext &Context, 
00156                MemberNonce _,
00157                CXXRecordDecl *NamingClass,
00158                DeclAccessPair FoundDecl,
00159                QualType BaseObjectType)
00160     : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,
00161                      FoundDecl, BaseObjectType) {
00162     initialize();
00163   }
00164 
00165   AccessTarget(ASTContext &Context, 
00166                BaseNonce _,
00167                CXXRecordDecl *BaseClass,
00168                CXXRecordDecl *DerivedClass,
00169                AccessSpecifier Access)
00170     : AccessedEntity(Context.getDiagAllocator(), Base, BaseClass, DerivedClass,
00171                      Access) {
00172     initialize();
00173   }
00174 
00175   bool isInstanceMember() const {
00176     return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
00177   }
00178 
00179   bool hasInstanceContext() const {
00180     return HasInstanceContext;
00181   }
00182 
00183   class SavedInstanceContext {
00184   public:
00185     ~SavedInstanceContext() {
00186       Target.HasInstanceContext = Has;
00187     }
00188 
00189   private:
00190     friend struct AccessTarget;
00191     explicit SavedInstanceContext(AccessTarget &Target)
00192       : Target(Target), Has(Target.HasInstanceContext) {}
00193     AccessTarget &Target;
00194     bool Has;
00195   };
00196 
00197   SavedInstanceContext saveInstanceContext() {
00198     return SavedInstanceContext(*this);
00199   }
00200 
00201   void suppressInstanceContext() {
00202     HasInstanceContext = false;
00203   }
00204 
00205   const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
00206     assert(HasInstanceContext);
00207     if (CalculatedInstanceContext)
00208       return InstanceContext;
00209 
00210     CalculatedInstanceContext = true;
00211     DeclContext *IC = S.computeDeclContext(getBaseObjectType());
00212     InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
00213                           : nullptr);
00214     return InstanceContext;
00215   }
00216 
00217   const CXXRecordDecl *getDeclaringClass() const {
00218     return DeclaringClass;
00219   }
00220 
00221   /// The "effective" naming class is the canonical non-anonymous
00222   /// class containing the actual naming class.
00223   const CXXRecordDecl *getEffectiveNamingClass() const {
00224     const CXXRecordDecl *namingClass = getNamingClass();
00225     while (namingClass->isAnonymousStructOrUnion())
00226       namingClass = cast<CXXRecordDecl>(namingClass->getParent());
00227     return namingClass->getCanonicalDecl();
00228   }
00229 
00230 private:
00231   void initialize() {
00232     HasInstanceContext = (isMemberAccess() &&
00233                           !getBaseObjectType().isNull() &&
00234                           getTargetDecl()->isCXXInstanceMember());
00235     CalculatedInstanceContext = false;
00236     InstanceContext = nullptr;
00237 
00238     if (isMemberAccess())
00239       DeclaringClass = FindDeclaringClass(getTargetDecl());
00240     else
00241       DeclaringClass = getBaseClass();
00242     DeclaringClass = DeclaringClass->getCanonicalDecl();
00243   }
00244 
00245   bool HasInstanceContext : 1;
00246   mutable bool CalculatedInstanceContext : 1;
00247   mutable const CXXRecordDecl *InstanceContext;
00248   const CXXRecordDecl *DeclaringClass;
00249 };
00250 
00251 }
00252 
00253 /// Checks whether one class might instantiate to the other.
00254 static bool MightInstantiateTo(const CXXRecordDecl *From,
00255                                const CXXRecordDecl *To) {
00256   // Declaration names are always preserved by instantiation.
00257   if (From->getDeclName() != To->getDeclName())
00258     return false;
00259 
00260   const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
00261   const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
00262   if (FromDC == ToDC) return true;
00263   if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
00264 
00265   // Be conservative.
00266   return true;
00267 }
00268 
00269 /// Checks whether one class is derived from another, inclusively.
00270 /// Properly indicates when it couldn't be determined due to
00271 /// dependence.
00272 ///
00273 /// This should probably be donated to AST or at least Sema.
00274 static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived,
00275                                            const CXXRecordDecl *Target) {
00276   assert(Derived->getCanonicalDecl() == Derived);
00277   assert(Target->getCanonicalDecl() == Target);
00278 
00279   if (Derived == Target) return AR_accessible;
00280 
00281   bool CheckDependent = Derived->isDependentContext();
00282   if (CheckDependent && MightInstantiateTo(Derived, Target))
00283     return AR_dependent;
00284 
00285   AccessResult OnFailure = AR_inaccessible;
00286   SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
00287 
00288   while (true) {
00289     if (Derived->isDependentContext() && !Derived->hasDefinition())
00290       return AR_dependent;
00291     
00292     for (const auto &I : Derived->bases()) {
00293       const CXXRecordDecl *RD;
00294 
00295       QualType T = I.getType();
00296       if (const RecordType *RT = T->getAs<RecordType>()) {
00297         RD = cast<CXXRecordDecl>(RT->getDecl());
00298       } else if (const InjectedClassNameType *IT
00299                    = T->getAs<InjectedClassNameType>()) {
00300         RD = IT->getDecl();
00301       } else {
00302         assert(T->isDependentType() && "non-dependent base wasn't a record?");
00303         OnFailure = AR_dependent;
00304         continue;
00305       }
00306 
00307       RD = RD->getCanonicalDecl();
00308       if (RD == Target) return AR_accessible;
00309       if (CheckDependent && MightInstantiateTo(RD, Target))
00310         OnFailure = AR_dependent;
00311 
00312       Queue.push_back(RD);
00313     }
00314 
00315     if (Queue.empty()) break;
00316 
00317     Derived = Queue.pop_back_val();
00318   }
00319 
00320   return OnFailure;
00321 }
00322 
00323 
00324 static bool MightInstantiateTo(Sema &S, DeclContext *Context,
00325                                DeclContext *Friend) {
00326   if (Friend == Context)
00327     return true;
00328 
00329   assert(!Friend->isDependentContext() &&
00330          "can't handle friends with dependent contexts here");
00331 
00332   if (!Context->isDependentContext())
00333     return false;
00334 
00335   if (Friend->isFileContext())
00336     return false;
00337 
00338   // TODO: this is very conservative
00339   return true;
00340 }
00341 
00342 // Asks whether the type in 'context' can ever instantiate to the type
00343 // in 'friend'.
00344 static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) {
00345   if (Friend == Context)
00346     return true;
00347 
00348   if (!Friend->isDependentType() && !Context->isDependentType())
00349     return false;
00350 
00351   // TODO: this is very conservative.
00352   return true;
00353 }
00354 
00355 static bool MightInstantiateTo(Sema &S,
00356                                FunctionDecl *Context,
00357                                FunctionDecl *Friend) {
00358   if (Context->getDeclName() != Friend->getDeclName())
00359     return false;
00360 
00361   if (!MightInstantiateTo(S,
00362                           Context->getDeclContext(),
00363                           Friend->getDeclContext()))
00364     return false;
00365 
00366   CanQual<FunctionProtoType> FriendTy
00367     = S.Context.getCanonicalType(Friend->getType())
00368          ->getAs<FunctionProtoType>();
00369   CanQual<FunctionProtoType> ContextTy
00370     = S.Context.getCanonicalType(Context->getType())
00371          ->getAs<FunctionProtoType>();
00372 
00373   // There isn't any way that I know of to add qualifiers
00374   // during instantiation.
00375   if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
00376     return false;
00377 
00378   if (FriendTy->getNumParams() != ContextTy->getNumParams())
00379     return false;
00380 
00381   if (!MightInstantiateTo(S, ContextTy->getReturnType(),
00382                           FriendTy->getReturnType()))
00383     return false;
00384 
00385   for (unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
00386     if (!MightInstantiateTo(S, ContextTy->getParamType(I),
00387                             FriendTy->getParamType(I)))
00388       return false;
00389 
00390   return true;
00391 }
00392 
00393 static bool MightInstantiateTo(Sema &S,
00394                                FunctionTemplateDecl *Context,
00395                                FunctionTemplateDecl *Friend) {
00396   return MightInstantiateTo(S,
00397                             Context->getTemplatedDecl(),
00398                             Friend->getTemplatedDecl());
00399 }
00400 
00401 static AccessResult MatchesFriend(Sema &S,
00402                                   const EffectiveContext &EC,
00403                                   const CXXRecordDecl *Friend) {
00404   if (EC.includesClass(Friend))
00405     return AR_accessible;
00406 
00407   if (EC.isDependent()) {
00408     CanQualType FriendTy
00409       = S.Context.getCanonicalType(S.Context.getTypeDeclType(Friend));
00410 
00411     for (EffectiveContext::record_iterator
00412            I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
00413       CanQualType ContextTy
00414         = S.Context.getCanonicalType(S.Context.getTypeDeclType(*I));
00415       if (MightInstantiateTo(S, ContextTy, FriendTy))
00416         return AR_dependent;
00417     }
00418   }
00419 
00420   return AR_inaccessible;
00421 }
00422 
00423 static AccessResult MatchesFriend(Sema &S,
00424                                   const EffectiveContext &EC,
00425                                   CanQualType Friend) {
00426   if (const RecordType *RT = Friend->getAs<RecordType>())
00427     return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
00428 
00429   // TODO: we can do better than this
00430   if (Friend->isDependentType())
00431     return AR_dependent;
00432 
00433   return AR_inaccessible;
00434 }
00435 
00436 /// Determines whether the given friend class template matches
00437 /// anything in the effective context.
00438 static AccessResult MatchesFriend(Sema &S,
00439                                   const EffectiveContext &EC,
00440                                   ClassTemplateDecl *Friend) {
00441   AccessResult OnFailure = AR_inaccessible;
00442 
00443   // Check whether the friend is the template of a class in the
00444   // context chain.
00445   for (SmallVectorImpl<CXXRecordDecl*>::const_iterator
00446          I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
00447     CXXRecordDecl *Record = *I;
00448 
00449     // Figure out whether the current class has a template:
00450     ClassTemplateDecl *CTD;
00451 
00452     // A specialization of the template...
00453     if (isa<ClassTemplateSpecializationDecl>(Record)) {
00454       CTD = cast<ClassTemplateSpecializationDecl>(Record)
00455         ->getSpecializedTemplate();
00456 
00457     // ... or the template pattern itself.
00458     } else {
00459       CTD = Record->getDescribedClassTemplate();
00460       if (!CTD) continue;
00461     }
00462 
00463     // It's a match.
00464     if (Friend == CTD->getCanonicalDecl())
00465       return AR_accessible;
00466 
00467     // If the context isn't dependent, it can't be a dependent match.
00468     if (!EC.isDependent())
00469       continue;
00470 
00471     // If the template names don't match, it can't be a dependent
00472     // match.
00473     if (CTD->getDeclName() != Friend->getDeclName())
00474       continue;
00475 
00476     // If the class's context can't instantiate to the friend's
00477     // context, it can't be a dependent match.
00478     if (!MightInstantiateTo(S, CTD->getDeclContext(),
00479                             Friend->getDeclContext()))
00480       continue;
00481 
00482     // Otherwise, it's a dependent match.
00483     OnFailure = AR_dependent;
00484   }
00485 
00486   return OnFailure;
00487 }
00488 
00489 /// Determines whether the given friend function matches anything in
00490 /// the effective context.
00491 static AccessResult MatchesFriend(Sema &S,
00492                                   const EffectiveContext &EC,
00493                                   FunctionDecl *Friend) {
00494   AccessResult OnFailure = AR_inaccessible;
00495 
00496   for (SmallVectorImpl<FunctionDecl*>::const_iterator
00497          I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
00498     if (Friend == *I)
00499       return AR_accessible;
00500 
00501     if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
00502       OnFailure = AR_dependent;
00503   }
00504 
00505   return OnFailure;
00506 }
00507 
00508 /// Determines whether the given friend function template matches
00509 /// anything in the effective context.
00510 static AccessResult MatchesFriend(Sema &S,
00511                                   const EffectiveContext &EC,
00512                                   FunctionTemplateDecl *Friend) {
00513   if (EC.Functions.empty()) return AR_inaccessible;
00514 
00515   AccessResult OnFailure = AR_inaccessible;
00516 
00517   for (SmallVectorImpl<FunctionDecl*>::const_iterator
00518          I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
00519 
00520     FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
00521     if (!FTD)
00522       FTD = (*I)->getDescribedFunctionTemplate();
00523     if (!FTD)
00524       continue;
00525 
00526     FTD = FTD->getCanonicalDecl();
00527 
00528     if (Friend == FTD)
00529       return AR_accessible;
00530 
00531     if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
00532       OnFailure = AR_dependent;
00533   }
00534 
00535   return OnFailure;
00536 }
00537 
00538 /// Determines whether the given friend declaration matches anything
00539 /// in the effective context.
00540 static AccessResult MatchesFriend(Sema &S,
00541                                   const EffectiveContext &EC,
00542                                   FriendDecl *FriendD) {
00543   // Whitelist accesses if there's an invalid or unsupported friend
00544   // declaration.
00545   if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend())
00546     return AR_accessible;
00547 
00548   if (TypeSourceInfo *T = FriendD->getFriendType())
00549     return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
00550 
00551   NamedDecl *Friend
00552     = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
00553 
00554   // FIXME: declarations with dependent or templated scope.
00555 
00556   if (isa<ClassTemplateDecl>(Friend))
00557     return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
00558 
00559   if (isa<FunctionTemplateDecl>(Friend))
00560     return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
00561 
00562   if (isa<CXXRecordDecl>(Friend))
00563     return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
00564 
00565   assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
00566   return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
00567 }
00568 
00569 static AccessResult GetFriendKind(Sema &S,
00570                                   const EffectiveContext &EC,
00571                                   const CXXRecordDecl *Class) {
00572   AccessResult OnFailure = AR_inaccessible;
00573 
00574   // Okay, check friends.
00575   for (auto *Friend : Class->friends()) {
00576     switch (MatchesFriend(S, EC, Friend)) {
00577     case AR_accessible:
00578       return AR_accessible;
00579 
00580     case AR_inaccessible:
00581       continue;
00582 
00583     case AR_dependent:
00584       OnFailure = AR_dependent;
00585       break;
00586     }
00587   }
00588 
00589   // That's it, give up.
00590   return OnFailure;
00591 }
00592 
00593 namespace {
00594 
00595 /// A helper class for checking for a friend which will grant access
00596 /// to a protected instance member.
00597 struct ProtectedFriendContext {
00598   Sema &S;
00599   const EffectiveContext &EC;
00600   const CXXRecordDecl *NamingClass;
00601   bool CheckDependent;
00602   bool EverDependent;
00603 
00604   /// The path down to the current base class.
00605   SmallVector<const CXXRecordDecl*, 20> CurPath;
00606 
00607   ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
00608                          const CXXRecordDecl *InstanceContext,
00609                          const CXXRecordDecl *NamingClass)
00610     : S(S), EC(EC), NamingClass(NamingClass),
00611       CheckDependent(InstanceContext->isDependentContext() ||
00612                      NamingClass->isDependentContext()),
00613       EverDependent(false) {}
00614 
00615   /// Check classes in the current path for friendship, starting at
00616   /// the given index.
00617   bool checkFriendshipAlongPath(unsigned I) {
00618     assert(I < CurPath.size());
00619     for (unsigned E = CurPath.size(); I != E; ++I) {
00620       switch (GetFriendKind(S, EC, CurPath[I])) {
00621       case AR_accessible:   return true;
00622       case AR_inaccessible: continue;
00623       case AR_dependent:    EverDependent = true; continue;
00624       }
00625     }
00626     return false;
00627   }
00628 
00629   /// Perform a search starting at the given class.
00630   ///
00631   /// PrivateDepth is the index of the last (least derived) class
00632   /// along the current path such that a notional public member of
00633   /// the final class in the path would have access in that class.
00634   bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
00635     // If we ever reach the naming class, check the current path for
00636     // friendship.  We can also stop recursing because we obviously
00637     // won't find the naming class there again.
00638     if (Cur == NamingClass)
00639       return checkFriendshipAlongPath(PrivateDepth);
00640 
00641     if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
00642       EverDependent = true;
00643 
00644     // Recurse into the base classes.
00645     for (const auto &I : Cur->bases()) {
00646       // If this is private inheritance, then a public member of the
00647       // base will not have any access in classes derived from Cur.
00648       unsigned BasePrivateDepth = PrivateDepth;
00649       if (I.getAccessSpecifier() == AS_private)
00650         BasePrivateDepth = CurPath.size() - 1;
00651 
00652       const CXXRecordDecl *RD;
00653 
00654       QualType T = I.getType();
00655       if (const RecordType *RT = T->getAs<RecordType>()) {
00656         RD = cast<CXXRecordDecl>(RT->getDecl());
00657       } else if (const InjectedClassNameType *IT
00658                    = T->getAs<InjectedClassNameType>()) {
00659         RD = IT->getDecl();
00660       } else {
00661         assert(T->isDependentType() && "non-dependent base wasn't a record?");
00662         EverDependent = true;
00663         continue;
00664       }
00665 
00666       // Recurse.  We don't need to clean up if this returns true.
00667       CurPath.push_back(RD);
00668       if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
00669         return true;
00670       CurPath.pop_back();
00671     }
00672 
00673     return false;
00674   }
00675 
00676   bool findFriendship(const CXXRecordDecl *Cur) {
00677     assert(CurPath.empty());
00678     CurPath.push_back(Cur);
00679     return findFriendship(Cur, 0);
00680   }
00681 };
00682 }
00683 
00684 /// Search for a class P that EC is a friend of, under the constraint
00685 ///   InstanceContext <= P
00686 /// if InstanceContext exists, or else
00687 ///   NamingClass <= P
00688 /// and with the additional restriction that a protected member of
00689 /// NamingClass would have some natural access in P, which implicitly
00690 /// imposes the constraint that P <= NamingClass.
00691 ///
00692 /// This isn't quite the condition laid out in the standard.
00693 /// Instead of saying that a notional protected member of NamingClass
00694 /// would have to have some natural access in P, it says the actual
00695 /// target has to have some natural access in P, which opens up the
00696 /// possibility that the target (which is not necessarily a member
00697 /// of NamingClass) might be more accessible along some path not
00698 /// passing through it.  That's really a bad idea, though, because it
00699 /// introduces two problems:
00700 ///   - Most importantly, it breaks encapsulation because you can
00701 ///     access a forbidden base class's members by directly subclassing
00702 ///     it elsewhere.
00703 ///   - It also makes access substantially harder to compute because it
00704 ///     breaks the hill-climbing algorithm: knowing that the target is
00705 ///     accessible in some base class would no longer let you change
00706 ///     the question solely to whether the base class is accessible,
00707 ///     because the original target might have been more accessible
00708 ///     because of crazy subclassing.
00709 /// So we don't implement that.
00710 static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
00711                                            const CXXRecordDecl *InstanceContext,
00712                                            const CXXRecordDecl *NamingClass) {
00713   assert(InstanceContext == nullptr ||
00714          InstanceContext->getCanonicalDecl() == InstanceContext);
00715   assert(NamingClass->getCanonicalDecl() == NamingClass);
00716 
00717   // If we don't have an instance context, our constraints give us
00718   // that NamingClass <= P <= NamingClass, i.e. P == NamingClass.
00719   // This is just the usual friendship check.
00720   if (!InstanceContext) return GetFriendKind(S, EC, NamingClass);
00721 
00722   ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
00723   if (PRC.findFriendship(InstanceContext)) return AR_accessible;
00724   if (PRC.EverDependent) return AR_dependent;
00725   return AR_inaccessible;
00726 }
00727 
00728 static AccessResult HasAccess(Sema &S,
00729                               const EffectiveContext &EC,
00730                               const CXXRecordDecl *NamingClass,
00731                               AccessSpecifier Access,
00732                               const AccessTarget &Target) {
00733   assert(NamingClass->getCanonicalDecl() == NamingClass &&
00734          "declaration should be canonicalized before being passed here");
00735 
00736   if (Access == AS_public) return AR_accessible;
00737   assert(Access == AS_private || Access == AS_protected);
00738 
00739   AccessResult OnFailure = AR_inaccessible;
00740 
00741   for (EffectiveContext::record_iterator
00742          I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
00743     // All the declarations in EC have been canonicalized, so pointer
00744     // equality from this point on will work fine.
00745     const CXXRecordDecl *ECRecord = *I;
00746 
00747     // [B2] and [M2]
00748     if (Access == AS_private) {
00749       if (ECRecord == NamingClass)
00750         return AR_accessible;
00751 
00752       if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
00753         OnFailure = AR_dependent;
00754 
00755     // [B3] and [M3]
00756     } else {
00757       assert(Access == AS_protected);
00758       switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
00759       case AR_accessible: break;
00760       case AR_inaccessible: continue;
00761       case AR_dependent: OnFailure = AR_dependent; continue;
00762       }
00763 
00764       // C++ [class.protected]p1:
00765       //   An additional access check beyond those described earlier in
00766       //   [class.access] is applied when a non-static data member or
00767       //   non-static member function is a protected member of its naming
00768       //   class.  As described earlier, access to a protected member is
00769       //   granted because the reference occurs in a friend or member of
00770       //   some class C.  If the access is to form a pointer to member,
00771       //   the nested-name-specifier shall name C or a class derived from
00772       //   C. All other accesses involve a (possibly implicit) object
00773       //   expression. In this case, the class of the object expression
00774       //   shall be C or a class derived from C.
00775       //
00776       // We interpret this as a restriction on [M3].
00777 
00778       // In this part of the code, 'C' is just our context class ECRecord.
00779       
00780       // These rules are different if we don't have an instance context.
00781       if (!Target.hasInstanceContext()) {
00782         // If it's not an instance member, these restrictions don't apply.
00783         if (!Target.isInstanceMember()) return AR_accessible;
00784 
00785         // If it's an instance member, use the pointer-to-member rule
00786         // that the naming class has to be derived from the effective
00787         // context.
00788 
00789         // Emulate a MSVC bug where the creation of pointer-to-member
00790         // to protected member of base class is allowed but only from
00791         // static member functions.
00792         if (S.getLangOpts().MSVCCompat && !EC.Functions.empty())
00793           if (CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
00794             if (MD->isStatic()) return AR_accessible;
00795 
00796         // Despite the standard's confident wording, there is a case
00797         // where you can have an instance member that's neither in a
00798         // pointer-to-member expression nor in a member access:  when
00799         // it names a field in an unevaluated context that can't be an
00800         // implicit member.  Pending clarification, we just apply the
00801         // same naming-class restriction here.
00802         //   FIXME: we're probably not correctly adding the
00803         //   protected-member restriction when we retroactively convert
00804         //   an expression to being evaluated.
00805 
00806         // We know that ECRecord derives from NamingClass.  The
00807         // restriction says to check whether NamingClass derives from
00808         // ECRecord, but that's not really necessary: two distinct
00809         // classes can't be recursively derived from each other.  So
00810         // along this path, we just need to check whether the classes
00811         // are equal.
00812         if (NamingClass == ECRecord) return AR_accessible;
00813 
00814         // Otherwise, this context class tells us nothing;  on to the next.
00815         continue;
00816       }
00817 
00818       assert(Target.isInstanceMember());
00819 
00820       const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
00821       if (!InstanceContext) {
00822         OnFailure = AR_dependent;
00823         continue;
00824       }
00825 
00826       switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
00827       case AR_accessible: return AR_accessible;
00828       case AR_inaccessible: continue;
00829       case AR_dependent: OnFailure = AR_dependent; continue;
00830       }
00831     }
00832   }
00833 
00834   // [M3] and [B3] say that, if the target is protected in N, we grant
00835   // access if the access occurs in a friend or member of some class P
00836   // that's a subclass of N and where the target has some natural
00837   // access in P.  The 'member' aspect is easy to handle because P
00838   // would necessarily be one of the effective-context records, and we
00839   // address that above.  The 'friend' aspect is completely ridiculous
00840   // to implement because there are no restrictions at all on P
00841   // *unless* the [class.protected] restriction applies.  If it does,
00842   // however, we should ignore whether the naming class is a friend,
00843   // and instead rely on whether any potential P is a friend.
00844   if (Access == AS_protected && Target.isInstanceMember()) {
00845     // Compute the instance context if possible.
00846     const CXXRecordDecl *InstanceContext = nullptr;
00847     if (Target.hasInstanceContext()) {
00848       InstanceContext = Target.resolveInstanceContext(S);
00849       if (!InstanceContext) return AR_dependent;
00850     }
00851 
00852     switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
00853     case AR_accessible: return AR_accessible;
00854     case AR_inaccessible: return OnFailure;
00855     case AR_dependent: return AR_dependent;
00856     }
00857     llvm_unreachable("impossible friendship kind");
00858   }
00859 
00860   switch (GetFriendKind(S, EC, NamingClass)) {
00861   case AR_accessible: return AR_accessible;
00862   case AR_inaccessible: return OnFailure;
00863   case AR_dependent: return AR_dependent;
00864   }
00865 
00866   // Silence bogus warnings
00867   llvm_unreachable("impossible friendship kind");
00868 }
00869 
00870 /// Finds the best path from the naming class to the declaring class,
00871 /// taking friend declarations into account.
00872 ///
00873 /// C++0x [class.access.base]p5:
00874 ///   A member m is accessible at the point R when named in class N if
00875 ///   [M1] m as a member of N is public, or
00876 ///   [M2] m as a member of N is private, and R occurs in a member or
00877 ///        friend of class N, or
00878 ///   [M3] m as a member of N is protected, and R occurs in a member or
00879 ///        friend of class N, or in a member or friend of a class P
00880 ///        derived from N, where m as a member of P is public, private,
00881 ///        or protected, or
00882 ///   [M4] there exists a base class B of N that is accessible at R, and
00883 ///        m is accessible at R when named in class B.
00884 ///
00885 /// C++0x [class.access.base]p4:
00886 ///   A base class B of N is accessible at R, if
00887 ///   [B1] an invented public member of B would be a public member of N, or
00888 ///   [B2] R occurs in a member or friend of class N, and an invented public
00889 ///        member of B would be a private or protected member of N, or
00890 ///   [B3] R occurs in a member or friend of a class P derived from N, and an
00891 ///        invented public member of B would be a private or protected member
00892 ///        of P, or
00893 ///   [B4] there exists a class S such that B is a base class of S accessible
00894 ///        at R and S is a base class of N accessible at R.
00895 ///
00896 /// Along a single inheritance path we can restate both of these
00897 /// iteratively:
00898 ///
00899 /// First, we note that M1-4 are equivalent to B1-4 if the member is
00900 /// treated as a notional base of its declaring class with inheritance
00901 /// access equivalent to the member's access.  Therefore we need only
00902 /// ask whether a class B is accessible from a class N in context R.
00903 ///
00904 /// Let B_1 .. B_n be the inheritance path in question (i.e. where
00905 /// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
00906 /// B_i).  For i in 1..n, we will calculate ACAB(i), the access to the
00907 /// closest accessible base in the path:
00908 ///   Access(a, b) = (* access on the base specifier from a to b *)
00909 ///   Merge(a, forbidden) = forbidden
00910 ///   Merge(a, private) = forbidden
00911 ///   Merge(a, b) = min(a,b)
00912 ///   Accessible(c, forbidden) = false
00913 ///   Accessible(c, private) = (R is c) || IsFriend(c, R)
00914 ///   Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
00915 ///   Accessible(c, public) = true
00916 ///   ACAB(n) = public
00917 ///   ACAB(i) =
00918 ///     let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
00919 ///     if Accessible(B_i, AccessToBase) then public else AccessToBase
00920 ///
00921 /// B is an accessible base of N at R iff ACAB(1) = public.
00922 ///
00923 /// \param FinalAccess the access of the "final step", or AS_public if
00924 ///   there is no final step.
00925 /// \return null if friendship is dependent
00926 static CXXBasePath *FindBestPath(Sema &S,
00927                                  const EffectiveContext &EC,
00928                                  AccessTarget &Target,
00929                                  AccessSpecifier FinalAccess,
00930                                  CXXBasePaths &Paths) {
00931   // Derive the paths to the desired base.
00932   const CXXRecordDecl *Derived = Target.getNamingClass();
00933   const CXXRecordDecl *Base = Target.getDeclaringClass();
00934 
00935   // FIXME: fail correctly when there are dependent paths.
00936   bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
00937                                           Paths);
00938   assert(isDerived && "derived class not actually derived from base");
00939   (void) isDerived;
00940 
00941   CXXBasePath *BestPath = nullptr;
00942 
00943   assert(FinalAccess != AS_none && "forbidden access after declaring class");
00944 
00945   bool AnyDependent = false;
00946 
00947   // Derive the friend-modified access along each path.
00948   for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
00949          PI != PE; ++PI) {
00950     AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
00951 
00952     // Walk through the path backwards.
00953     AccessSpecifier PathAccess = FinalAccess;
00954     CXXBasePath::iterator I = PI->end(), E = PI->begin();
00955     while (I != E) {
00956       --I;
00957 
00958       assert(PathAccess != AS_none);
00959 
00960       // If the declaration is a private member of a base class, there
00961       // is no level of friendship in derived classes that can make it
00962       // accessible.
00963       if (PathAccess == AS_private) {
00964         PathAccess = AS_none;
00965         break;
00966       }
00967 
00968       const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
00969 
00970       AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
00971       PathAccess = std::max(PathAccess, BaseAccess);
00972 
00973       switch (HasAccess(S, EC, NC, PathAccess, Target)) {
00974       case AR_inaccessible: break;
00975       case AR_accessible:
00976         PathAccess = AS_public;
00977 
00978         // Future tests are not against members and so do not have
00979         // instance context.
00980         Target.suppressInstanceContext();
00981         break;
00982       case AR_dependent:
00983         AnyDependent = true;
00984         goto Next;
00985       }
00986     }
00987 
00988     // Note that we modify the path's Access field to the
00989     // friend-modified access.
00990     if (BestPath == nullptr || PathAccess < BestPath->Access) {
00991       BestPath = &*PI;
00992       BestPath->Access = PathAccess;
00993 
00994       // Short-circuit if we found a public path.
00995       if (BestPath->Access == AS_public)
00996         return BestPath;
00997     }
00998 
00999   Next: ;
01000   }
01001 
01002   assert((!BestPath || BestPath->Access != AS_public) &&
01003          "fell out of loop with public path");
01004 
01005   // We didn't find a public path, but at least one path was subject
01006   // to dependent friendship, so delay the check.
01007   if (AnyDependent)
01008     return nullptr;
01009 
01010   return BestPath;
01011 }
01012 
01013 /// Given that an entity has protected natural access, check whether
01014 /// access might be denied because of the protected member access
01015 /// restriction.
01016 ///
01017 /// \return true if a note was emitted
01018 static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
01019                                        AccessTarget &Target) {
01020   // Only applies to instance accesses.
01021   if (!Target.isInstanceMember())
01022     return false;
01023 
01024   assert(Target.isMemberAccess());
01025 
01026   const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass();
01027 
01028   for (EffectiveContext::record_iterator
01029          I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
01030     const CXXRecordDecl *ECRecord = *I;
01031     switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
01032     case AR_accessible: break;
01033     case AR_inaccessible: continue;
01034     case AR_dependent: continue;
01035     }
01036 
01037     // The effective context is a subclass of the declaring class.
01038     // Check whether the [class.protected] restriction is limiting
01039     // access.
01040 
01041     // To get this exactly right, this might need to be checked more
01042     // holistically;  it's not necessarily the case that gaining
01043     // access here would grant us access overall.
01044 
01045     NamedDecl *D = Target.getTargetDecl();
01046 
01047     // If we don't have an instance context, [class.protected] says the
01048     // naming class has to equal the context class.
01049     if (!Target.hasInstanceContext()) {
01050       // If it does, the restriction doesn't apply.
01051       if (NamingClass == ECRecord) continue;
01052 
01053       // TODO: it would be great to have a fixit here, since this is
01054       // such an obvious error.
01055       S.Diag(D->getLocation(), diag::note_access_protected_restricted_noobject)
01056         << S.Context.getTypeDeclType(ECRecord);
01057       return true;
01058     }
01059 
01060     const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
01061     assert(InstanceContext && "diagnosing dependent access");
01062 
01063     switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
01064     case AR_accessible: continue;
01065     case AR_dependent: continue;
01066     case AR_inaccessible:
01067       break;
01068     }
01069 
01070     // Okay, the restriction seems to be what's limiting us.
01071 
01072     // Use a special diagnostic for constructors and destructors.
01073     if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
01074         (isa<FunctionTemplateDecl>(D) &&
01075          isa<CXXConstructorDecl>(
01076                 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
01077       return S.Diag(D->getLocation(),
01078                     diag::note_access_protected_restricted_ctordtor)
01079              << isa<CXXDestructorDecl>(D->getAsFunction());
01080     }
01081 
01082     // Otherwise, use the generic diagnostic.
01083     return S.Diag(D->getLocation(),
01084                   diag::note_access_protected_restricted_object)
01085            << S.Context.getTypeDeclType(ECRecord);
01086   }
01087 
01088   return false;
01089 }
01090 
01091 /// We are unable to access a given declaration due to its direct
01092 /// access control;  diagnose that.
01093 static void diagnoseBadDirectAccess(Sema &S,
01094                                     const EffectiveContext &EC,
01095                                     AccessTarget &entity) {
01096   assert(entity.isMemberAccess());
01097   NamedDecl *D = entity.getTargetDecl();
01098 
01099   if (D->getAccess() == AS_protected &&
01100       TryDiagnoseProtectedAccess(S, EC, entity))
01101     return;
01102 
01103   // Find an original declaration.
01104   while (D->isOutOfLine()) {
01105     NamedDecl *PrevDecl = nullptr;
01106     if (VarDecl *VD = dyn_cast<VarDecl>(D))
01107       PrevDecl = VD->getPreviousDecl();
01108     else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
01109       PrevDecl = FD->getPreviousDecl();
01110     else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
01111       PrevDecl = TND->getPreviousDecl();
01112     else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
01113       if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
01114         break;
01115       PrevDecl = TD->getPreviousDecl();
01116     }
01117     if (!PrevDecl) break;
01118     D = PrevDecl;
01119   }
01120 
01121   CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
01122   Decl *ImmediateChild;
01123   if (D->getDeclContext() == DeclaringClass)
01124     ImmediateChild = D;
01125   else {
01126     DeclContext *DC = D->getDeclContext();
01127     while (DC->getParent() != DeclaringClass)
01128       DC = DC->getParent();
01129     ImmediateChild = cast<Decl>(DC);
01130   }
01131 
01132   // Check whether there's an AccessSpecDecl preceding this in the
01133   // chain of the DeclContext.
01134   bool isImplicit = true;
01135   for (const auto *I : DeclaringClass->decls()) {
01136     if (I == ImmediateChild) break;
01137     if (isa<AccessSpecDecl>(I)) {
01138       isImplicit = false;
01139       break;
01140     }
01141   }
01142 
01143   S.Diag(D->getLocation(), diag::note_access_natural)
01144     << (unsigned) (D->getAccess() == AS_protected)
01145     << isImplicit;
01146 }
01147 
01148 /// Diagnose the path which caused the given declaration or base class
01149 /// to become inaccessible.
01150 static void DiagnoseAccessPath(Sema &S,
01151                                const EffectiveContext &EC,
01152                                AccessTarget &entity) {
01153   // Save the instance context to preserve invariants.
01154   AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
01155 
01156   // This basically repeats the main algorithm but keeps some more
01157   // information.
01158 
01159   // The natural access so far.
01160   AccessSpecifier accessSoFar = AS_public;
01161 
01162   // Check whether we have special rights to the declaring class.
01163   if (entity.isMemberAccess()) {
01164     NamedDecl *D = entity.getTargetDecl();
01165     accessSoFar = D->getAccess();
01166     const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
01167 
01168     switch (HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
01169     // If the declaration is accessible when named in its declaring
01170     // class, then we must be constrained by the path.
01171     case AR_accessible:
01172       accessSoFar = AS_public;
01173       entity.suppressInstanceContext();
01174       break;
01175 
01176     case AR_inaccessible:
01177       if (accessSoFar == AS_private ||
01178           declaringClass == entity.getEffectiveNamingClass())
01179         return diagnoseBadDirectAccess(S, EC, entity);
01180       break;
01181 
01182     case AR_dependent:
01183       llvm_unreachable("cannot diagnose dependent access");
01184     }
01185   }
01186 
01187   CXXBasePaths paths;
01188   CXXBasePath &path = *FindBestPath(S, EC, entity, accessSoFar, paths);
01189   assert(path.Access != AS_public);
01190 
01191   CXXBasePath::iterator i = path.end(), e = path.begin();
01192   CXXBasePath::iterator constrainingBase = i;
01193   while (i != e) {
01194     --i;
01195 
01196     assert(accessSoFar != AS_none && accessSoFar != AS_private);
01197 
01198     // Is the entity accessible when named in the deriving class, as
01199     // modified by the base specifier?
01200     const CXXRecordDecl *derivingClass = i->Class->getCanonicalDecl();
01201     const CXXBaseSpecifier *base = i->Base;
01202 
01203     // If the access to this base is worse than the access we have to
01204     // the declaration, remember it.
01205     AccessSpecifier baseAccess = base->getAccessSpecifier();
01206     if (baseAccess > accessSoFar) {
01207       constrainingBase = i;
01208       accessSoFar = baseAccess;
01209     }
01210 
01211     switch (HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
01212     case AR_inaccessible: break;
01213     case AR_accessible:
01214       accessSoFar = AS_public;
01215       entity.suppressInstanceContext();
01216       constrainingBase = nullptr;
01217       break;
01218     case AR_dependent:
01219       llvm_unreachable("cannot diagnose dependent access");
01220     }
01221 
01222     // If this was private inheritance, but we don't have access to
01223     // the deriving class, we're done.
01224     if (accessSoFar == AS_private) {
01225       assert(baseAccess == AS_private);
01226       assert(constrainingBase == i);
01227       break;
01228     }
01229   }
01230 
01231   // If we don't have a constraining base, the access failure must be
01232   // due to the original declaration.
01233   if (constrainingBase == path.end())
01234     return diagnoseBadDirectAccess(S, EC, entity);
01235 
01236   // We're constrained by inheritance, but we want to say
01237   // "declared private here" if we're diagnosing a hierarchy
01238   // conversion and this is the final step.
01239   unsigned diagnostic;
01240   if (entity.isMemberAccess() ||
01241       constrainingBase + 1 != path.end()) {
01242     diagnostic = diag::note_access_constrained_by_path;
01243   } else {
01244     diagnostic = diag::note_access_natural;
01245   }
01246 
01247   const CXXBaseSpecifier *base = constrainingBase->Base;
01248 
01249   S.Diag(base->getSourceRange().getBegin(), diagnostic)
01250     << base->getSourceRange()
01251     << (base->getAccessSpecifier() == AS_protected)
01252     << (base->getAccessSpecifierAsWritten() == AS_none);
01253 
01254   if (entity.isMemberAccess())
01255     S.Diag(entity.getTargetDecl()->getLocation(),
01256            diag::note_member_declared_at);
01257 }
01258 
01259 static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
01260                               const EffectiveContext &EC,
01261                               AccessTarget &Entity) {
01262   const CXXRecordDecl *NamingClass = Entity.getNamingClass();
01263   const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
01264   NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr);
01265 
01266   S.Diag(Loc, Entity.getDiag())
01267     << (Entity.getAccess() == AS_protected)
01268     << (D ? D->getDeclName() : DeclarationName())
01269     << S.Context.getTypeDeclType(NamingClass)
01270     << S.Context.getTypeDeclType(DeclaringClass);
01271   DiagnoseAccessPath(S, EC, Entity);
01272 }
01273 
01274 /// MSVC has a bug where if during an using declaration name lookup, 
01275 /// the declaration found is unaccessible (private) and that declaration 
01276 /// was bring into scope via another using declaration whose target
01277 /// declaration is accessible (public) then no error is generated.
01278 /// Example:
01279 ///   class A {
01280 ///   public:
01281 ///     int f();
01282 ///   };
01283 ///   class B : public A {
01284 ///   private:
01285 ///     using A::f;
01286 ///   };
01287 ///   class C : public B {
01288 ///   private:
01289 ///     using B::f;
01290 ///   };
01291 ///
01292 /// Here, B::f is private so this should fail in Standard C++, but 
01293 /// because B::f refers to A::f which is public MSVC accepts it.
01294 static bool IsMicrosoftUsingDeclarationAccessBug(Sema& S, 
01295                                                  SourceLocation AccessLoc,
01296                                                  AccessTarget &Entity) {
01297   if (UsingShadowDecl *Shadow =
01298                          dyn_cast<UsingShadowDecl>(Entity.getTargetDecl())) {
01299     const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
01300     if (Entity.getTargetDecl()->getAccess() == AS_private && 
01301         (OrigDecl->getAccess() == AS_public ||
01302          OrigDecl->getAccess() == AS_protected)) {
01303       S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
01304         << Shadow->getUsingDecl()->getQualifiedNameAsString()
01305         << OrigDecl->getQualifiedNameAsString();
01306       return true;
01307     }
01308   }
01309   return false;
01310 }
01311 
01312 /// Determines whether the accessed entity is accessible.  Public members
01313 /// have been weeded out by this point.
01314 static AccessResult IsAccessible(Sema &S,
01315                                  const EffectiveContext &EC,
01316                                  AccessTarget &Entity) {
01317   // Determine the actual naming class.
01318   const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
01319 
01320   AccessSpecifier UnprivilegedAccess = Entity.getAccess();
01321   assert(UnprivilegedAccess != AS_public && "public access not weeded out");
01322 
01323   // Before we try to recalculate access paths, try to white-list
01324   // accesses which just trade in on the final step, i.e. accesses
01325   // which don't require [M4] or [B4]. These are by far the most
01326   // common forms of privileged access.
01327   if (UnprivilegedAccess != AS_none) {
01328     switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
01329     case AR_dependent:
01330       // This is actually an interesting policy decision.  We don't
01331       // *have* to delay immediately here: we can do the full access
01332       // calculation in the hope that friendship on some intermediate
01333       // class will make the declaration accessible non-dependently.
01334       // But that's not cheap, and odds are very good (note: assertion
01335       // made without data) that the friend declaration will determine
01336       // access.
01337       return AR_dependent;
01338 
01339     case AR_accessible: return AR_accessible;
01340     case AR_inaccessible: break;
01341     }
01342   }
01343 
01344   AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
01345 
01346   // We lower member accesses to base accesses by pretending that the
01347   // member is a base class of its declaring class.
01348   AccessSpecifier FinalAccess;
01349 
01350   if (Entity.isMemberAccess()) {
01351     // Determine if the declaration is accessible from EC when named
01352     // in its declaring class.
01353     NamedDecl *Target = Entity.getTargetDecl();
01354     const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
01355 
01356     FinalAccess = Target->getAccess();
01357     switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
01358     case AR_accessible:
01359       // Target is accessible at EC when named in its declaring class.
01360       // We can now hill-climb and simply check whether the declaring
01361       // class is accessible as a base of the naming class.  This is
01362       // equivalent to checking the access of a notional public
01363       // member with no instance context.
01364       FinalAccess = AS_public;
01365       Entity.suppressInstanceContext();
01366       break;
01367     case AR_inaccessible: break;
01368     case AR_dependent: return AR_dependent; // see above
01369     }
01370 
01371     if (DeclaringClass == NamingClass)
01372       return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
01373   } else {
01374     FinalAccess = AS_public;
01375   }
01376 
01377   assert(Entity.getDeclaringClass() != NamingClass);
01378 
01379   // Append the declaration's access if applicable.
01380   CXXBasePaths Paths;
01381   CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
01382   if (!Path)
01383     return AR_dependent;
01384 
01385   assert(Path->Access <= UnprivilegedAccess &&
01386          "access along best path worse than direct?");
01387   if (Path->Access == AS_public)
01388     return AR_accessible;
01389   return AR_inaccessible;
01390 }
01391 
01392 static void DelayDependentAccess(Sema &S,
01393                                  const EffectiveContext &EC,
01394                                  SourceLocation Loc,
01395                                  const AccessTarget &Entity) {
01396   assert(EC.isDependent() && "delaying non-dependent access");
01397   DeclContext *DC = EC.getInnerContext();
01398   assert(DC->isDependentContext() && "delaying non-dependent access");
01399   DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access,
01400                               Loc,
01401                               Entity.isMemberAccess(),
01402                               Entity.getAccess(),
01403                               Entity.getTargetDecl(),
01404                               Entity.getNamingClass(),
01405                               Entity.getBaseObjectType(),
01406                               Entity.getDiag());
01407 }
01408 
01409 /// Checks access to an entity from the given effective context.
01410 static AccessResult CheckEffectiveAccess(Sema &S,
01411                                          const EffectiveContext &EC,
01412                                          SourceLocation Loc,
01413                                          AccessTarget &Entity) {
01414   assert(Entity.getAccess() != AS_public && "called for public access!");
01415 
01416   switch (IsAccessible(S, EC, Entity)) {
01417   case AR_dependent:
01418     DelayDependentAccess(S, EC, Loc, Entity);
01419     return AR_dependent;
01420 
01421   case AR_inaccessible:
01422     if (S.getLangOpts().MSVCCompat &&
01423         IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity))
01424       return AR_accessible;
01425     if (!Entity.isQuiet())
01426       DiagnoseBadAccess(S, Loc, EC, Entity);
01427     return AR_inaccessible;
01428 
01429   case AR_accessible:
01430     return AR_accessible;
01431   }
01432 
01433   // silence unnecessary warning
01434   llvm_unreachable("invalid access result");
01435 }
01436 
01437 static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
01438                                       AccessTarget &Entity) {
01439   // If the access path is public, it's accessible everywhere.
01440   if (Entity.getAccess() == AS_public)
01441     return Sema::AR_accessible;
01442 
01443   // If we're currently parsing a declaration, we may need to delay
01444   // access control checking, because our effective context might be
01445   // different based on what the declaration comes out as.
01446   //
01447   // For example, we might be parsing a declaration with a scope
01448   // specifier, like this:
01449   //   A::private_type A::foo() { ... }
01450   //
01451   // Or we might be parsing something that will turn out to be a friend:
01452   //   void foo(A::private_type);
01453   //   void B::foo(A::private_type);
01454   if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
01455     S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
01456     return Sema::AR_delayed;
01457   }
01458 
01459   EffectiveContext EC(S.CurContext);
01460   switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
01461   case AR_accessible: return Sema::AR_accessible;
01462   case AR_inaccessible: return Sema::AR_inaccessible;
01463   case AR_dependent: return Sema::AR_dependent;
01464   }
01465   llvm_unreachable("falling off end");
01466 }
01467 
01468 void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) {
01469   // Access control for names used in the declarations of functions
01470   // and function templates should normally be evaluated in the context
01471   // of the declaration, just in case it's a friend of something.
01472   // However, this does not apply to local extern declarations.
01473 
01474   DeclContext *DC = D->getDeclContext();
01475   if (D->isLocalExternDecl()) {
01476     DC = D->getLexicalDeclContext();
01477   } else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
01478     DC = FN;
01479   } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
01480     DC = cast<DeclContext>(TD->getTemplatedDecl());
01481   }
01482 
01483   EffectiveContext EC(DC);
01484 
01485   AccessTarget Target(DD.getAccessData());
01486 
01487   if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
01488     DD.Triggered = true;
01489 }
01490 
01491 void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD,
01492                         const MultiLevelTemplateArgumentList &TemplateArgs) {
01493   SourceLocation Loc = DD.getAccessLoc();
01494   AccessSpecifier Access = DD.getAccess();
01495 
01496   Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
01497                                        TemplateArgs);
01498   if (!NamingD) return;
01499   Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
01500                                        TemplateArgs);
01501   if (!TargetD) return;
01502 
01503   if (DD.isAccessToMember()) {
01504     CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
01505     NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
01506     QualType BaseObjectType = DD.getAccessBaseObjectType();
01507     if (!BaseObjectType.isNull()) {
01508       BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
01509                                  DeclarationName());
01510       if (BaseObjectType.isNull()) return;
01511     }
01512 
01513     AccessTarget Entity(Context,
01514                         AccessTarget::Member,
01515                         NamingClass,
01516                         DeclAccessPair::make(TargetDecl, Access),
01517                         BaseObjectType);
01518     Entity.setDiag(DD.getDiagnostic());
01519     CheckAccess(*this, Loc, Entity);
01520   } else {
01521     AccessTarget Entity(Context,
01522                         AccessTarget::Base,
01523                         cast<CXXRecordDecl>(TargetD),
01524                         cast<CXXRecordDecl>(NamingD),
01525                         Access);
01526     Entity.setDiag(DD.getDiagnostic());
01527     CheckAccess(*this, Loc, Entity);
01528   }
01529 }
01530 
01531 Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
01532                                                      DeclAccessPair Found) {
01533   if (!getLangOpts().AccessControl ||
01534       !E->getNamingClass() ||
01535       Found.getAccess() == AS_public)
01536     return AR_accessible;
01537 
01538   AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(), 
01539                       Found, QualType());
01540   Entity.setDiag(diag::err_access) << E->getSourceRange();
01541 
01542   return CheckAccess(*this, E->getNameLoc(), Entity);
01543 }
01544 
01545 /// Perform access-control checking on a previously-unresolved member
01546 /// access which has now been resolved to a member.
01547 Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
01548                                                      DeclAccessPair Found) {
01549   if (!getLangOpts().AccessControl ||
01550       Found.getAccess() == AS_public)
01551     return AR_accessible;
01552 
01553   QualType BaseType = E->getBaseType();
01554   if (E->isArrow())
01555     BaseType = BaseType->getAs<PointerType>()->getPointeeType();
01556 
01557   AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
01558                       Found, BaseType);
01559   Entity.setDiag(diag::err_access) << E->getSourceRange();
01560 
01561   return CheckAccess(*this, E->getMemberLoc(), Entity);
01562 }
01563 
01564 /// Is the given special member function accessible for the purposes of
01565 /// deciding whether to define a special member function as deleted?
01566 bool Sema::isSpecialMemberAccessibleForDeletion(CXXMethodDecl *decl,
01567                                                 AccessSpecifier access,
01568                                                 QualType objectType) {
01569   // Fast path.
01570   if (access == AS_public || !getLangOpts().AccessControl) return true;
01571 
01572   AccessTarget entity(Context, AccessTarget::Member, decl->getParent(),
01573                       DeclAccessPair::make(decl, access), objectType);
01574 
01575   // Suppress diagnostics.
01576   entity.setDiag(PDiag());
01577 
01578   switch (CheckAccess(*this, SourceLocation(), entity)) {
01579   case AR_accessible: return true;
01580   case AR_inaccessible: return false;
01581   case AR_dependent: llvm_unreachable("dependent for =delete computation");
01582   case AR_delayed: llvm_unreachable("cannot delay =delete computation");
01583   }
01584   llvm_unreachable("bad access result");
01585 }
01586 
01587 Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
01588                                                CXXDestructorDecl *Dtor,
01589                                                const PartialDiagnostic &PDiag,
01590                                                QualType ObjectTy) {
01591   if (!getLangOpts().AccessControl)
01592     return AR_accessible;
01593 
01594   // There's never a path involved when checking implicit destructor access.
01595   AccessSpecifier Access = Dtor->getAccess();
01596   if (Access == AS_public)
01597     return AR_accessible;
01598 
01599   CXXRecordDecl *NamingClass = Dtor->getParent();
01600   if (ObjectTy.isNull()) ObjectTy = Context.getTypeDeclType(NamingClass);
01601 
01602   AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
01603                       DeclAccessPair::make(Dtor, Access),
01604                       ObjectTy);
01605   Entity.setDiag(PDiag); // TODO: avoid copy
01606 
01607   return CheckAccess(*this, Loc, Entity);
01608 }
01609 
01610 /// Checks access to a constructor.
01611 Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
01612                                                 CXXConstructorDecl *Constructor,
01613                                                 const InitializedEntity &Entity,
01614                                                 AccessSpecifier Access,
01615                                                 bool IsCopyBindingRefToTemp) {
01616   if (!getLangOpts().AccessControl || Access == AS_public)
01617     return AR_accessible;
01618 
01619   PartialDiagnostic PD(PDiag());
01620   switch (Entity.getKind()) {
01621   default:
01622     PD = PDiag(IsCopyBindingRefToTemp
01623                  ? diag::ext_rvalue_to_reference_access_ctor
01624                  : diag::err_access_ctor);
01625 
01626     break;
01627 
01628   case InitializedEntity::EK_Base:
01629     PD = PDiag(diag::err_access_base_ctor);
01630     PD << Entity.isInheritedVirtualBase()
01631        << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor);
01632     break;
01633 
01634   case InitializedEntity::EK_Member: {
01635     const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
01636     PD = PDiag(diag::err_access_field_ctor);
01637     PD << Field->getType() << getSpecialMember(Constructor);
01638     break;
01639   }
01640 
01641   case InitializedEntity::EK_LambdaCapture: {
01642     StringRef VarName = Entity.getCapturedVarName();
01643     PD = PDiag(diag::err_access_lambda_capture);
01644     PD << VarName << Entity.getType() << getSpecialMember(Constructor);
01645     break;
01646   }
01647 
01648   }
01649 
01650   return CheckConstructorAccess(UseLoc, Constructor, Entity, Access, PD);
01651 }
01652 
01653 /// Checks access to a constructor.
01654 Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
01655                                                 CXXConstructorDecl *Constructor,
01656                                                 const InitializedEntity &Entity,
01657                                                 AccessSpecifier Access,
01658                                                 const PartialDiagnostic &PD) {
01659   if (!getLangOpts().AccessControl ||
01660       Access == AS_public)
01661     return AR_accessible;
01662 
01663   CXXRecordDecl *NamingClass = Constructor->getParent();
01664 
01665   // Initializing a base sub-object is an instance method call on an
01666   // object of the derived class.  Otherwise, we have an instance method
01667   // call on an object of the constructed type.
01668   CXXRecordDecl *ObjectClass;
01669   if (Entity.getKind() == InitializedEntity::EK_Base) {
01670     ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
01671   } else {
01672     ObjectClass = NamingClass;
01673   }
01674 
01675   AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass,
01676                             DeclAccessPair::make(Constructor, Access),
01677                             Context.getTypeDeclType(ObjectClass));
01678   AccessEntity.setDiag(PD);
01679 
01680   return CheckAccess(*this, UseLoc, AccessEntity);
01681 } 
01682 
01683 /// Checks access to an overloaded operator new or delete.
01684 Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
01685                                                SourceRange PlacementRange,
01686                                                CXXRecordDecl *NamingClass,
01687                                                DeclAccessPair Found,
01688                                                bool Diagnose) {
01689   if (!getLangOpts().AccessControl ||
01690       !NamingClass ||
01691       Found.getAccess() == AS_public)
01692     return AR_accessible;
01693 
01694   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
01695                       QualType());
01696   if (Diagnose)
01697     Entity.setDiag(diag::err_access)
01698       << PlacementRange;
01699 
01700   return CheckAccess(*this, OpLoc, Entity);
01701 }
01702 
01703 /// \brief Checks access to a member.
01704 Sema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc,
01705                                            CXXRecordDecl *NamingClass,
01706                                            DeclAccessPair Found) {
01707   if (!getLangOpts().AccessControl ||
01708       !NamingClass ||
01709       Found.getAccess() == AS_public)
01710     return AR_accessible;
01711 
01712   AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
01713                       Found, QualType());
01714 
01715   return CheckAccess(*this, UseLoc, Entity);
01716 }
01717 
01718 /// Checks access to an overloaded member operator, including
01719 /// conversion operators.
01720 Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
01721                                                    Expr *ObjectExpr,
01722                                                    Expr *ArgExpr,
01723                                                    DeclAccessPair Found) {
01724   if (!getLangOpts().AccessControl ||
01725       Found.getAccess() == AS_public)
01726     return AR_accessible;
01727 
01728   const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
01729   CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
01730 
01731   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
01732                       ObjectExpr->getType());
01733   Entity.setDiag(diag::err_access)
01734     << ObjectExpr->getSourceRange()
01735     << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange());
01736 
01737   return CheckAccess(*this, OpLoc, Entity);
01738 }
01739 
01740 /// Checks access to the target of a friend declaration.
01741 Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
01742   assert(isa<CXXMethodDecl>(target->getAsFunction()));
01743 
01744   // Friendship lookup is a redeclaration lookup, so there's never an
01745   // inheritance path modifying access.
01746   AccessSpecifier access = target->getAccess();
01747 
01748   if (!getLangOpts().AccessControl || access == AS_public)
01749     return AR_accessible;
01750 
01751   CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
01752   assert(method->getQualifier());
01753 
01754   AccessTarget entity(Context, AccessTarget::Member,
01755                       cast<CXXRecordDecl>(target->getDeclContext()),
01756                       DeclAccessPair::make(target, access),
01757                       /*no instance context*/ QualType());
01758   entity.setDiag(diag::err_access_friend_function)
01759     << method->getQualifierLoc().getSourceRange();
01760 
01761   // We need to bypass delayed-diagnostics because we might be called
01762   // while the ParsingDeclarator is active.
01763   EffectiveContext EC(CurContext);
01764   switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
01765   case AR_accessible: return Sema::AR_accessible;
01766   case AR_inaccessible: return Sema::AR_inaccessible;
01767   case AR_dependent: return Sema::AR_dependent;
01768   }
01769   llvm_unreachable("falling off end");
01770 }
01771 
01772 Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
01773                                                     DeclAccessPair Found) {
01774   if (!getLangOpts().AccessControl ||
01775       Found.getAccess() == AS_none ||
01776       Found.getAccess() == AS_public)
01777     return AR_accessible;
01778 
01779   OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
01780   CXXRecordDecl *NamingClass = Ovl->getNamingClass();
01781 
01782   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
01783                       /*no instance context*/ QualType());
01784   Entity.setDiag(diag::err_access)
01785     << Ovl->getSourceRange();
01786 
01787   return CheckAccess(*this, Ovl->getNameLoc(), Entity);
01788 }
01789 
01790 /// Checks access for a hierarchy conversion.
01791 ///
01792 /// \param ForceCheck true if this check should be performed even if access
01793 ///     control is disabled;  some things rely on this for semantics
01794 /// \param ForceUnprivileged true if this check should proceed as if the
01795 ///     context had no special privileges
01796 Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
01797                                               QualType Base,
01798                                               QualType Derived,
01799                                               const CXXBasePath &Path,
01800                                               unsigned DiagID,
01801                                               bool ForceCheck,
01802                                               bool ForceUnprivileged) {
01803   if (!ForceCheck && !getLangOpts().AccessControl)
01804     return AR_accessible;
01805 
01806   if (Path.Access == AS_public)
01807     return AR_accessible;
01808 
01809   CXXRecordDecl *BaseD, *DerivedD;
01810   BaseD = cast<CXXRecordDecl>(Base->getAs<RecordType>()->getDecl());
01811   DerivedD = cast<CXXRecordDecl>(Derived->getAs<RecordType>()->getDecl());
01812 
01813   AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD, 
01814                       Path.Access);
01815   if (DiagID)
01816     Entity.setDiag(DiagID) << Derived << Base;
01817 
01818   if (ForceUnprivileged) {
01819     switch (CheckEffectiveAccess(*this, EffectiveContext(),
01820                                  AccessLoc, Entity)) {
01821     case ::AR_accessible: return Sema::AR_accessible;
01822     case ::AR_inaccessible: return Sema::AR_inaccessible;
01823     case ::AR_dependent: return Sema::AR_dependent;
01824     }
01825     llvm_unreachable("unexpected result from CheckEffectiveAccess");
01826   }
01827   return CheckAccess(*this, AccessLoc, Entity);
01828 }
01829 
01830 /// Checks access to all the declarations in the given result set.
01831 void Sema::CheckLookupAccess(const LookupResult &R) {
01832   assert(getLangOpts().AccessControl
01833          && "performing access check without access control");
01834   assert(R.getNamingClass() && "performing access check without naming class");
01835 
01836   for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
01837     if (I.getAccess() != AS_public) {
01838       AccessTarget Entity(Context, AccessedEntity::Member,
01839                           R.getNamingClass(), I.getPair(),
01840                           R.getBaseObjectType());
01841       Entity.setDiag(diag::err_access);
01842       CheckAccess(*this, R.getNameLoc(), Entity);
01843     }
01844   }
01845 }
01846 
01847 /// Checks access to Decl from the given class. The check will take access
01848 /// specifiers into account, but no member access expressions and such.
01849 ///
01850 /// \param Decl the declaration to check if it can be accessed
01851 /// \param Ctx the class/context from which to start the search
01852 /// \return true if the Decl is accessible from the Class, false otherwise.
01853 bool Sema::IsSimplyAccessible(NamedDecl *Decl, DeclContext *Ctx) {
01854   if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx)) {
01855     if (!Decl->isCXXClassMember())
01856       return true;
01857 
01858     QualType qType = Class->getTypeForDecl()->getCanonicalTypeInternal();
01859     AccessTarget Entity(Context, AccessedEntity::Member, Class,
01860                         DeclAccessPair::make(Decl, Decl->getAccess()),
01861                         qType);
01862     if (Entity.getAccess() == AS_public)
01863       return true;
01864 
01865     EffectiveContext EC(CurContext);
01866     return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
01867   }
01868   
01869   if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Decl)) {
01870     // @public and @package ivars are always accessible.
01871     if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public ||
01872         Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package)
01873       return true;
01874 
01875     // If we are inside a class or category implementation, determine the
01876     // interface we're in.
01877     ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
01878     if (ObjCMethodDecl *MD = getCurMethodDecl())
01879       ClassOfMethodDecl =  MD->getClassInterface();
01880     else if (FunctionDecl *FD = getCurFunctionDecl()) {
01881       if (ObjCImplDecl *Impl 
01882             = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
01883         if (ObjCImplementationDecl *IMPD
01884               = dyn_cast<ObjCImplementationDecl>(Impl))
01885           ClassOfMethodDecl = IMPD->getClassInterface();
01886         else if (ObjCCategoryImplDecl* CatImplClass
01887                    = dyn_cast<ObjCCategoryImplDecl>(Impl))
01888           ClassOfMethodDecl = CatImplClass->getClassInterface();
01889       }
01890     }
01891     
01892     // If we're not in an interface, this ivar is inaccessible.
01893     if (!ClassOfMethodDecl)
01894       return false;
01895     
01896     // If we're inside the same interface that owns the ivar, we're fine.
01897     if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))
01898       return true;
01899     
01900     // If the ivar is private, it's inaccessible.
01901     if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private)
01902       return false;
01903     
01904     return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);
01905   }
01906   
01907   return true;
01908 }