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