SemaAccess.cpp revision 17015eff2b3166e445377b15913474b472775e7c
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/Sema/DelayedDiagnostic.h"
16#include "clang/Sema/Initialization.h"
17#include "clang/Sema/Lookup.h"
18#include "clang/AST/ASTContext.h"
19#include "clang/AST/CXXInheritance.h"
20#include "clang/AST/DeclCXX.h"
21#include "clang/AST/DeclFriend.h"
22#include "clang/AST/DependentDiagnostic.h"
23#include "clang/AST/ExprCXX.h"
24
25using namespace clang;
26using namespace sema;
27
28/// A copy of Sema's enum without AR_delayed.
29enum AccessResult {
30  AR_accessible,
31  AR_inaccessible,
32  AR_dependent
33};
34
35/// SetMemberAccessSpecifier - Set the access specifier of a member.
36/// Returns true on error (when the previous member decl access specifier
37/// is different from the new member decl access specifier).
38bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
39                                    NamedDecl *PrevMemberDecl,
40                                    AccessSpecifier LexicalAS) {
41  if (!PrevMemberDecl) {
42    // Use the lexical access specifier.
43    MemberDecl->setAccess(LexicalAS);
44    return false;
45  }
46
47  // C++ [class.access.spec]p3: When a member is redeclared its access
48  // specifier must be same as its initial declaration.
49  if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
50    Diag(MemberDecl->getLocation(),
51         diag::err_class_redeclared_with_different_access)
52      << MemberDecl << LexicalAS;
53    Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
54      << PrevMemberDecl << PrevMemberDecl->getAccess();
55
56    MemberDecl->setAccess(LexicalAS);
57    return true;
58  }
59
60  MemberDecl->setAccess(PrevMemberDecl->getAccess());
61  return false;
62}
63
64static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) {
65  DeclContext *DC = D->getDeclContext();
66
67  // This can only happen at top: enum decls only "publish" their
68  // immediate members.
69  if (isa<EnumDecl>(DC))
70    DC = cast<EnumDecl>(DC)->getDeclContext();
71
72  CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
73  while (DeclaringClass->isAnonymousStructOrUnion())
74    DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
75  return DeclaringClass;
76}
77
78namespace {
79struct EffectiveContext {
80  EffectiveContext() : Inner(0), Dependent(false) {}
81
82  explicit EffectiveContext(DeclContext *DC)
83    : Inner(DC),
84      Dependent(DC->isDependentContext()) {
85
86    // C++ [class.access.nest]p1:
87    //   A nested class is a member and as such has the same access
88    //   rights as any other member.
89    // C++ [class.access]p2:
90    //   A member of a class can also access all the names to which
91    //   the class has access.  A local class of a member function
92    //   may access the same names that the member function itself
93    //   may access.
94    // This almost implies that the privileges of nesting are transitive.
95    // Technically it says nothing about the local classes of non-member
96    // functions (which can gain privileges through friendship), but we
97    // take that as an oversight.
98    while (true) {
99      if (isa<CXXRecordDecl>(DC)) {
100        CXXRecordDecl *Record = cast<CXXRecordDecl>(DC)->getCanonicalDecl();
101        Records.push_back(Record);
102        DC = Record->getDeclContext();
103      } else if (isa<FunctionDecl>(DC)) {
104        FunctionDecl *Function = cast<FunctionDecl>(DC)->getCanonicalDecl();
105        Functions.push_back(Function);
106
107        if (Function->getFriendObjectKind())
108          DC = Function->getLexicalDeclContext();
109        else
110          DC = Function->getDeclContext();
111      } else if (DC->isFileContext()) {
112        break;
113      } else {
114        DC = DC->getParent();
115      }
116    }
117  }
118
119  bool isDependent() const { return Dependent; }
120
121  bool includesClass(const CXXRecordDecl *R) const {
122    R = R->getCanonicalDecl();
123    return std::find(Records.begin(), Records.end(), R)
124             != Records.end();
125  }
126
127  /// Retrieves the innermost "useful" context.  Can be null if we're
128  /// doing access-control without privileges.
129  DeclContext *getInnerContext() const {
130    return Inner;
131  }
132
133  typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
134
135  DeclContext *Inner;
136  SmallVector<FunctionDecl*, 4> Functions;
137  SmallVector<CXXRecordDecl*, 4> Records;
138  bool Dependent;
139};
140
141/// Like sema::AccessedEntity, but kindly lets us scribble all over
142/// it.
143struct AccessTarget : public AccessedEntity {
144  AccessTarget(const AccessedEntity &Entity)
145    : AccessedEntity(Entity) {
146    initialize();
147  }
148
149  AccessTarget(ASTContext &Context,
150               MemberNonce _,
151               CXXRecordDecl *NamingClass,
152               DeclAccessPair FoundDecl,
153               QualType BaseObjectType)
154    : AccessedEntity(Context, Member, NamingClass, FoundDecl, BaseObjectType) {
155    initialize();
156  }
157
158  AccessTarget(ASTContext &Context,
159               BaseNonce _,
160               CXXRecordDecl *BaseClass,
161               CXXRecordDecl *DerivedClass,
162               AccessSpecifier Access)
163    : AccessedEntity(Context, Base, BaseClass, DerivedClass, Access) {
164    initialize();
165  }
166
167  bool hasInstanceContext() const {
168    return HasInstanceContext;
169  }
170
171  class SavedInstanceContext {
172  public:
173    ~SavedInstanceContext() {
174      Target.HasInstanceContext = Has;
175    }
176
177  private:
178    friend struct AccessTarget;
179    explicit SavedInstanceContext(AccessTarget &Target)
180      : Target(Target), Has(Target.HasInstanceContext) {}
181    AccessTarget &Target;
182    bool Has;
183  };
184
185  SavedInstanceContext saveInstanceContext() {
186    return SavedInstanceContext(*this);
187  }
188
189  void suppressInstanceContext() {
190    HasInstanceContext = false;
191  }
192
193  const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
194    assert(HasInstanceContext);
195    if (CalculatedInstanceContext)
196      return InstanceContext;
197
198    CalculatedInstanceContext = true;
199    DeclContext *IC = S.computeDeclContext(getBaseObjectType());
200    InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl() : 0);
201    return InstanceContext;
202  }
203
204  const CXXRecordDecl *getDeclaringClass() const {
205    return DeclaringClass;
206  }
207
208private:
209  void initialize() {
210    HasInstanceContext = (isMemberAccess() &&
211                          !getBaseObjectType().isNull() &&
212                          getTargetDecl()->isCXXInstanceMember());
213    CalculatedInstanceContext = false;
214    InstanceContext = 0;
215
216    if (isMemberAccess())
217      DeclaringClass = FindDeclaringClass(getTargetDecl());
218    else
219      DeclaringClass = getBaseClass();
220    DeclaringClass = DeclaringClass->getCanonicalDecl();
221  }
222
223  bool HasInstanceContext : 1;
224  mutable bool CalculatedInstanceContext : 1;
225  mutable const CXXRecordDecl *InstanceContext;
226  const CXXRecordDecl *DeclaringClass;
227};
228
229}
230
231/// Checks whether one class might instantiate to the other.
232static bool MightInstantiateTo(const CXXRecordDecl *From,
233                               const CXXRecordDecl *To) {
234  // Declaration names are always preserved by instantiation.
235  if (From->getDeclName() != To->getDeclName())
236    return false;
237
238  const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
239  const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
240  if (FromDC == ToDC) return true;
241  if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
242
243  // Be conservative.
244  return true;
245}
246
247/// Checks whether one class is derived from another, inclusively.
248/// Properly indicates when it couldn't be determined due to
249/// dependence.
250///
251/// This should probably be donated to AST or at least Sema.
252static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived,
253                                           const CXXRecordDecl *Target) {
254  assert(Derived->getCanonicalDecl() == Derived);
255  assert(Target->getCanonicalDecl() == Target);
256
257  if (Derived == Target) return AR_accessible;
258
259  bool CheckDependent = Derived->isDependentContext();
260  if (CheckDependent && MightInstantiateTo(Derived, Target))
261    return AR_dependent;
262
263  AccessResult OnFailure = AR_inaccessible;
264  SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
265
266  while (true) {
267    for (CXXRecordDecl::base_class_const_iterator
268           I = Derived->bases_begin(), E = Derived->bases_end(); I != E; ++I) {
269
270      const CXXRecordDecl *RD;
271
272      QualType T = I->getType();
273      if (const RecordType *RT = T->getAs<RecordType>()) {
274        RD = cast<CXXRecordDecl>(RT->getDecl());
275      } else if (const InjectedClassNameType *IT
276                   = T->getAs<InjectedClassNameType>()) {
277        RD = IT->getDecl();
278      } else {
279        assert(T->isDependentType() && "non-dependent base wasn't a record?");
280        OnFailure = AR_dependent;
281        continue;
282      }
283
284      RD = RD->getCanonicalDecl();
285      if (RD == Target) return AR_accessible;
286      if (CheckDependent && MightInstantiateTo(RD, Target))
287        OnFailure = AR_dependent;
288
289      Queue.push_back(RD);
290    }
291
292    if (Queue.empty()) break;
293
294    Derived = Queue.back();
295    Queue.pop_back();
296  }
297
298  return OnFailure;
299}
300
301
302static bool MightInstantiateTo(Sema &S, DeclContext *Context,
303                               DeclContext *Friend) {
304  if (Friend == Context)
305    return true;
306
307  assert(!Friend->isDependentContext() &&
308         "can't handle friends with dependent contexts here");
309
310  if (!Context->isDependentContext())
311    return false;
312
313  if (Friend->isFileContext())
314    return false;
315
316  // TODO: this is very conservative
317  return true;
318}
319
320// Asks whether the type in 'context' can ever instantiate to the type
321// in 'friend'.
322static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) {
323  if (Friend == Context)
324    return true;
325
326  if (!Friend->isDependentType() && !Context->isDependentType())
327    return false;
328
329  // TODO: this is very conservative.
330  return true;
331}
332
333static bool MightInstantiateTo(Sema &S,
334                               FunctionDecl *Context,
335                               FunctionDecl *Friend) {
336  if (Context->getDeclName() != Friend->getDeclName())
337    return false;
338
339  if (!MightInstantiateTo(S,
340                          Context->getDeclContext(),
341                          Friend->getDeclContext()))
342    return false;
343
344  CanQual<FunctionProtoType> FriendTy
345    = S.Context.getCanonicalType(Friend->getType())
346         ->getAs<FunctionProtoType>();
347  CanQual<FunctionProtoType> ContextTy
348    = S.Context.getCanonicalType(Context->getType())
349         ->getAs<FunctionProtoType>();
350
351  // There isn't any way that I know of to add qualifiers
352  // during instantiation.
353  if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
354    return false;
355
356  if (FriendTy->getNumArgs() != ContextTy->getNumArgs())
357    return false;
358
359  if (!MightInstantiateTo(S,
360                          ContextTy->getResultType(),
361                          FriendTy->getResultType()))
362    return false;
363
364  for (unsigned I = 0, E = FriendTy->getNumArgs(); I != E; ++I)
365    if (!MightInstantiateTo(S,
366                            ContextTy->getArgType(I),
367                            FriendTy->getArgType(I)))
368      return false;
369
370  return true;
371}
372
373static bool MightInstantiateTo(Sema &S,
374                               FunctionTemplateDecl *Context,
375                               FunctionTemplateDecl *Friend) {
376  return MightInstantiateTo(S,
377                            Context->getTemplatedDecl(),
378                            Friend->getTemplatedDecl());
379}
380
381static AccessResult MatchesFriend(Sema &S,
382                                  const EffectiveContext &EC,
383                                  const CXXRecordDecl *Friend) {
384  if (EC.includesClass(Friend))
385    return AR_accessible;
386
387  if (EC.isDependent()) {
388    CanQualType FriendTy
389      = S.Context.getCanonicalType(S.Context.getTypeDeclType(Friend));
390
391    for (EffectiveContext::record_iterator
392           I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
393      CanQualType ContextTy
394        = S.Context.getCanonicalType(S.Context.getTypeDeclType(*I));
395      if (MightInstantiateTo(S, ContextTy, FriendTy))
396        return AR_dependent;
397    }
398  }
399
400  return AR_inaccessible;
401}
402
403static AccessResult MatchesFriend(Sema &S,
404                                  const EffectiveContext &EC,
405                                  CanQualType Friend) {
406  if (const RecordType *RT = Friend->getAs<RecordType>())
407    return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
408
409  // TODO: we can do better than this
410  if (Friend->isDependentType())
411    return AR_dependent;
412
413  return AR_inaccessible;
414}
415
416/// Determines whether the given friend class template matches
417/// anything in the effective context.
418static AccessResult MatchesFriend(Sema &S,
419                                  const EffectiveContext &EC,
420                                  ClassTemplateDecl *Friend) {
421  AccessResult OnFailure = AR_inaccessible;
422
423  // Check whether the friend is the template of a class in the
424  // context chain.
425  for (SmallVectorImpl<CXXRecordDecl*>::const_iterator
426         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
427    CXXRecordDecl *Record = *I;
428
429    // Figure out whether the current class has a template:
430    ClassTemplateDecl *CTD;
431
432    // A specialization of the template...
433    if (isa<ClassTemplateSpecializationDecl>(Record)) {
434      CTD = cast<ClassTemplateSpecializationDecl>(Record)
435        ->getSpecializedTemplate();
436
437    // ... or the template pattern itself.
438    } else {
439      CTD = Record->getDescribedClassTemplate();
440      if (!CTD) continue;
441    }
442
443    // It's a match.
444    if (Friend == CTD->getCanonicalDecl())
445      return AR_accessible;
446
447    // If the context isn't dependent, it can't be a dependent match.
448    if (!EC.isDependent())
449      continue;
450
451    // If the template names don't match, it can't be a dependent
452    // match.
453    if (CTD->getDeclName() != Friend->getDeclName())
454      continue;
455
456    // If the class's context can't instantiate to the friend's
457    // context, it can't be a dependent match.
458    if (!MightInstantiateTo(S, CTD->getDeclContext(),
459                            Friend->getDeclContext()))
460      continue;
461
462    // Otherwise, it's a dependent match.
463    OnFailure = AR_dependent;
464  }
465
466  return OnFailure;
467}
468
469/// Determines whether the given friend function matches anything in
470/// the effective context.
471static AccessResult MatchesFriend(Sema &S,
472                                  const EffectiveContext &EC,
473                                  FunctionDecl *Friend) {
474  AccessResult OnFailure = AR_inaccessible;
475
476  for (SmallVectorImpl<FunctionDecl*>::const_iterator
477         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
478    if (Friend == *I)
479      return AR_accessible;
480
481    if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
482      OnFailure = AR_dependent;
483  }
484
485  return OnFailure;
486}
487
488/// Determines whether the given friend function template matches
489/// anything in the effective context.
490static AccessResult MatchesFriend(Sema &S,
491                                  const EffectiveContext &EC,
492                                  FunctionTemplateDecl *Friend) {
493  if (EC.Functions.empty()) return AR_inaccessible;
494
495  AccessResult OnFailure = AR_inaccessible;
496
497  for (SmallVectorImpl<FunctionDecl*>::const_iterator
498         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
499
500    FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
501    if (!FTD)
502      FTD = (*I)->getDescribedFunctionTemplate();
503    if (!FTD)
504      continue;
505
506    FTD = FTD->getCanonicalDecl();
507
508    if (Friend == FTD)
509      return AR_accessible;
510
511    if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
512      OnFailure = AR_dependent;
513  }
514
515  return OnFailure;
516}
517
518/// Determines whether the given friend declaration matches anything
519/// in the effective context.
520static AccessResult MatchesFriend(Sema &S,
521                                  const EffectiveContext &EC,
522                                  FriendDecl *FriendD) {
523  // Whitelist accesses if there's an invalid or unsupported friend
524  // declaration.
525  if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend())
526    return AR_accessible;
527
528  if (TypeSourceInfo *T = FriendD->getFriendType())
529    return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
530
531  NamedDecl *Friend
532    = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
533
534  // FIXME: declarations with dependent or templated scope.
535
536  if (isa<ClassTemplateDecl>(Friend))
537    return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
538
539  if (isa<FunctionTemplateDecl>(Friend))
540    return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
541
542  if (isa<CXXRecordDecl>(Friend))
543    return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
544
545  assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
546  return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
547}
548
549static AccessResult GetFriendKind(Sema &S,
550                                  const EffectiveContext &EC,
551                                  const CXXRecordDecl *Class) {
552  AccessResult OnFailure = AR_inaccessible;
553
554  // Okay, check friends.
555  for (CXXRecordDecl::friend_iterator I = Class->friend_begin(),
556         E = Class->friend_end(); I != E; ++I) {
557    FriendDecl *Friend = *I;
558
559    switch (MatchesFriend(S, EC, Friend)) {
560    case AR_accessible:
561      return AR_accessible;
562
563    case AR_inaccessible:
564      continue;
565
566    case AR_dependent:
567      OnFailure = AR_dependent;
568      break;
569    }
570  }
571
572  // That's it, give up.
573  return OnFailure;
574}
575
576namespace {
577
578/// A helper class for checking for a friend which will grant access
579/// to a protected instance member.
580struct ProtectedFriendContext {
581  Sema &S;
582  const EffectiveContext &EC;
583  const CXXRecordDecl *NamingClass;
584  bool CheckDependent;
585  bool EverDependent;
586
587  /// The path down to the current base class.
588  SmallVector<const CXXRecordDecl*, 20> CurPath;
589
590  ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
591                         const CXXRecordDecl *InstanceContext,
592                         const CXXRecordDecl *NamingClass)
593    : S(S), EC(EC), NamingClass(NamingClass),
594      CheckDependent(InstanceContext->isDependentContext() ||
595                     NamingClass->isDependentContext()),
596      EverDependent(false) {}
597
598  /// Check classes in the current path for friendship, starting at
599  /// the given index.
600  bool checkFriendshipAlongPath(unsigned I) {
601    assert(I < CurPath.size());
602    for (unsigned E = CurPath.size(); I != E; ++I) {
603      switch (GetFriendKind(S, EC, CurPath[I])) {
604      case AR_accessible:   return true;
605      case AR_inaccessible: continue;
606      case AR_dependent:    EverDependent = true; continue;
607      }
608    }
609    return false;
610  }
611
612  /// Perform a search starting at the given class.
613  ///
614  /// PrivateDepth is the index of the last (least derived) class
615  /// along the current path such that a notional public member of
616  /// the final class in the path would have access in that class.
617  bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
618    // If we ever reach the naming class, check the current path for
619    // friendship.  We can also stop recursing because we obviously
620    // won't find the naming class there again.
621    if (Cur == NamingClass)
622      return checkFriendshipAlongPath(PrivateDepth);
623
624    if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
625      EverDependent = true;
626
627    // Recurse into the base classes.
628    for (CXXRecordDecl::base_class_const_iterator
629           I = Cur->bases_begin(), E = Cur->bases_end(); I != E; ++I) {
630
631      // If this is private inheritance, then a public member of the
632      // base will not have any access in classes derived from Cur.
633      unsigned BasePrivateDepth = PrivateDepth;
634      if (I->getAccessSpecifier() == AS_private)
635        BasePrivateDepth = CurPath.size() - 1;
636
637      const CXXRecordDecl *RD;
638
639      QualType T = I->getType();
640      if (const RecordType *RT = T->getAs<RecordType>()) {
641        RD = cast<CXXRecordDecl>(RT->getDecl());
642      } else if (const InjectedClassNameType *IT
643                   = T->getAs<InjectedClassNameType>()) {
644        RD = IT->getDecl();
645      } else {
646        assert(T->isDependentType() && "non-dependent base wasn't a record?");
647        EverDependent = true;
648        continue;
649      }
650
651      // Recurse.  We don't need to clean up if this returns true.
652      CurPath.push_back(RD);
653      if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
654        return true;
655      CurPath.pop_back();
656    }
657
658    return false;
659  }
660
661  bool findFriendship(const CXXRecordDecl *Cur) {
662    assert(CurPath.empty());
663    CurPath.push_back(Cur);
664    return findFriendship(Cur, 0);
665  }
666};
667}
668
669/// Search for a class P that EC is a friend of, under the constraint
670///   InstanceContext <= P <= NamingClass
671/// and with the additional restriction that a protected member of
672/// NamingClass would have some natural access in P.
673///
674/// That second condition isn't actually quite right: the condition in
675/// the standard is whether the target would have some natural access
676/// in P.  The difference is that the target might be more accessible
677/// along some path not passing through NamingClass.  Allowing that
678/// introduces two problems:
679///   - It breaks encapsulation because you can suddenly access a
680///     forbidden base class's members by subclassing it elsewhere.
681///   - It makes access substantially harder to compute because it
682///     breaks the hill-climbing algorithm: knowing that the target is
683///     accessible in some base class would no longer let you change
684///     the question solely to whether the base class is accessible,
685///     because the original target might have been more accessible
686///     because of crazy subclassing.
687/// So we don't implement that.
688static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
689                                           const CXXRecordDecl *InstanceContext,
690                                           const CXXRecordDecl *NamingClass) {
691  assert(InstanceContext->getCanonicalDecl() == InstanceContext);
692  assert(NamingClass->getCanonicalDecl() == NamingClass);
693
694  ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
695  if (PRC.findFriendship(InstanceContext)) return AR_accessible;
696  if (PRC.EverDependent) return AR_dependent;
697  return AR_inaccessible;
698}
699
700static AccessResult HasAccess(Sema &S,
701                              const EffectiveContext &EC,
702                              const CXXRecordDecl *NamingClass,
703                              AccessSpecifier Access,
704                              const AccessTarget &Target) {
705  assert(NamingClass->getCanonicalDecl() == NamingClass &&
706         "declaration should be canonicalized before being passed here");
707
708  if (Access == AS_public) return AR_accessible;
709  assert(Access == AS_private || Access == AS_protected);
710
711  AccessResult OnFailure = AR_inaccessible;
712
713  for (EffectiveContext::record_iterator
714         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
715    // All the declarations in EC have been canonicalized, so pointer
716    // equality from this point on will work fine.
717    const CXXRecordDecl *ECRecord = *I;
718
719    // [B2] and [M2]
720    if (Access == AS_private) {
721      if (ECRecord == NamingClass)
722        return AR_accessible;
723
724      if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
725        OnFailure = AR_dependent;
726
727    // [B3] and [M3]
728    } else {
729      assert(Access == AS_protected);
730      switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
731      case AR_accessible: break;
732      case AR_inaccessible: continue;
733      case AR_dependent: OnFailure = AR_dependent; continue;
734      }
735
736      if (!Target.hasInstanceContext())
737        return AR_accessible;
738
739      const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
740      if (!InstanceContext) {
741        OnFailure = AR_dependent;
742        continue;
743      }
744
745      // C++ [class.protected]p1:
746      //   An additional access check beyond those described earlier in
747      //   [class.access] is applied when a non-static data member or
748      //   non-static member function is a protected member of its naming
749      //   class.  As described earlier, access to a protected member is
750      //   granted because the reference occurs in a friend or member of
751      //   some class C.  If the access is to form a pointer to member,
752      //   the nested-name-specifier shall name C or a class derived from
753      //   C. All other accesses involve a (possibly implicit) object
754      //   expression. In this case, the class of the object expression
755      //   shall be C or a class derived from C.
756      //
757      // We interpret this as a restriction on [M3].  Most of the
758      // conditions are encoded by not having any instance context.
759      switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
760      case AR_accessible: return AR_accessible;
761      case AR_inaccessible: continue;
762      case AR_dependent: OnFailure = AR_dependent; continue;
763      }
764    }
765  }
766
767  // [M3] and [B3] say that, if the target is protected in N, we grant
768  // access if the access occurs in a friend or member of some class P
769  // that's a subclass of N and where the target has some natural
770  // access in P.  The 'member' aspect is easy to handle because P
771  // would necessarily be one of the effective-context records, and we
772  // address that above.  The 'friend' aspect is completely ridiculous
773  // to implement because there are no restrictions at all on P
774  // *unless* the [class.protected] restriction applies.  If it does,
775  // however, we should ignore whether the naming class is a friend,
776  // and instead rely on whether any potential P is a friend.
777  if (Access == AS_protected && Target.hasInstanceContext()) {
778    const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
779    if (!InstanceContext) return AR_dependent;
780    switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
781    case AR_accessible: return AR_accessible;
782    case AR_inaccessible: return OnFailure;
783    case AR_dependent: return AR_dependent;
784    }
785    llvm_unreachable("impossible friendship kind");
786  }
787
788  switch (GetFriendKind(S, EC, NamingClass)) {
789  case AR_accessible: return AR_accessible;
790  case AR_inaccessible: return OnFailure;
791  case AR_dependent: return AR_dependent;
792  }
793
794  // Silence bogus warnings
795  llvm_unreachable("impossible friendship kind");
796  return OnFailure;
797}
798
799/// Finds the best path from the naming class to the declaring class,
800/// taking friend declarations into account.
801///
802/// C++0x [class.access.base]p5:
803///   A member m is accessible at the point R when named in class N if
804///   [M1] m as a member of N is public, or
805///   [M2] m as a member of N is private, and R occurs in a member or
806///        friend of class N, or
807///   [M3] m as a member of N is protected, and R occurs in a member or
808///        friend of class N, or in a member or friend of a class P
809///        derived from N, where m as a member of P is public, private,
810///        or protected, or
811///   [M4] there exists a base class B of N that is accessible at R, and
812///        m is accessible at R when named in class B.
813///
814/// C++0x [class.access.base]p4:
815///   A base class B of N is accessible at R, if
816///   [B1] an invented public member of B would be a public member of N, or
817///   [B2] R occurs in a member or friend of class N, and an invented public
818///        member of B would be a private or protected member of N, or
819///   [B3] R occurs in a member or friend of a class P derived from N, and an
820///        invented public member of B would be a private or protected member
821///        of P, or
822///   [B4] there exists a class S such that B is a base class of S accessible
823///        at R and S is a base class of N accessible at R.
824///
825/// Along a single inheritance path we can restate both of these
826/// iteratively:
827///
828/// First, we note that M1-4 are equivalent to B1-4 if the member is
829/// treated as a notional base of its declaring class with inheritance
830/// access equivalent to the member's access.  Therefore we need only
831/// ask whether a class B is accessible from a class N in context R.
832///
833/// Let B_1 .. B_n be the inheritance path in question (i.e. where
834/// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
835/// B_i).  For i in 1..n, we will calculate ACAB(i), the access to the
836/// closest accessible base in the path:
837///   Access(a, b) = (* access on the base specifier from a to b *)
838///   Merge(a, forbidden) = forbidden
839///   Merge(a, private) = forbidden
840///   Merge(a, b) = min(a,b)
841///   Accessible(c, forbidden) = false
842///   Accessible(c, private) = (R is c) || IsFriend(c, R)
843///   Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
844///   Accessible(c, public) = true
845///   ACAB(n) = public
846///   ACAB(i) =
847///     let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
848///     if Accessible(B_i, AccessToBase) then public else AccessToBase
849///
850/// B is an accessible base of N at R iff ACAB(1) = public.
851///
852/// \param FinalAccess the access of the "final step", or AS_public if
853///   there is no final step.
854/// \return null if friendship is dependent
855static CXXBasePath *FindBestPath(Sema &S,
856                                 const EffectiveContext &EC,
857                                 AccessTarget &Target,
858                                 AccessSpecifier FinalAccess,
859                                 CXXBasePaths &Paths) {
860  // Derive the paths to the desired base.
861  const CXXRecordDecl *Derived = Target.getNamingClass();
862  const CXXRecordDecl *Base = Target.getDeclaringClass();
863
864  // FIXME: fail correctly when there are dependent paths.
865  bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
866                                          Paths);
867  assert(isDerived && "derived class not actually derived from base");
868  (void) isDerived;
869
870  CXXBasePath *BestPath = 0;
871
872  assert(FinalAccess != AS_none && "forbidden access after declaring class");
873
874  bool AnyDependent = false;
875
876  // Derive the friend-modified access along each path.
877  for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
878         PI != PE; ++PI) {
879    AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
880
881    // Walk through the path backwards.
882    AccessSpecifier PathAccess = FinalAccess;
883    CXXBasePath::iterator I = PI->end(), E = PI->begin();
884    while (I != E) {
885      --I;
886
887      assert(PathAccess != AS_none);
888
889      // If the declaration is a private member of a base class, there
890      // is no level of friendship in derived classes that can make it
891      // accessible.
892      if (PathAccess == AS_private) {
893        PathAccess = AS_none;
894        break;
895      }
896
897      const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
898
899      AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
900      PathAccess = std::max(PathAccess, BaseAccess);
901
902      switch (HasAccess(S, EC, NC, PathAccess, Target)) {
903      case AR_inaccessible: break;
904      case AR_accessible:
905        PathAccess = AS_public;
906
907        // Future tests are not against members and so do not have
908        // instance context.
909        Target.suppressInstanceContext();
910        break;
911      case AR_dependent:
912        AnyDependent = true;
913        goto Next;
914      }
915    }
916
917    // Note that we modify the path's Access field to the
918    // friend-modified access.
919    if (BestPath == 0 || PathAccess < BestPath->Access) {
920      BestPath = &*PI;
921      BestPath->Access = PathAccess;
922
923      // Short-circuit if we found a public path.
924      if (BestPath->Access == AS_public)
925        return BestPath;
926    }
927
928  Next: ;
929  }
930
931  assert((!BestPath || BestPath->Access != AS_public) &&
932         "fell out of loop with public path");
933
934  // We didn't find a public path, but at least one path was subject
935  // to dependent friendship, so delay the check.
936  if (AnyDependent)
937    return 0;
938
939  return BestPath;
940}
941
942/// Given that an entity has protected natural access, check whether
943/// access might be denied because of the protected member access
944/// restriction.
945///
946/// \return true if a note was emitted
947static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
948                                       AccessTarget &Target) {
949  // Only applies to instance accesses.
950  if (!Target.hasInstanceContext())
951    return false;
952  assert(Target.isMemberAccess());
953  NamedDecl *D = Target.getTargetDecl();
954
955  const CXXRecordDecl *DeclaringClass = Target.getDeclaringClass();
956  DeclaringClass = DeclaringClass->getCanonicalDecl();
957
958  for (EffectiveContext::record_iterator
959         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
960    const CXXRecordDecl *ECRecord = *I;
961    switch (IsDerivedFromInclusive(ECRecord, DeclaringClass)) {
962    case AR_accessible: break;
963    case AR_inaccessible: continue;
964    case AR_dependent: continue;
965    }
966
967    // The effective context is a subclass of the declaring class.
968    // If that class isn't a superclass of the instance context,
969    // then the [class.protected] restriction applies.
970
971    // To get this exactly right, this might need to be checked more
972    // holistically;  it's not necessarily the case that gaining
973    // access here would grant us access overall.
974
975    const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
976    assert(InstanceContext && "diagnosing dependent access");
977
978    switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
979    case AR_accessible: continue;
980    case AR_dependent: continue;
981    case AR_inaccessible:
982      S.Diag(D->getLocation(), diag::note_access_protected_restricted)
983        << (InstanceContext != Target.getNamingClass()->getCanonicalDecl())
984        << S.Context.getTypeDeclType(InstanceContext)
985        << S.Context.getTypeDeclType(ECRecord);
986      return true;
987    }
988  }
989
990  return false;
991}
992
993/// Diagnose the path which caused the given declaration or base class
994/// to become inaccessible.
995static void DiagnoseAccessPath(Sema &S,
996                               const EffectiveContext &EC,
997                               AccessTarget &Entity) {
998  AccessSpecifier Access = Entity.getAccess();
999  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
1000  NamingClass = NamingClass->getCanonicalDecl();
1001
1002  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);
1003  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1004
1005  // Easy case: the decl's natural access determined its path access.
1006  // We have to check against AS_private here in case Access is AS_none,
1007  // indicating a non-public member of a private base class.
1008  if (D && (Access == D->getAccess() || D->getAccess() == AS_private)) {
1009    switch (HasAccess(S, EC, DeclaringClass, D->getAccess(), Entity)) {
1010    case AR_inaccessible: {
1011      if (Access == AS_protected &&
1012          TryDiagnoseProtectedAccess(S, EC, Entity))
1013        return;
1014
1015      // Find an original declaration.
1016      while (D->isOutOfLine()) {
1017        NamedDecl *PrevDecl = 0;
1018        if (VarDecl *VD = dyn_cast<VarDecl>(D))
1019          PrevDecl = VD->getPreviousDeclaration();
1020        else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1021          PrevDecl = FD->getPreviousDeclaration();
1022        else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
1023          PrevDecl = TND->getPreviousDeclaration();
1024        else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
1025          if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1026            break;
1027          PrevDecl = TD->getPreviousDeclaration();
1028        }
1029        if (!PrevDecl) break;
1030        D = PrevDecl;
1031      }
1032
1033      CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
1034      Decl *ImmediateChild;
1035      if (D->getDeclContext() == DeclaringClass)
1036        ImmediateChild = D;
1037      else {
1038        DeclContext *DC = D->getDeclContext();
1039        while (DC->getParent() != DeclaringClass)
1040          DC = DC->getParent();
1041        ImmediateChild = cast<Decl>(DC);
1042      }
1043
1044      // Check whether there's an AccessSpecDecl preceding this in the
1045      // chain of the DeclContext.
1046      bool Implicit = true;
1047      for (CXXRecordDecl::decl_iterator
1048             I = DeclaringClass->decls_begin(), E = DeclaringClass->decls_end();
1049           I != E; ++I) {
1050        if (*I == ImmediateChild) break;
1051        if (isa<AccessSpecDecl>(*I)) {
1052          Implicit = false;
1053          break;
1054        }
1055      }
1056
1057      S.Diag(D->getLocation(), diag::note_access_natural)
1058        << (unsigned) (Access == AS_protected)
1059        << Implicit;
1060      return;
1061    }
1062
1063    case AR_accessible: break;
1064
1065    case AR_dependent:
1066      llvm_unreachable("can't diagnose dependent access failures");
1067      return;
1068    }
1069  }
1070
1071  CXXBasePaths Paths;
1072  CXXBasePath &Path = *FindBestPath(S, EC, Entity, AS_public, Paths);
1073
1074  CXXBasePath::iterator I = Path.end(), E = Path.begin();
1075  while (I != E) {
1076    --I;
1077
1078    const CXXBaseSpecifier *BS = I->Base;
1079    AccessSpecifier BaseAccess = BS->getAccessSpecifier();
1080
1081    // If this is public inheritance, or the derived class is a friend,
1082    // skip this step.
1083    if (BaseAccess == AS_public)
1084      continue;
1085
1086    switch (GetFriendKind(S, EC, I->Class)) {
1087    case AR_accessible: continue;
1088    case AR_inaccessible: break;
1089    case AR_dependent:
1090      llvm_unreachable("can't diagnose dependent access failures");
1091    }
1092
1093    // Check whether this base specifier is the tighest point
1094    // constraining access.  We have to check against AS_private for
1095    // the same reasons as above.
1096    if (BaseAccess == AS_private || BaseAccess >= Access) {
1097
1098      // We're constrained by inheritance, but we want to say
1099      // "declared private here" if we're diagnosing a hierarchy
1100      // conversion and this is the final step.
1101      unsigned diagnostic;
1102      if (D) diagnostic = diag::note_access_constrained_by_path;
1103      else if (I + 1 == Path.end()) diagnostic = diag::note_access_natural;
1104      else diagnostic = diag::note_access_constrained_by_path;
1105
1106      S.Diag(BS->getSourceRange().getBegin(), diagnostic)
1107        << BS->getSourceRange()
1108        << (BaseAccess == AS_protected)
1109        << (BS->getAccessSpecifierAsWritten() == AS_none);
1110
1111      if (D)
1112        S.Diag(D->getLocation(), diag::note_field_decl);
1113
1114      return;
1115    }
1116  }
1117
1118  llvm_unreachable("access not apparently constrained by path");
1119}
1120
1121static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
1122                              const EffectiveContext &EC,
1123                              AccessTarget &Entity) {
1124  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
1125  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1126  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);
1127
1128  S.Diag(Loc, Entity.getDiag())
1129    << (Entity.getAccess() == AS_protected)
1130    << (D ? D->getDeclName() : DeclarationName())
1131    << S.Context.getTypeDeclType(NamingClass)
1132    << S.Context.getTypeDeclType(DeclaringClass);
1133  DiagnoseAccessPath(S, EC, Entity);
1134}
1135
1136/// MSVC has a bug where if during an using declaration name lookup,
1137/// the declaration found is unaccessible (private) and that declaration
1138/// was bring into scope via another using declaration whose target
1139/// declaration is accessible (public) then no error is generated.
1140/// Example:
1141///   class A {
1142///   public:
1143///     int f();
1144///   };
1145///   class B : public A {
1146///   private:
1147///     using A::f;
1148///   };
1149///   class C : public B {
1150///   private:
1151///     using B::f;
1152///   };
1153///
1154/// Here, B::f is private so this should fail in Standard C++, but
1155/// because B::f refers to A::f which is public MSVC accepts it.
1156static bool IsMicrosoftUsingDeclarationAccessBug(Sema& S,
1157                                                 SourceLocation AccessLoc,
1158                                                 AccessTarget &Entity) {
1159  if (UsingShadowDecl *Shadow =
1160                         dyn_cast<UsingShadowDecl>(Entity.getTargetDecl())) {
1161    const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1162    if (Entity.getTargetDecl()->getAccess() == AS_private &&
1163        (OrigDecl->getAccess() == AS_public ||
1164         OrigDecl->getAccess() == AS_protected)) {
1165      S.Diag(AccessLoc, diag::war_ms_using_declaration_inaccessible)
1166        << Shadow->getUsingDecl()->getQualifiedNameAsString()
1167        << OrigDecl->getQualifiedNameAsString();
1168      return true;
1169    }
1170  }
1171  return false;
1172}
1173
1174/// Determines whether the accessed entity is accessible.  Public members
1175/// have been weeded out by this point.
1176static AccessResult IsAccessible(Sema &S,
1177                                 const EffectiveContext &EC,
1178                                 AccessTarget &Entity) {
1179  // Determine the actual naming class.
1180  CXXRecordDecl *NamingClass = Entity.getNamingClass();
1181  while (NamingClass->isAnonymousStructOrUnion())
1182    NamingClass = cast<CXXRecordDecl>(NamingClass->getParent());
1183  NamingClass = NamingClass->getCanonicalDecl();
1184
1185  AccessSpecifier UnprivilegedAccess = Entity.getAccess();
1186  assert(UnprivilegedAccess != AS_public && "public access not weeded out");
1187
1188  // Before we try to recalculate access paths, try to white-list
1189  // accesses which just trade in on the final step, i.e. accesses
1190  // which don't require [M4] or [B4]. These are by far the most
1191  // common forms of privileged access.
1192  if (UnprivilegedAccess != AS_none) {
1193    switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1194    case AR_dependent:
1195      // This is actually an interesting policy decision.  We don't
1196      // *have* to delay immediately here: we can do the full access
1197      // calculation in the hope that friendship on some intermediate
1198      // class will make the declaration accessible non-dependently.
1199      // But that's not cheap, and odds are very good (note: assertion
1200      // made without data) that the friend declaration will determine
1201      // access.
1202      return AR_dependent;
1203
1204    case AR_accessible: return AR_accessible;
1205    case AR_inaccessible: break;
1206    }
1207  }
1208
1209  AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1210
1211  // We lower member accesses to base accesses by pretending that the
1212  // member is a base class of its declaring class.
1213  AccessSpecifier FinalAccess;
1214
1215  if (Entity.isMemberAccess()) {
1216    // Determine if the declaration is accessible from EC when named
1217    // in its declaring class.
1218    NamedDecl *Target = Entity.getTargetDecl();
1219    const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1220
1221    FinalAccess = Target->getAccess();
1222    switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1223    case AR_accessible:
1224      FinalAccess = AS_public;
1225      break;
1226    case AR_inaccessible: break;
1227    case AR_dependent: return AR_dependent; // see above
1228    }
1229
1230    if (DeclaringClass == NamingClass)
1231      return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
1232
1233    Entity.suppressInstanceContext();
1234  } else {
1235    FinalAccess = AS_public;
1236  }
1237
1238  assert(Entity.getDeclaringClass() != NamingClass);
1239
1240  // Append the declaration's access if applicable.
1241  CXXBasePaths Paths;
1242  CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
1243  if (!Path)
1244    return AR_dependent;
1245
1246  assert(Path->Access <= UnprivilegedAccess &&
1247         "access along best path worse than direct?");
1248  if (Path->Access == AS_public)
1249    return AR_accessible;
1250  return AR_inaccessible;
1251}
1252
1253static void DelayDependentAccess(Sema &S,
1254                                 const EffectiveContext &EC,
1255                                 SourceLocation Loc,
1256                                 const AccessTarget &Entity) {
1257  assert(EC.isDependent() && "delaying non-dependent access");
1258  DeclContext *DC = EC.getInnerContext();
1259  assert(DC->isDependentContext() && "delaying non-dependent access");
1260  DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access,
1261                              Loc,
1262                              Entity.isMemberAccess(),
1263                              Entity.getAccess(),
1264                              Entity.getTargetDecl(),
1265                              Entity.getNamingClass(),
1266                              Entity.getBaseObjectType(),
1267                              Entity.getDiag());
1268}
1269
1270/// Checks access to an entity from the given effective context.
1271static AccessResult CheckEffectiveAccess(Sema &S,
1272                                         const EffectiveContext &EC,
1273                                         SourceLocation Loc,
1274                                         AccessTarget &Entity) {
1275  assert(Entity.getAccess() != AS_public && "called for public access!");
1276
1277  if (S.getLangOptions().MicrosoftMode &&
1278      IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity))
1279    return AR_accessible;
1280
1281  switch (IsAccessible(S, EC, Entity)) {
1282  case AR_dependent:
1283    DelayDependentAccess(S, EC, Loc, Entity);
1284    return AR_dependent;
1285
1286  case AR_inaccessible:
1287    if (!Entity.isQuiet())
1288      DiagnoseBadAccess(S, Loc, EC, Entity);
1289    return AR_inaccessible;
1290
1291  case AR_accessible:
1292    return AR_accessible;
1293  }
1294
1295  // silence unnecessary warning
1296  llvm_unreachable("invalid access result");
1297  return AR_accessible;
1298}
1299
1300static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
1301                                      AccessTarget &Entity) {
1302  // If the access path is public, it's accessible everywhere.
1303  if (Entity.getAccess() == AS_public)
1304    return Sema::AR_accessible;
1305
1306  if (S.SuppressAccessChecking)
1307    return Sema::AR_accessible;
1308
1309  // If we're currently parsing a declaration, we may need to delay
1310  // access control checking, because our effective context might be
1311  // different based on what the declaration comes out as.
1312  //
1313  // For example, we might be parsing a declaration with a scope
1314  // specifier, like this:
1315  //   A::private_type A::foo() { ... }
1316  //
1317  // Or we might be parsing something that will turn out to be a friend:
1318  //   void foo(A::private_type);
1319  //   void B::foo(A::private_type);
1320  if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
1321    S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
1322    return Sema::AR_delayed;
1323  }
1324
1325  EffectiveContext EC(S.CurContext);
1326  switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
1327  case AR_accessible: return Sema::AR_accessible;
1328  case AR_inaccessible: return Sema::AR_inaccessible;
1329  case AR_dependent: return Sema::AR_dependent;
1330  }
1331  llvm_unreachable("falling off end");
1332  return Sema::AR_accessible;
1333}
1334
1335void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *decl) {
1336  // Access control for names used in the declarations of functions
1337  // and function templates should normally be evaluated in the context
1338  // of the declaration, just in case it's a friend of something.
1339  // However, this does not apply to local extern declarations.
1340
1341  DeclContext *DC = decl->getDeclContext();
1342  if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
1343    if (!DC->isFunctionOrMethod()) DC = fn;
1344  } else if (FunctionTemplateDecl *fnt = dyn_cast<FunctionTemplateDecl>(decl)) {
1345    // Never a local declaration.
1346    DC = fnt->getTemplatedDecl();
1347  }
1348
1349  EffectiveContext EC(DC);
1350
1351  AccessTarget Target(DD.getAccessData());
1352
1353  if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
1354    DD.Triggered = true;
1355}
1356
1357void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD,
1358                        const MultiLevelTemplateArgumentList &TemplateArgs) {
1359  SourceLocation Loc = DD.getAccessLoc();
1360  AccessSpecifier Access = DD.getAccess();
1361
1362  Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
1363                                       TemplateArgs);
1364  if (!NamingD) return;
1365  Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
1366                                       TemplateArgs);
1367  if (!TargetD) return;
1368
1369  if (DD.isAccessToMember()) {
1370    CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
1371    NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1372    QualType BaseObjectType = DD.getAccessBaseObjectType();
1373    if (!BaseObjectType.isNull()) {
1374      BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1375                                 DeclarationName());
1376      if (BaseObjectType.isNull()) return;
1377    }
1378
1379    AccessTarget Entity(Context,
1380                        AccessTarget::Member,
1381                        NamingClass,
1382                        DeclAccessPair::make(TargetDecl, Access),
1383                        BaseObjectType);
1384    Entity.setDiag(DD.getDiagnostic());
1385    CheckAccess(*this, Loc, Entity);
1386  } else {
1387    AccessTarget Entity(Context,
1388                        AccessTarget::Base,
1389                        cast<CXXRecordDecl>(TargetD),
1390                        cast<CXXRecordDecl>(NamingD),
1391                        Access);
1392    Entity.setDiag(DD.getDiagnostic());
1393    CheckAccess(*this, Loc, Entity);
1394  }
1395}
1396
1397Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
1398                                                     DeclAccessPair Found) {
1399  if (!getLangOptions().AccessControl ||
1400      !E->getNamingClass() ||
1401      Found.getAccess() == AS_public)
1402    return AR_accessible;
1403
1404  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1405                      Found, QualType());
1406  Entity.setDiag(diag::err_access) << E->getSourceRange();
1407
1408  return CheckAccess(*this, E->getNameLoc(), Entity);
1409}
1410
1411/// Perform access-control checking on a previously-unresolved member
1412/// access which has now been resolved to a member.
1413Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
1414                                                     DeclAccessPair Found) {
1415  if (!getLangOptions().AccessControl ||
1416      Found.getAccess() == AS_public)
1417    return AR_accessible;
1418
1419  QualType BaseType = E->getBaseType();
1420  if (E->isArrow())
1421    BaseType = BaseType->getAs<PointerType>()->getPointeeType();
1422
1423  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1424                      Found, BaseType);
1425  Entity.setDiag(diag::err_access) << E->getSourceRange();
1426
1427  return CheckAccess(*this, E->getMemberLoc(), Entity);
1428}
1429
1430Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
1431                                               CXXDestructorDecl *Dtor,
1432                                               const PartialDiagnostic &PDiag) {
1433  if (!getLangOptions().AccessControl)
1434    return AR_accessible;
1435
1436  // There's never a path involved when checking implicit destructor access.
1437  AccessSpecifier Access = Dtor->getAccess();
1438  if (Access == AS_public)
1439    return AR_accessible;
1440
1441  CXXRecordDecl *NamingClass = Dtor->getParent();
1442  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1443                      DeclAccessPair::make(Dtor, Access),
1444                      QualType());
1445  Entity.setDiag(PDiag); // TODO: avoid copy
1446
1447  return CheckAccess(*this, Loc, Entity);
1448}
1449
1450/// Checks access to a constructor.
1451Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
1452                                                CXXConstructorDecl *Constructor,
1453                                                const InitializedEntity &Entity,
1454                                                AccessSpecifier Access,
1455                                                bool IsCopyBindingRefToTemp) {
1456  if (!getLangOptions().AccessControl ||
1457      Access == AS_public)
1458    return AR_accessible;
1459
1460  CXXRecordDecl *NamingClass = Constructor->getParent();
1461  AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass,
1462                            DeclAccessPair::make(Constructor, Access),
1463                            QualType());
1464  PartialDiagnostic PD(PDiag());
1465  switch (Entity.getKind()) {
1466  default:
1467    PD = PDiag(IsCopyBindingRefToTemp
1468                 ? diag::ext_rvalue_to_reference_access_ctor
1469                 : diag::err_access_ctor);
1470
1471    break;
1472
1473  case InitializedEntity::EK_Base:
1474    PD = PDiag(diag::err_access_base_ctor);
1475    PD << Entity.isInheritedVirtualBase()
1476       << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor);
1477    break;
1478
1479  case InitializedEntity::EK_Member: {
1480    const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
1481    PD = PDiag(diag::err_access_field_ctor);
1482    PD << Field->getType() << getSpecialMember(Constructor);
1483    break;
1484  }
1485
1486  }
1487
1488  return CheckConstructorAccess(UseLoc, Constructor, Access, PD);
1489}
1490
1491/// Checks access to a constructor.
1492Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
1493                                                CXXConstructorDecl *Constructor,
1494                                                AccessSpecifier Access,
1495                                                PartialDiagnostic PD) {
1496  if (!getLangOptions().AccessControl ||
1497      Access == AS_public)
1498    return AR_accessible;
1499
1500  CXXRecordDecl *NamingClass = Constructor->getParent();
1501  AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass,
1502                            DeclAccessPair::make(Constructor, Access),
1503                            QualType());
1504  AccessEntity.setDiag(PD);
1505
1506  return CheckAccess(*this, UseLoc, AccessEntity);
1507}
1508
1509/// Checks direct (i.e. non-inherited) access to an arbitrary class
1510/// member.
1511Sema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc,
1512                                                 NamedDecl *Target,
1513                                           const PartialDiagnostic &Diag) {
1514  AccessSpecifier Access = Target->getAccess();
1515  if (!getLangOptions().AccessControl ||
1516      Access == AS_public)
1517    return AR_accessible;
1518
1519  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Target->getDeclContext());
1520  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1521                      DeclAccessPair::make(Target, Access),
1522                      QualType());
1523  Entity.setDiag(Diag);
1524  return CheckAccess(*this, UseLoc, Entity);
1525}
1526
1527
1528/// Checks access to an overloaded operator new or delete.
1529Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
1530                                               SourceRange PlacementRange,
1531                                               CXXRecordDecl *NamingClass,
1532                                               DeclAccessPair Found,
1533                                               bool Diagnose) {
1534  if (!getLangOptions().AccessControl ||
1535      !NamingClass ||
1536      Found.getAccess() == AS_public)
1537    return AR_accessible;
1538
1539  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1540                      QualType());
1541  if (Diagnose)
1542    Entity.setDiag(diag::err_access)
1543      << PlacementRange;
1544
1545  return CheckAccess(*this, OpLoc, Entity);
1546}
1547
1548/// Checks access to an overloaded member operator, including
1549/// conversion operators.
1550Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
1551                                                   Expr *ObjectExpr,
1552                                                   Expr *ArgExpr,
1553                                                   DeclAccessPair Found) {
1554  if (!getLangOptions().AccessControl ||
1555      Found.getAccess() == AS_public)
1556    return AR_accessible;
1557
1558  const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
1559  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
1560
1561  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1562                      ObjectExpr->getType());
1563  Entity.setDiag(diag::err_access)
1564    << ObjectExpr->getSourceRange()
1565    << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange());
1566
1567  return CheckAccess(*this, OpLoc, Entity);
1568}
1569
1570Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
1571                                                    DeclAccessPair Found) {
1572  if (!getLangOptions().AccessControl ||
1573      Found.getAccess() == AS_none ||
1574      Found.getAccess() == AS_public)
1575    return AR_accessible;
1576
1577  OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
1578  CXXRecordDecl *NamingClass = Ovl->getNamingClass();
1579
1580  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1581                      Context.getTypeDeclType(NamingClass));
1582  Entity.setDiag(diag::err_access)
1583    << Ovl->getSourceRange();
1584
1585  return CheckAccess(*this, Ovl->getNameLoc(), Entity);
1586}
1587
1588/// Checks access for a hierarchy conversion.
1589///
1590/// \param IsBaseToDerived whether this is a base-to-derived conversion (true)
1591///     or a derived-to-base conversion (false)
1592/// \param ForceCheck true if this check should be performed even if access
1593///     control is disabled;  some things rely on this for semantics
1594/// \param ForceUnprivileged true if this check should proceed as if the
1595///     context had no special privileges
1596/// \param ADK controls the kind of diagnostics that are used
1597Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
1598                                              QualType Base,
1599                                              QualType Derived,
1600                                              const CXXBasePath &Path,
1601                                              unsigned DiagID,
1602                                              bool ForceCheck,
1603                                              bool ForceUnprivileged) {
1604  if (!ForceCheck && !getLangOptions().AccessControl)
1605    return AR_accessible;
1606
1607  if (Path.Access == AS_public)
1608    return AR_accessible;
1609
1610  CXXRecordDecl *BaseD, *DerivedD;
1611  BaseD = cast<CXXRecordDecl>(Base->getAs<RecordType>()->getDecl());
1612  DerivedD = cast<CXXRecordDecl>(Derived->getAs<RecordType>()->getDecl());
1613
1614  AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
1615                      Path.Access);
1616  if (DiagID)
1617    Entity.setDiag(DiagID) << Derived << Base;
1618
1619  if (ForceUnprivileged) {
1620    switch (CheckEffectiveAccess(*this, EffectiveContext(),
1621                                 AccessLoc, Entity)) {
1622    case ::AR_accessible: return Sema::AR_accessible;
1623    case ::AR_inaccessible: return Sema::AR_inaccessible;
1624    case ::AR_dependent: return Sema::AR_dependent;
1625    }
1626    llvm_unreachable("unexpected result from CheckEffectiveAccess");
1627  }
1628  return CheckAccess(*this, AccessLoc, Entity);
1629}
1630
1631/// Checks access to all the declarations in the given result set.
1632void Sema::CheckLookupAccess(const LookupResult &R) {
1633  assert(getLangOptions().AccessControl
1634         && "performing access check without access control");
1635  assert(R.getNamingClass() && "performing access check without naming class");
1636
1637  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
1638    if (I.getAccess() != AS_public) {
1639      AccessTarget Entity(Context, AccessedEntity::Member,
1640                          R.getNamingClass(), I.getPair(),
1641                          R.getBaseObjectType());
1642      Entity.setDiag(diag::err_access);
1643      CheckAccess(*this, R.getNameLoc(), Entity);
1644    }
1645  }
1646}
1647
1648/// Checks access to Decl from the given class. The check will take access
1649/// specifiers into account, but no member access expressions and such.
1650///
1651/// \param Decl the declaration to check if it can be accessed
1652/// \param Class the class/context from which to start the search
1653/// \return true if the Decl is accessible from the Class, false otherwise.
1654bool Sema::IsSimplyAccessible(NamedDecl *Decl, DeclContext *Ctx) {
1655  if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx)) {
1656    if (!Class || !Decl->isCXXClassMember())
1657      return true;
1658
1659    QualType qType = Class->getTypeForDecl()->getCanonicalTypeInternal();
1660    AccessTarget Entity(Context, AccessedEntity::Member, Class,
1661                        DeclAccessPair::make(Decl, Decl->getAccess()),
1662                        qType);
1663    if (Entity.getAccess() == AS_public)
1664      return true;
1665
1666    EffectiveContext EC(CurContext);
1667    return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
1668  }
1669
1670  // FIXME: Check access for Objective-C ivars.
1671  return true;
1672}
1673
1674void Sema::ActOnStartSuppressingAccessChecks() {
1675  assert(!SuppressAccessChecking &&
1676         "Tried to start access check suppression when already started.");
1677  SuppressAccessChecking = true;
1678}
1679
1680void Sema::ActOnStopSuppressingAccessChecks() {
1681  assert(SuppressAccessChecking &&
1682         "Tried to stop access check suprression when already stopped.");
1683  SuppressAccessChecking = false;
1684}
1685