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