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