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