SemaAccess.cpp revision 162e1c1b487352434552147967c3dd296ebee2f7
129f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson//===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===//
260d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//
360d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//                     The LLVM Compiler Infrastructure
460d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//
560d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson// This file is distributed under the University of Illinois Open Source
660d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson// License. See LICENSE.TXT for details.
760d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//
860d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//===----------------------------------------------------------------------===//
960d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//
1060d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson// This file provides Sema routines for C++ access control semantics.
1160d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//
1260d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//===----------------------------------------------------------------------===//
13c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson
142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h"
159c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall#include "clang/Sema/DelayedDiagnostic.h"
16e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "clang/Sema/Initialization.h"
17e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "clang/Sema/Lookup.h"
18c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson#include "clang/AST/ASTContext.h"
19a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor#include "clang/AST/CXXInheritance.h"
20a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor#include "clang/AST/DeclCXX.h"
21d60e22e601852ae1345f01514318a0951dc09f89John McCall#include "clang/AST/DeclFriend.h"
220c01d18094100db92d38daa923c95661512db203John McCall#include "clang/AST/DependentDiagnostic.h"
23c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall#include "clang/AST/ExprCXX.h"
24c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
25c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlssonusing namespace clang;
269c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
27c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson
28161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// A copy of Sema's enum without AR_delayed.
29161755a09898c95d21bfff33707da9ca41cd53c5John McCallenum AccessResult {
30161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AR_accessible,
31161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AR_inaccessible,
32161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AR_dependent
33161755a09898c95d21bfff33707da9ca41cd53c5John McCall};
34161755a09898c95d21bfff33707da9ca41cd53c5John McCall
3529f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson/// SetMemberAccessSpecifier - Set the access specifier of a member.
3629f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson/// Returns true on error (when the previous member decl access specifier
3729f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson/// is different from the new member decl access specifier).
381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpbool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
39c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson                                    NamedDecl *PrevMemberDecl,
40c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson                                    AccessSpecifier LexicalAS) {
41c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  if (!PrevMemberDecl) {
42c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    // Use the lexical access specifier.
43c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    MemberDecl->setAccess(LexicalAS);
44c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    return false;
45c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  }
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
47c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  // C++ [class.access.spec]p3: When a member is redeclared its access
48c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  // specifier must be same as its initial declaration.
49c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Diag(MemberDecl->getLocation(),
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump         diag::err_class_redeclared_with_different_access)
52c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson      << MemberDecl << LexicalAS;
53c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
54c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson      << PrevMemberDecl << PrevMemberDecl->getAccess();
5544e067bd8f923ba8e7c24b2189e06717d70015c8John McCall
5644e067bd8f923ba8e7c24b2189e06717d70015c8John McCall    MemberDecl->setAccess(LexicalAS);
57c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    return true;
58c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  }
591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  MemberDecl->setAccess(PrevMemberDecl->getAccess());
61c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  return false;
62c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson}
6329f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson
64161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic CXXRecordDecl *FindDeclaringClass(NamedDecl *D) {
65161755a09898c95d21bfff33707da9ca41cd53c5John McCall  DeclContext *DC = D->getDeclContext();
66161755a09898c95d21bfff33707da9ca41cd53c5John McCall
67161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // This can only happen at top: enum decls only "publish" their
68161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // immediate members.
69161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (isa<EnumDecl>(DC))
70161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DC = cast<EnumDecl>(DC)->getDeclContext();
71161755a09898c95d21bfff33707da9ca41cd53c5John McCall
72161755a09898c95d21bfff33707da9ca41cd53c5John McCall  CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
73161755a09898c95d21bfff33707da9ca41cd53c5John McCall  while (DeclaringClass->isAnonymousStructOrUnion())
74161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
75161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return DeclaringClass;
76161755a09898c95d21bfff33707da9ca41cd53c5John McCall}
77161755a09898c95d21bfff33707da9ca41cd53c5John McCall
786b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallnamespace {
796b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstruct EffectiveContext {
802cc2675d426af23476a9722c08c1b6c5266bd653John McCall  EffectiveContext() : Inner(0), Dependent(false) {}
816b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
827ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  explicit EffectiveContext(DeclContext *DC)
837ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall    : Inner(DC),
847ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall      Dependent(DC->isDependentContext()) {
850c01d18094100db92d38daa923c95661512db203John McCall
8688b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    // C++ [class.access.nest]p1:
8788b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    //   A nested class is a member and as such has the same access
8888b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    //   rights as any other member.
8988b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    // C++ [class.access]p2:
9088b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    //   A member of a class can also access all the names to which
912cc2675d426af23476a9722c08c1b6c5266bd653John McCall    //   the class has access.  A local class of a member function
922cc2675d426af23476a9722c08c1b6c5266bd653John McCall    //   may access the same names that the member function itself
932cc2675d426af23476a9722c08c1b6c5266bd653John McCall    //   may access.
942cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // This almost implies that the privileges of nesting are transitive.
952cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // Technically it says nothing about the local classes of non-member
962cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // functions (which can gain privileges through friendship), but we
972cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // take that as an oversight.
982cc2675d426af23476a9722c08c1b6c5266bd653John McCall    while (true) {
992cc2675d426af23476a9722c08c1b6c5266bd653John McCall      if (isa<CXXRecordDecl>(DC)) {
1002cc2675d426af23476a9722c08c1b6c5266bd653John McCall        CXXRecordDecl *Record = cast<CXXRecordDecl>(DC)->getCanonicalDecl();
1012cc2675d426af23476a9722c08c1b6c5266bd653John McCall        Records.push_back(Record);
1022cc2675d426af23476a9722c08c1b6c5266bd653John McCall        DC = Record->getDeclContext();
1032cc2675d426af23476a9722c08c1b6c5266bd653John McCall      } else if (isa<FunctionDecl>(DC)) {
1042cc2675d426af23476a9722c08c1b6c5266bd653John McCall        FunctionDecl *Function = cast<FunctionDecl>(DC)->getCanonicalDecl();
1052cc2675d426af23476a9722c08c1b6c5266bd653John McCall        Functions.push_back(Function);
1062cc2675d426af23476a9722c08c1b6c5266bd653John McCall        DC = Function->getDeclContext();
1072cc2675d426af23476a9722c08c1b6c5266bd653John McCall      } else if (DC->isFileContext()) {
1082cc2675d426af23476a9722c08c1b6c5266bd653John McCall        break;
1092cc2675d426af23476a9722c08c1b6c5266bd653John McCall      } else {
1102cc2675d426af23476a9722c08c1b6c5266bd653John McCall        DC = DC->getParent();
1112cc2675d426af23476a9722c08c1b6c5266bd653John McCall      }
11288b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    }
1136b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
1146b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1150c01d18094100db92d38daa923c95661512db203John McCall  bool isDependent() const { return Dependent; }
1160c01d18094100db92d38daa923c95661512db203John McCall
11788b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall  bool includesClass(const CXXRecordDecl *R) const {
11888b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    R = R->getCanonicalDecl();
11988b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    return std::find(Records.begin(), Records.end(), R)
12088b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall             != Records.end();
1216b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
1226b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1237ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  /// Retrieves the innermost "useful" context.  Can be null if we're
1247ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  /// doing access-control without privileges.
1257ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  DeclContext *getInnerContext() const {
1267ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall    return Inner;
1270c01d18094100db92d38daa923c95661512db203John McCall  }
1280c01d18094100db92d38daa923c95661512db203John McCall
1290c01d18094100db92d38daa923c95661512db203John McCall  typedef llvm::SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
1300c01d18094100db92d38daa923c95661512db203John McCall
1317ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  DeclContext *Inner;
1322cc2675d426af23476a9722c08c1b6c5266bd653John McCall  llvm::SmallVector<FunctionDecl*, 4> Functions;
13388b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall  llvm::SmallVector<CXXRecordDecl*, 4> Records;
1340c01d18094100db92d38daa923c95661512db203John McCall  bool Dependent;
1356b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall};
136161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1376bb4dcb412d53d05a80017df81d41e447e2aa3eaNico Weber/// Like sema::AccessedEntity, but kindly lets us scribble all over
138161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// it.
1399c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallstruct AccessTarget : public AccessedEntity {
1409c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  AccessTarget(const AccessedEntity &Entity)
141161755a09898c95d21bfff33707da9ca41cd53c5John McCall    : AccessedEntity(Entity) {
142161755a09898c95d21bfff33707da9ca41cd53c5John McCall    initialize();
143161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
144161755a09898c95d21bfff33707da9ca41cd53c5John McCall
145161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget(ASTContext &Context,
146161755a09898c95d21bfff33707da9ca41cd53c5John McCall               MemberNonce _,
147161755a09898c95d21bfff33707da9ca41cd53c5John McCall               CXXRecordDecl *NamingClass,
148161755a09898c95d21bfff33707da9ca41cd53c5John McCall               DeclAccessPair FoundDecl,
149161755a09898c95d21bfff33707da9ca41cd53c5John McCall               QualType BaseObjectType)
150161755a09898c95d21bfff33707da9ca41cd53c5John McCall    : AccessedEntity(Context, Member, NamingClass, FoundDecl, BaseObjectType) {
151161755a09898c95d21bfff33707da9ca41cd53c5John McCall    initialize();
152161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
153161755a09898c95d21bfff33707da9ca41cd53c5John McCall
154161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget(ASTContext &Context,
155161755a09898c95d21bfff33707da9ca41cd53c5John McCall               BaseNonce _,
156161755a09898c95d21bfff33707da9ca41cd53c5John McCall               CXXRecordDecl *BaseClass,
157161755a09898c95d21bfff33707da9ca41cd53c5John McCall               CXXRecordDecl *DerivedClass,
158161755a09898c95d21bfff33707da9ca41cd53c5John McCall               AccessSpecifier Access)
159161755a09898c95d21bfff33707da9ca41cd53c5John McCall    : AccessedEntity(Context, Base, BaseClass, DerivedClass, Access) {
160161755a09898c95d21bfff33707da9ca41cd53c5John McCall    initialize();
161161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
162161755a09898c95d21bfff33707da9ca41cd53c5John McCall
163161755a09898c95d21bfff33707da9ca41cd53c5John McCall  bool hasInstanceContext() const {
164161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return HasInstanceContext;
165161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
166161755a09898c95d21bfff33707da9ca41cd53c5John McCall
167161755a09898c95d21bfff33707da9ca41cd53c5John McCall  class SavedInstanceContext {
168161755a09898c95d21bfff33707da9ca41cd53c5John McCall  public:
169161755a09898c95d21bfff33707da9ca41cd53c5John McCall    ~SavedInstanceContext() {
170161755a09898c95d21bfff33707da9ca41cd53c5John McCall      Target.HasInstanceContext = Has;
171161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
172161755a09898c95d21bfff33707da9ca41cd53c5John McCall
173161755a09898c95d21bfff33707da9ca41cd53c5John McCall  private:
174c91cc66e92b084acd1fdbaa1c3c74242741b3d46John McCall    friend struct AccessTarget;
175161755a09898c95d21bfff33707da9ca41cd53c5John McCall    explicit SavedInstanceContext(AccessTarget &Target)
176161755a09898c95d21bfff33707da9ca41cd53c5John McCall      : Target(Target), Has(Target.HasInstanceContext) {}
177161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget &Target;
178161755a09898c95d21bfff33707da9ca41cd53c5John McCall    bool Has;
179161755a09898c95d21bfff33707da9ca41cd53c5John McCall  };
180161755a09898c95d21bfff33707da9ca41cd53c5John McCall
181161755a09898c95d21bfff33707da9ca41cd53c5John McCall  SavedInstanceContext saveInstanceContext() {
182161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return SavedInstanceContext(*this);
183161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
184161755a09898c95d21bfff33707da9ca41cd53c5John McCall
185161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void suppressInstanceContext() {
186161755a09898c95d21bfff33707da9ca41cd53c5John McCall    HasInstanceContext = false;
187161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
188161755a09898c95d21bfff33707da9ca41cd53c5John McCall
189161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
190161755a09898c95d21bfff33707da9ca41cd53c5John McCall    assert(HasInstanceContext);
191161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (CalculatedInstanceContext)
192161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return InstanceContext;
193161755a09898c95d21bfff33707da9ca41cd53c5John McCall
194161755a09898c95d21bfff33707da9ca41cd53c5John McCall    CalculatedInstanceContext = true;
195161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DeclContext *IC = S.computeDeclContext(getBaseObjectType());
196161755a09898c95d21bfff33707da9ca41cd53c5John McCall    InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl() : 0);
197161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return InstanceContext;
198161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
199161755a09898c95d21bfff33707da9ca41cd53c5John McCall
200161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *getDeclaringClass() const {
201161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return DeclaringClass;
202161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
203161755a09898c95d21bfff33707da9ca41cd53c5John McCall
204161755a09898c95d21bfff33707da9ca41cd53c5John McCallprivate:
205161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void initialize() {
206161755a09898c95d21bfff33707da9ca41cd53c5John McCall    HasInstanceContext = (isMemberAccess() &&
207161755a09898c95d21bfff33707da9ca41cd53c5John McCall                          !getBaseObjectType().isNull() &&
208161755a09898c95d21bfff33707da9ca41cd53c5John McCall                          getTargetDecl()->isCXXInstanceMember());
209161755a09898c95d21bfff33707da9ca41cd53c5John McCall    CalculatedInstanceContext = false;
210161755a09898c95d21bfff33707da9ca41cd53c5John McCall    InstanceContext = 0;
211161755a09898c95d21bfff33707da9ca41cd53c5John McCall
212161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (isMemberAccess())
213161755a09898c95d21bfff33707da9ca41cd53c5John McCall      DeclaringClass = FindDeclaringClass(getTargetDecl());
214161755a09898c95d21bfff33707da9ca41cd53c5John McCall    else
215161755a09898c95d21bfff33707da9ca41cd53c5John McCall      DeclaringClass = getBaseClass();
216161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DeclaringClass = DeclaringClass->getCanonicalDecl();
217161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
218161755a09898c95d21bfff33707da9ca41cd53c5John McCall
219161755a09898c95d21bfff33707da9ca41cd53c5John McCall  bool HasInstanceContext : 1;
220161755a09898c95d21bfff33707da9ca41cd53c5John McCall  mutable bool CalculatedInstanceContext : 1;
221161755a09898c95d21bfff33707da9ca41cd53c5John McCall  mutable const CXXRecordDecl *InstanceContext;
222161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *DeclaringClass;
223161755a09898c95d21bfff33707da9ca41cd53c5John McCall};
224161755a09898c95d21bfff33707da9ca41cd53c5John McCall
2256b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
226726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
22701ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall/// Checks whether one class might instantiate to the other.
22801ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCallstatic bool MightInstantiateTo(const CXXRecordDecl *From,
22901ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall                               const CXXRecordDecl *To) {
23001ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  // Declaration names are always preserved by instantiation.
23101ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (From->getDeclName() != To->getDeclName())
23201ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall    return false;
23301ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
23401ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
23501ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
23601ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (FromDC == ToDC) return true;
23701ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
23801ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
23901ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  // Be conservative.
24001ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  return true;
24101ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall}
24201ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
243161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// Checks whether one class is derived from another, inclusively.
244161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// Properly indicates when it couldn't be determined due to
245161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// dependence.
246161755a09898c95d21bfff33707da9ca41cd53c5John McCall///
247161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// This should probably be donated to AST or at least Sema.
248161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived,
249161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                           const CXXRecordDecl *Target) {
250161755a09898c95d21bfff33707da9ca41cd53c5John McCall  assert(Derived->getCanonicalDecl() == Derived);
251161755a09898c95d21bfff33707da9ca41cd53c5John McCall  assert(Target->getCanonicalDecl() == Target);
252c1b621daf98d83075a466c6f4ad9904dc845dd09John McCall
253161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (Derived == Target) return AR_accessible;
254c1b621daf98d83075a466c6f4ad9904dc845dd09John McCall
25501ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  bool CheckDependent = Derived->isDependentContext();
25601ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (CheckDependent && MightInstantiateTo(Derived, Target))
25701ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall    return AR_dependent;
25801ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
259161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
260161755a09898c95d21bfff33707da9ca41cd53c5John McCall  llvm::SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
261161755a09898c95d21bfff33707da9ca41cd53c5John McCall
262161755a09898c95d21bfff33707da9ca41cd53c5John McCall  while (true) {
263161755a09898c95d21bfff33707da9ca41cd53c5John McCall    for (CXXRecordDecl::base_class_const_iterator
264161755a09898c95d21bfff33707da9ca41cd53c5John McCall           I = Derived->bases_begin(), E = Derived->bases_end(); I != E; ++I) {
265161755a09898c95d21bfff33707da9ca41cd53c5John McCall
266161755a09898c95d21bfff33707da9ca41cd53c5John McCall      const CXXRecordDecl *RD;
267161755a09898c95d21bfff33707da9ca41cd53c5John McCall
268161755a09898c95d21bfff33707da9ca41cd53c5John McCall      QualType T = I->getType();
269161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (const RecordType *RT = T->getAs<RecordType>()) {
270161755a09898c95d21bfff33707da9ca41cd53c5John McCall        RD = cast<CXXRecordDecl>(RT->getDecl());
27101ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall      } else if (const InjectedClassNameType *IT
27201ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall                   = T->getAs<InjectedClassNameType>()) {
27301ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall        RD = IT->getDecl();
274161755a09898c95d21bfff33707da9ca41cd53c5John McCall      } else {
275161755a09898c95d21bfff33707da9ca41cd53c5John McCall        assert(T->isDependentType() && "non-dependent base wasn't a record?");
276161755a09898c95d21bfff33707da9ca41cd53c5John McCall        OnFailure = AR_dependent;
277161755a09898c95d21bfff33707da9ca41cd53c5John McCall        continue;
278161755a09898c95d21bfff33707da9ca41cd53c5John McCall      }
279161755a09898c95d21bfff33707da9ca41cd53c5John McCall
280161755a09898c95d21bfff33707da9ca41cd53c5John McCall      RD = RD->getCanonicalDecl();
281161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (RD == Target) return AR_accessible;
28201ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall      if (CheckDependent && MightInstantiateTo(RD, Target))
28301ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall        OnFailure = AR_dependent;
28401ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
285161755a09898c95d21bfff33707da9ca41cd53c5John McCall      Queue.push_back(RD);
286161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
287161755a09898c95d21bfff33707da9ca41cd53c5John McCall
288161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (Queue.empty()) break;
289161755a09898c95d21bfff33707da9ca41cd53c5John McCall
290161755a09898c95d21bfff33707da9ca41cd53c5John McCall    Derived = Queue.back();
291161755a09898c95d21bfff33707da9ca41cd53c5John McCall    Queue.pop_back();
292161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
293161755a09898c95d21bfff33707da9ca41cd53c5John McCall
294161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return OnFailure;
2956b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
2966b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
297161755a09898c95d21bfff33707da9ca41cd53c5John McCall
2980c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S, DeclContext *Context,
2990c01d18094100db92d38daa923c95661512db203John McCall                               DeclContext *Friend) {
3000c01d18094100db92d38daa923c95661512db203John McCall  if (Friend == Context)
3010c01d18094100db92d38daa923c95661512db203John McCall    return true;
3020c01d18094100db92d38daa923c95661512db203John McCall
3030c01d18094100db92d38daa923c95661512db203John McCall  assert(!Friend->isDependentContext() &&
3040c01d18094100db92d38daa923c95661512db203John McCall         "can't handle friends with dependent contexts here");
3050c01d18094100db92d38daa923c95661512db203John McCall
3060c01d18094100db92d38daa923c95661512db203John McCall  if (!Context->isDependentContext())
3070c01d18094100db92d38daa923c95661512db203John McCall    return false;
3080c01d18094100db92d38daa923c95661512db203John McCall
3090c01d18094100db92d38daa923c95661512db203John McCall  if (Friend->isFileContext())
3100c01d18094100db92d38daa923c95661512db203John McCall    return false;
3110c01d18094100db92d38daa923c95661512db203John McCall
3120c01d18094100db92d38daa923c95661512db203John McCall  // TODO: this is very conservative
3130c01d18094100db92d38daa923c95661512db203John McCall  return true;
3140c01d18094100db92d38daa923c95661512db203John McCall}
3150c01d18094100db92d38daa923c95661512db203John McCall
3160c01d18094100db92d38daa923c95661512db203John McCall// Asks whether the type in 'context' can ever instantiate to the type
3170c01d18094100db92d38daa923c95661512db203John McCall// in 'friend'.
3180c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) {
3190c01d18094100db92d38daa923c95661512db203John McCall  if (Friend == Context)
3200c01d18094100db92d38daa923c95661512db203John McCall    return true;
3210c01d18094100db92d38daa923c95661512db203John McCall
3220c01d18094100db92d38daa923c95661512db203John McCall  if (!Friend->isDependentType() && !Context->isDependentType())
3230c01d18094100db92d38daa923c95661512db203John McCall    return false;
3240c01d18094100db92d38daa923c95661512db203John McCall
3250c01d18094100db92d38daa923c95661512db203John McCall  // TODO: this is very conservative.
3260c01d18094100db92d38daa923c95661512db203John McCall  return true;
3270c01d18094100db92d38daa923c95661512db203John McCall}
3280c01d18094100db92d38daa923c95661512db203John McCall
3290c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S,
3300c01d18094100db92d38daa923c95661512db203John McCall                               FunctionDecl *Context,
3310c01d18094100db92d38daa923c95661512db203John McCall                               FunctionDecl *Friend) {
3320c01d18094100db92d38daa923c95661512db203John McCall  if (Context->getDeclName() != Friend->getDeclName())
3330c01d18094100db92d38daa923c95661512db203John McCall    return false;
3340c01d18094100db92d38daa923c95661512db203John McCall
3350c01d18094100db92d38daa923c95661512db203John McCall  if (!MightInstantiateTo(S,
3360c01d18094100db92d38daa923c95661512db203John McCall                          Context->getDeclContext(),
3370c01d18094100db92d38daa923c95661512db203John McCall                          Friend->getDeclContext()))
3380c01d18094100db92d38daa923c95661512db203John McCall    return false;
3390c01d18094100db92d38daa923c95661512db203John McCall
3400c01d18094100db92d38daa923c95661512db203John McCall  CanQual<FunctionProtoType> FriendTy
3410c01d18094100db92d38daa923c95661512db203John McCall    = S.Context.getCanonicalType(Friend->getType())
3420c01d18094100db92d38daa923c95661512db203John McCall         ->getAs<FunctionProtoType>();
3430c01d18094100db92d38daa923c95661512db203John McCall  CanQual<FunctionProtoType> ContextTy
3440c01d18094100db92d38daa923c95661512db203John McCall    = S.Context.getCanonicalType(Context->getType())
3450c01d18094100db92d38daa923c95661512db203John McCall         ->getAs<FunctionProtoType>();
3460c01d18094100db92d38daa923c95661512db203John McCall
3470c01d18094100db92d38daa923c95661512db203John McCall  // There isn't any way that I know of to add qualifiers
3480c01d18094100db92d38daa923c95661512db203John McCall  // during instantiation.
3490c01d18094100db92d38daa923c95661512db203John McCall  if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
3500c01d18094100db92d38daa923c95661512db203John McCall    return false;
3510c01d18094100db92d38daa923c95661512db203John McCall
3520c01d18094100db92d38daa923c95661512db203John McCall  if (FriendTy->getNumArgs() != ContextTy->getNumArgs())
3530c01d18094100db92d38daa923c95661512db203John McCall    return false;
3540c01d18094100db92d38daa923c95661512db203John McCall
3550c01d18094100db92d38daa923c95661512db203John McCall  if (!MightInstantiateTo(S,
3560c01d18094100db92d38daa923c95661512db203John McCall                          ContextTy->getResultType(),
3570c01d18094100db92d38daa923c95661512db203John McCall                          FriendTy->getResultType()))
3580c01d18094100db92d38daa923c95661512db203John McCall    return false;
3590c01d18094100db92d38daa923c95661512db203John McCall
3600c01d18094100db92d38daa923c95661512db203John McCall  for (unsigned I = 0, E = FriendTy->getNumArgs(); I != E; ++I)
3610c01d18094100db92d38daa923c95661512db203John McCall    if (!MightInstantiateTo(S,
3620c01d18094100db92d38daa923c95661512db203John McCall                            ContextTy->getArgType(I),
3630c01d18094100db92d38daa923c95661512db203John McCall                            FriendTy->getArgType(I)))
3640c01d18094100db92d38daa923c95661512db203John McCall      return false;
3650c01d18094100db92d38daa923c95661512db203John McCall
3660c01d18094100db92d38daa923c95661512db203John McCall  return true;
3670c01d18094100db92d38daa923c95661512db203John McCall}
3680c01d18094100db92d38daa923c95661512db203John McCall
3690c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S,
3700c01d18094100db92d38daa923c95661512db203John McCall                               FunctionTemplateDecl *Context,
3710c01d18094100db92d38daa923c95661512db203John McCall                               FunctionTemplateDecl *Friend) {
3720c01d18094100db92d38daa923c95661512db203John McCall  return MightInstantiateTo(S,
3730c01d18094100db92d38daa923c95661512db203John McCall                            Context->getTemplatedDecl(),
3740c01d18094100db92d38daa923c95661512db203John McCall                            Friend->getTemplatedDecl());
3750c01d18094100db92d38daa923c95661512db203John McCall}
3760c01d18094100db92d38daa923c95661512db203John McCall
377161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
378161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
379161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const CXXRecordDecl *Friend) {
380a742db0032d8f458fe229600d2082981a1fb1481John McCall  if (EC.includesClass(Friend))
381161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_accessible;
382a742db0032d8f458fe229600d2082981a1fb1481John McCall
3830c01d18094100db92d38daa923c95661512db203John McCall  if (EC.isDependent()) {
3840c01d18094100db92d38daa923c95661512db203John McCall    CanQualType FriendTy
3850c01d18094100db92d38daa923c95661512db203John McCall      = S.Context.getCanonicalType(S.Context.getTypeDeclType(Friend));
3860c01d18094100db92d38daa923c95661512db203John McCall
3870c01d18094100db92d38daa923c95661512db203John McCall    for (EffectiveContext::record_iterator
3880c01d18094100db92d38daa923c95661512db203John McCall           I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
3890c01d18094100db92d38daa923c95661512db203John McCall      CanQualType ContextTy
3900c01d18094100db92d38daa923c95661512db203John McCall        = S.Context.getCanonicalType(S.Context.getTypeDeclType(*I));
3910c01d18094100db92d38daa923c95661512db203John McCall      if (MightInstantiateTo(S, ContextTy, FriendTy))
392161755a09898c95d21bfff33707da9ca41cd53c5John McCall        return AR_dependent;
3930c01d18094100db92d38daa923c95661512db203John McCall    }
3940c01d18094100db92d38daa923c95661512db203John McCall  }
3950c01d18094100db92d38daa923c95661512db203John McCall
396161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return AR_inaccessible;
397a742db0032d8f458fe229600d2082981a1fb1481John McCall}
398a742db0032d8f458fe229600d2082981a1fb1481John McCall
399161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
400161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
401161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  CanQualType Friend) {
4020c01d18094100db92d38daa923c95661512db203John McCall  if (const RecordType *RT = Friend->getAs<RecordType>())
4030c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
404a742db0032d8f458fe229600d2082981a1fb1481John McCall
4050c01d18094100db92d38daa923c95661512db203John McCall  // TODO: we can do better than this
4060c01d18094100db92d38daa923c95661512db203John McCall  if (Friend->isDependentType())
407161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_dependent;
408a742db0032d8f458fe229600d2082981a1fb1481John McCall
409161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return AR_inaccessible;
4100c01d18094100db92d38daa923c95661512db203John McCall}
411a742db0032d8f458fe229600d2082981a1fb1481John McCall
4120c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend class template matches
4130c01d18094100db92d38daa923c95661512db203John McCall/// anything in the effective context.
414161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
415161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
416161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  ClassTemplateDecl *Friend) {
417161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
418a742db0032d8f458fe229600d2082981a1fb1481John McCall
41993ba8579c341d5329175f1413cdc3b35a36592d2John McCall  // Check whether the friend is the template of a class in the
42093ba8579c341d5329175f1413cdc3b35a36592d2John McCall  // context chain.
4210c01d18094100db92d38daa923c95661512db203John McCall  for (llvm::SmallVectorImpl<CXXRecordDecl*>::const_iterator
4220c01d18094100db92d38daa923c95661512db203John McCall         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
4230c01d18094100db92d38daa923c95661512db203John McCall    CXXRecordDecl *Record = *I;
424a742db0032d8f458fe229600d2082981a1fb1481John McCall
42593ba8579c341d5329175f1413cdc3b35a36592d2John McCall    // Figure out whether the current class has a template:
4260c01d18094100db92d38daa923c95661512db203John McCall    ClassTemplateDecl *CTD;
427a742db0032d8f458fe229600d2082981a1fb1481John McCall
4280c01d18094100db92d38daa923c95661512db203John McCall    // A specialization of the template...
4290c01d18094100db92d38daa923c95661512db203John McCall    if (isa<ClassTemplateSpecializationDecl>(Record)) {
4300c01d18094100db92d38daa923c95661512db203John McCall      CTD = cast<ClassTemplateSpecializationDecl>(Record)
4310c01d18094100db92d38daa923c95661512db203John McCall        ->getSpecializedTemplate();
432a742db0032d8f458fe229600d2082981a1fb1481John McCall
4330c01d18094100db92d38daa923c95661512db203John McCall    // ... or the template pattern itself.
4340c01d18094100db92d38daa923c95661512db203John McCall    } else {
4350c01d18094100db92d38daa923c95661512db203John McCall      CTD = Record->getDescribedClassTemplate();
4360c01d18094100db92d38daa923c95661512db203John McCall      if (!CTD) continue;
437a742db0032d8f458fe229600d2082981a1fb1481John McCall    }
438a742db0032d8f458fe229600d2082981a1fb1481John McCall
4390c01d18094100db92d38daa923c95661512db203John McCall    // It's a match.
4400c01d18094100db92d38daa923c95661512db203John McCall    if (Friend == CTD->getCanonicalDecl())
441161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
4420c01d18094100db92d38daa923c95661512db203John McCall
44393ba8579c341d5329175f1413cdc3b35a36592d2John McCall    // If the context isn't dependent, it can't be a dependent match.
44493ba8579c341d5329175f1413cdc3b35a36592d2John McCall    if (!EC.isDependent())
44593ba8579c341d5329175f1413cdc3b35a36592d2John McCall      continue;
44693ba8579c341d5329175f1413cdc3b35a36592d2John McCall
4470c01d18094100db92d38daa923c95661512db203John McCall    // If the template names don't match, it can't be a dependent
4480c01d18094100db92d38daa923c95661512db203John McCall    // match.  This isn't true in C++0x because of template aliases.
4490c01d18094100db92d38daa923c95661512db203John McCall    if (!S.LangOpts.CPlusPlus0x && CTD->getDeclName() != Friend->getDeclName())
4500c01d18094100db92d38daa923c95661512db203John McCall      continue;
4510c01d18094100db92d38daa923c95661512db203John McCall
4520c01d18094100db92d38daa923c95661512db203John McCall    // If the class's context can't instantiate to the friend's
4530c01d18094100db92d38daa923c95661512db203John McCall    // context, it can't be a dependent match.
4540c01d18094100db92d38daa923c95661512db203John McCall    if (!MightInstantiateTo(S, CTD->getDeclContext(),
4550c01d18094100db92d38daa923c95661512db203John McCall                            Friend->getDeclContext()))
4560c01d18094100db92d38daa923c95661512db203John McCall      continue;
4570c01d18094100db92d38daa923c95661512db203John McCall
4580c01d18094100db92d38daa923c95661512db203John McCall    // Otherwise, it's a dependent match.
459161755a09898c95d21bfff33707da9ca41cd53c5John McCall    OnFailure = AR_dependent;
460a742db0032d8f458fe229600d2082981a1fb1481John McCall  }
461a742db0032d8f458fe229600d2082981a1fb1481John McCall
4620c01d18094100db92d38daa923c95661512db203John McCall  return OnFailure;
4630c01d18094100db92d38daa923c95661512db203John McCall}
464a742db0032d8f458fe229600d2082981a1fb1481John McCall
4650c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend function matches anything in
4660c01d18094100db92d38daa923c95661512db203John McCall/// the effective context.
467161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
468161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
469161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  FunctionDecl *Friend) {
470161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
471a742db0032d8f458fe229600d2082981a1fb1481John McCall
4722cc2675d426af23476a9722c08c1b6c5266bd653John McCall  for (llvm::SmallVectorImpl<FunctionDecl*>::const_iterator
4732cc2675d426af23476a9722c08c1b6c5266bd653John McCall         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
4742cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (Friend == *I)
475161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
4760c01d18094100db92d38daa923c95661512db203John McCall
4772cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
478161755a09898c95d21bfff33707da9ca41cd53c5John McCall      OnFailure = AR_dependent;
4792cc2675d426af23476a9722c08c1b6c5266bd653John McCall  }
4800c01d18094100db92d38daa923c95661512db203John McCall
4812cc2675d426af23476a9722c08c1b6c5266bd653John McCall  return OnFailure;
4820c01d18094100db92d38daa923c95661512db203John McCall}
4830c01d18094100db92d38daa923c95661512db203John McCall
4840c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend function template matches
4850c01d18094100db92d38daa923c95661512db203John McCall/// anything in the effective context.
486161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
487161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
488161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  FunctionTemplateDecl *Friend) {
489161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (EC.Functions.empty()) return AR_inaccessible;
4902cc2675d426af23476a9722c08c1b6c5266bd653John McCall
491161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
4920c01d18094100db92d38daa923c95661512db203John McCall
4932cc2675d426af23476a9722c08c1b6c5266bd653John McCall  for (llvm::SmallVectorImpl<FunctionDecl*>::const_iterator
4942cc2675d426af23476a9722c08c1b6c5266bd653John McCall         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
495a742db0032d8f458fe229600d2082981a1fb1481John McCall
4962cc2675d426af23476a9722c08c1b6c5266bd653John McCall    FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
4972cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (!FTD)
4982cc2675d426af23476a9722c08c1b6c5266bd653John McCall      FTD = (*I)->getDescribedFunctionTemplate();
4992cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (!FTD)
5002cc2675d426af23476a9722c08c1b6c5266bd653John McCall      continue;
501a742db0032d8f458fe229600d2082981a1fb1481John McCall
5022cc2675d426af23476a9722c08c1b6c5266bd653John McCall    FTD = FTD->getCanonicalDecl();
503a742db0032d8f458fe229600d2082981a1fb1481John McCall
5042cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (Friend == FTD)
505161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
5062cc2675d426af23476a9722c08c1b6c5266bd653John McCall
5072cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
508161755a09898c95d21bfff33707da9ca41cd53c5John McCall      OnFailure = AR_dependent;
5092cc2675d426af23476a9722c08c1b6c5266bd653John McCall  }
5102cc2675d426af23476a9722c08c1b6c5266bd653John McCall
5112cc2675d426af23476a9722c08c1b6c5266bd653John McCall  return OnFailure;
512a742db0032d8f458fe229600d2082981a1fb1481John McCall}
513a742db0032d8f458fe229600d2082981a1fb1481John McCall
5140c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend declaration matches anything
5150c01d18094100db92d38daa923c95661512db203John McCall/// in the effective context.
516161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
517161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
518161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  FriendDecl *FriendD) {
5196102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  // Whitelist accesses if there's an invalid or unsupported friend
5206102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  // declaration.
5216102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend())
522337ec3d0e8cb24a591ecbecdc0a995a167f6af01John McCall    return AR_accessible;
523337ec3d0e8cb24a591ecbecdc0a995a167f6af01John McCall
52432f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  if (TypeSourceInfo *T = FriendD->getFriendType())
52532f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall    return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
5260c01d18094100db92d38daa923c95661512db203John McCall
5270c01d18094100db92d38daa923c95661512db203John McCall  NamedDecl *Friend
5280c01d18094100db92d38daa923c95661512db203John McCall    = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
5290c01d18094100db92d38daa923c95661512db203John McCall
5300c01d18094100db92d38daa923c95661512db203John McCall  // FIXME: declarations with dependent or templated scope.
5310c01d18094100db92d38daa923c95661512db203John McCall
5320c01d18094100db92d38daa923c95661512db203John McCall  if (isa<ClassTemplateDecl>(Friend))
5330c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
5340c01d18094100db92d38daa923c95661512db203John McCall
5350c01d18094100db92d38daa923c95661512db203John McCall  if (isa<FunctionTemplateDecl>(Friend))
5360c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
5370c01d18094100db92d38daa923c95661512db203John McCall
5380c01d18094100db92d38daa923c95661512db203John McCall  if (isa<CXXRecordDecl>(Friend))
5390c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
5400c01d18094100db92d38daa923c95661512db203John McCall
5410c01d18094100db92d38daa923c95661512db203John McCall  assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
5420c01d18094100db92d38daa923c95661512db203John McCall  return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
5430c01d18094100db92d38daa923c95661512db203John McCall}
5440c01d18094100db92d38daa923c95661512db203John McCall
545161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult GetFriendKind(Sema &S,
546161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
547161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const CXXRecordDecl *Class) {
548161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
54988b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall
550d60e22e601852ae1345f01514318a0951dc09f89John McCall  // Okay, check friends.
551d60e22e601852ae1345f01514318a0951dc09f89John McCall  for (CXXRecordDecl::friend_iterator I = Class->friend_begin(),
552d60e22e601852ae1345f01514318a0951dc09f89John McCall         E = Class->friend_end(); I != E; ++I) {
553d60e22e601852ae1345f01514318a0951dc09f89John McCall    FriendDecl *Friend = *I;
554d60e22e601852ae1345f01514318a0951dc09f89John McCall
555a742db0032d8f458fe229600d2082981a1fb1481John McCall    switch (MatchesFriend(S, EC, Friend)) {
556161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible:
557161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
55888b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall
559161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible:
560161755a09898c95d21bfff33707da9ca41cd53c5John McCall      continue;
561d60e22e601852ae1345f01514318a0951dc09f89John McCall
562161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
563161755a09898c95d21bfff33707da9ca41cd53c5John McCall      OnFailure = AR_dependent;
564a742db0032d8f458fe229600d2082981a1fb1481John McCall      break;
565a742db0032d8f458fe229600d2082981a1fb1481John McCall    }
566d60e22e601852ae1345f01514318a0951dc09f89John McCall  }
567d60e22e601852ae1345f01514318a0951dc09f89John McCall
568d60e22e601852ae1345f01514318a0951dc09f89John McCall  // That's it, give up.
56988b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall  return OnFailure;
5706b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
5716b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
5728c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCallnamespace {
5738c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
5748c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// A helper class for checking for a friend which will grant access
5758c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// to a protected instance member.
5768c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCallstruct ProtectedFriendContext {
5778c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  Sema &S;
5788c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  const EffectiveContext &EC;
5798c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  const CXXRecordDecl *NamingClass;
5808c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  bool CheckDependent;
5818c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  bool EverDependent;
5828c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
5838c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  /// The path down to the current base class.
5848c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  llvm::SmallVector<const CXXRecordDecl*, 20> CurPath;
5858c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
5868c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
5878c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                         const CXXRecordDecl *InstanceContext,
5888c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                         const CXXRecordDecl *NamingClass)
5898c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    : S(S), EC(EC), NamingClass(NamingClass),
5908c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      CheckDependent(InstanceContext->isDependentContext() ||
5918c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                     NamingClass->isDependentContext()),
5928c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      EverDependent(false) {}
5938c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
594326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  /// Check classes in the current path for friendship, starting at
595326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  /// the given index.
596326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  bool checkFriendshipAlongPath(unsigned I) {
597326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    assert(I < CurPath.size());
598326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    for (unsigned E = CurPath.size(); I != E; ++I) {
599326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      switch (GetFriendKind(S, EC, CurPath[I])) {
6008c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      case AR_accessible:   return true;
6018c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      case AR_inaccessible: continue;
6028c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      case AR_dependent:    EverDependent = true; continue;
6038c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      }
6048c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    }
6058c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    return false;
6068c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  }
6078c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6088c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  /// Perform a search starting at the given class.
609326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  ///
610326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  /// PrivateDepth is the index of the last (least derived) class
611326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  /// along the current path such that a notional public member of
612326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  /// the final class in the path would have access in that class.
613326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
6148c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    // If we ever reach the naming class, check the current path for
6158c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    // friendship.  We can also stop recursing because we obviously
6168c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    // won't find the naming class there again.
617326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    if (Cur == NamingClass)
618326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      return checkFriendshipAlongPath(PrivateDepth);
6198c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6208c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
6218c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      EverDependent = true;
6228c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6238c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    // Recurse into the base classes.
6248c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    for (CXXRecordDecl::base_class_const_iterator
6258c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall           I = Cur->bases_begin(), E = Cur->bases_end(); I != E; ++I) {
6268c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
627326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      // If this is private inheritance, then a public member of the
628326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      // base will not have any access in classes derived from Cur.
629326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      unsigned BasePrivateDepth = PrivateDepth;
630326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      if (I->getAccessSpecifier() == AS_private)
631326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall        BasePrivateDepth = CurPath.size() - 1;
6328c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6338c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      const CXXRecordDecl *RD;
6348c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6358c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      QualType T = I->getType();
6368c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      if (const RecordType *RT = T->getAs<RecordType>()) {
6378c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall        RD = cast<CXXRecordDecl>(RT->getDecl());
6388c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      } else if (const InjectedClassNameType *IT
6398c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                   = T->getAs<InjectedClassNameType>()) {
6408c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall        RD = IT->getDecl();
6418c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      } else {
6428c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall        assert(T->isDependentType() && "non-dependent base wasn't a record?");
6438c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall        EverDependent = true;
6448c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall        continue;
6458c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      }
6468c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6478c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      // Recurse.  We don't need to clean up if this returns true.
648326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      CurPath.push_back(RD);
649326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
650326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall        return true;
651326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      CurPath.pop_back();
6528c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    }
6538c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6548c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    return false;
6558c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  }
656326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall
657326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  bool findFriendship(const CXXRecordDecl *Cur) {
658326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    assert(CurPath.empty());
659326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    CurPath.push_back(Cur);
660326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    return findFriendship(Cur, 0);
661326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  }
6628c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall};
6638c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall}
6648c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6658c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// Search for a class P that EC is a friend of, under the constraint
6668c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///   InstanceContext <= P <= NamingClass
6678c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// and with the additional restriction that a protected member of
6688c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// NamingClass would have some natural access in P.
6698c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///
6708c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// That second condition isn't actually quite right: the condition in
6718c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// the standard is whether the target would have some natural access
6728c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// in P.  The difference is that the target might be more accessible
6738c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// along some path not passing through NamingClass.  Allowing that
6748c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// introduces two problems:
6758c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///   - It breaks encapsulation because you can suddenly access a
6768c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///     forbidden base class's members by subclassing it elsewhere.
6778c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///   - It makes access substantially harder to compute because it
6788c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///     breaks the hill-climbing algorithm: knowing that the target is
6798c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///     accessible in some base class would no longer let you change
6808c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///     the question solely to whether the base class is accessible,
6818c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///     because the original target might have been more accessible
6828c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///     because of crazy subclassing.
6838c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// So we don't implement that.
6848c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCallstatic AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
6858c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                                           const CXXRecordDecl *InstanceContext,
6868c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                                           const CXXRecordDecl *NamingClass) {
6878c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  assert(InstanceContext->getCanonicalDecl() == InstanceContext);
6888c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  assert(NamingClass->getCanonicalDecl() == NamingClass);
6898c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6908c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
6918c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  if (PRC.findFriendship(InstanceContext)) return AR_accessible;
6928c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  if (PRC.EverDependent) return AR_dependent;
6938c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  return AR_inaccessible;
6948c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall}
6958c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
696161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult HasAccess(Sema &S,
697161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              const EffectiveContext &EC,
698161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              const CXXRecordDecl *NamingClass,
699161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              AccessSpecifier Access,
700161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              const AccessTarget &Target) {
701db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(NamingClass->getCanonicalDecl() == NamingClass &&
702db73c684ba61fed4087af488e8610657ec638c17John McCall         "declaration should be canonicalized before being passed here");
703db73c684ba61fed4087af488e8610657ec638c17John McCall
704161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (Access == AS_public) return AR_accessible;
705db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(Access == AS_private || Access == AS_protected);
706db73c684ba61fed4087af488e8610657ec638c17John McCall
707161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
708161755a09898c95d21bfff33707da9ca41cd53c5John McCall
709db73c684ba61fed4087af488e8610657ec638c17John McCall  for (EffectiveContext::record_iterator
710db73c684ba61fed4087af488e8610657ec638c17John McCall         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
711db73c684ba61fed4087af488e8610657ec638c17John McCall    // All the declarations in EC have been canonicalized, so pointer
712db73c684ba61fed4087af488e8610657ec638c17John McCall    // equality from this point on will work fine.
713db73c684ba61fed4087af488e8610657ec638c17John McCall    const CXXRecordDecl *ECRecord = *I;
714db73c684ba61fed4087af488e8610657ec638c17John McCall
715db73c684ba61fed4087af488e8610657ec638c17John McCall    // [B2] and [M2]
716161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (Access == AS_private) {
717161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (ECRecord == NamingClass)
718161755a09898c95d21bfff33707da9ca41cd53c5John McCall        return AR_accessible;
719db73c684ba61fed4087af488e8610657ec638c17John McCall
72001ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall      if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
72101ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall        OnFailure = AR_dependent;
72201ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
723db73c684ba61fed4087af488e8610657ec638c17John McCall    // [B3] and [M3]
724161755a09898c95d21bfff33707da9ca41cd53c5John McCall    } else {
725161755a09898c95d21bfff33707da9ca41cd53c5John McCall      assert(Access == AS_protected);
726161755a09898c95d21bfff33707da9ca41cd53c5John McCall      switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
727161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_accessible: break;
728161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_inaccessible: continue;
729161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_dependent: OnFailure = AR_dependent; continue;
730161755a09898c95d21bfff33707da9ca41cd53c5John McCall      }
731161755a09898c95d21bfff33707da9ca41cd53c5John McCall
732161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (!Target.hasInstanceContext())
733161755a09898c95d21bfff33707da9ca41cd53c5John McCall        return AR_accessible;
734161755a09898c95d21bfff33707da9ca41cd53c5John McCall
735161755a09898c95d21bfff33707da9ca41cd53c5John McCall      const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
736161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (!InstanceContext) {
737161755a09898c95d21bfff33707da9ca41cd53c5John McCall        OnFailure = AR_dependent;
738161755a09898c95d21bfff33707da9ca41cd53c5John McCall        continue;
739161755a09898c95d21bfff33707da9ca41cd53c5John McCall      }
740161755a09898c95d21bfff33707da9ca41cd53c5John McCall
741161755a09898c95d21bfff33707da9ca41cd53c5John McCall      // C++ [class.protected]p1:
742161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   An additional access check beyond those described earlier in
743161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   [class.access] is applied when a non-static data member or
744161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   non-static member function is a protected member of its naming
745161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   class.  As described earlier, access to a protected member is
746161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   granted because the reference occurs in a friend or member of
747161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   some class C.  If the access is to form a pointer to member,
748161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   the nested-name-specifier shall name C or a class derived from
749161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   C. All other accesses involve a (possibly implicit) object
750161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   expression. In this case, the class of the object expression
751161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   shall be C or a class derived from C.
752161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //
753161755a09898c95d21bfff33707da9ca41cd53c5John McCall      // We interpret this as a restriction on [M3].  Most of the
754161755a09898c95d21bfff33707da9ca41cd53c5John McCall      // conditions are encoded by not having any instance context.
755161755a09898c95d21bfff33707da9ca41cd53c5John McCall      switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
756161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_accessible: return AR_accessible;
757161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_inaccessible: continue;
758161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_dependent: OnFailure = AR_dependent; continue;
759161755a09898c95d21bfff33707da9ca41cd53c5John McCall      }
760161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
761db73c684ba61fed4087af488e8610657ec638c17John McCall  }
762db73c684ba61fed4087af488e8610657ec638c17John McCall
7638c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // [M3] and [B3] say that, if the target is protected in N, we grant
7648c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // access if the access occurs in a friend or member of some class P
7658c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // that's a subclass of N and where the target has some natural
7668c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // access in P.  The 'member' aspect is easy to handle because P
7678c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // would necessarily be one of the effective-context records, and we
7688c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // address that above.  The 'friend' aspect is completely ridiculous
7698c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // to implement because there are no restrictions at all on P
7708c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // *unless* the [class.protected] restriction applies.  If it does,
7718c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // however, we should ignore whether the naming class is a friend,
7728c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // and instead rely on whether any potential P is a friend.
773161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (Access == AS_protected && Target.hasInstanceContext()) {
774161755a09898c95d21bfff33707da9ca41cd53c5John McCall    const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
775161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (!InstanceContext) return AR_dependent;
7768c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
7778c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    case AR_accessible: return AR_accessible;
778161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: return OnFailure;
779161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent: return AR_dependent;
780161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
7811797a05f97671d40929224ac030c8c16fe69938cJohn McCall    llvm_unreachable("impossible friendship kind");
782161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
783161755a09898c95d21bfff33707da9ca41cd53c5John McCall
784161755a09898c95d21bfff33707da9ca41cd53c5John McCall  switch (GetFriendKind(S, EC, NamingClass)) {
785161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_accessible: return AR_accessible;
786161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_inaccessible: return OnFailure;
787161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_dependent: return AR_dependent;
788161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
789161755a09898c95d21bfff33707da9ca41cd53c5John McCall
790161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // Silence bogus warnings
791161755a09898c95d21bfff33707da9ca41cd53c5John McCall  llvm_unreachable("impossible friendship kind");
792161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return OnFailure;
793db73c684ba61fed4087af488e8610657ec638c17John McCall}
794db73c684ba61fed4087af488e8610657ec638c17John McCall
7956b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Finds the best path from the naming class to the declaring class,
7966b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// taking friend declarations into account.
7976b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///
798db73c684ba61fed4087af488e8610657ec638c17John McCall/// C++0x [class.access.base]p5:
799db73c684ba61fed4087af488e8610657ec638c17John McCall///   A member m is accessible at the point R when named in class N if
800db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M1] m as a member of N is public, or
801db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M2] m as a member of N is private, and R occurs in a member or
802db73c684ba61fed4087af488e8610657ec638c17John McCall///        friend of class N, or
803db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M3] m as a member of N is protected, and R occurs in a member or
804db73c684ba61fed4087af488e8610657ec638c17John McCall///        friend of class N, or in a member or friend of a class P
805db73c684ba61fed4087af488e8610657ec638c17John McCall///        derived from N, where m as a member of P is public, private,
806db73c684ba61fed4087af488e8610657ec638c17John McCall///        or protected, or
807db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M4] there exists a base class B of N that is accessible at R, and
808db73c684ba61fed4087af488e8610657ec638c17John McCall///        m is accessible at R when named in class B.
809db73c684ba61fed4087af488e8610657ec638c17John McCall///
810db73c684ba61fed4087af488e8610657ec638c17John McCall/// C++0x [class.access.base]p4:
811db73c684ba61fed4087af488e8610657ec638c17John McCall///   A base class B of N is accessible at R, if
812db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B1] an invented public member of B would be a public member of N, or
813db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B2] R occurs in a member or friend of class N, and an invented public
814db73c684ba61fed4087af488e8610657ec638c17John McCall///        member of B would be a private or protected member of N, or
815db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B3] R occurs in a member or friend of a class P derived from N, and an
816db73c684ba61fed4087af488e8610657ec638c17John McCall///        invented public member of B would be a private or protected member
817db73c684ba61fed4087af488e8610657ec638c17John McCall///        of P, or
818db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B4] there exists a class S such that B is a base class of S accessible
819db73c684ba61fed4087af488e8610657ec638c17John McCall///        at R and S is a base class of N accessible at R.
820db73c684ba61fed4087af488e8610657ec638c17John McCall///
821db73c684ba61fed4087af488e8610657ec638c17John McCall/// Along a single inheritance path we can restate both of these
822db73c684ba61fed4087af488e8610657ec638c17John McCall/// iteratively:
823db73c684ba61fed4087af488e8610657ec638c17John McCall///
824db73c684ba61fed4087af488e8610657ec638c17John McCall/// First, we note that M1-4 are equivalent to B1-4 if the member is
825db73c684ba61fed4087af488e8610657ec638c17John McCall/// treated as a notional base of its declaring class with inheritance
826db73c684ba61fed4087af488e8610657ec638c17John McCall/// access equivalent to the member's access.  Therefore we need only
827db73c684ba61fed4087af488e8610657ec638c17John McCall/// ask whether a class B is accessible from a class N in context R.
828db73c684ba61fed4087af488e8610657ec638c17John McCall///
829db73c684ba61fed4087af488e8610657ec638c17John McCall/// Let B_1 .. B_n be the inheritance path in question (i.e. where
830db73c684ba61fed4087af488e8610657ec638c17John McCall/// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
831db73c684ba61fed4087af488e8610657ec638c17John McCall/// B_i).  For i in 1..n, we will calculate ACAB(i), the access to the
832db73c684ba61fed4087af488e8610657ec638c17John McCall/// closest accessible base in the path:
833db73c684ba61fed4087af488e8610657ec638c17John McCall///   Access(a, b) = (* access on the base specifier from a to b *)
834db73c684ba61fed4087af488e8610657ec638c17John McCall///   Merge(a, forbidden) = forbidden
835db73c684ba61fed4087af488e8610657ec638c17John McCall///   Merge(a, private) = forbidden
836db73c684ba61fed4087af488e8610657ec638c17John McCall///   Merge(a, b) = min(a,b)
837db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, forbidden) = false
838db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, private) = (R is c) || IsFriend(c, R)
839db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
840db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, public) = true
841db73c684ba61fed4087af488e8610657ec638c17John McCall///   ACAB(n) = public
842db73c684ba61fed4087af488e8610657ec638c17John McCall///   ACAB(i) =
843db73c684ba61fed4087af488e8610657ec638c17John McCall///     let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
844db73c684ba61fed4087af488e8610657ec638c17John McCall///     if Accessible(B_i, AccessToBase) then public else AccessToBase
845db73c684ba61fed4087af488e8610657ec638c17John McCall///
846db73c684ba61fed4087af488e8610657ec638c17John McCall/// B is an accessible base of N at R iff ACAB(1) = public.
847db73c684ba61fed4087af488e8610657ec638c17John McCall///
848161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// \param FinalAccess the access of the "final step", or AS_public if
8497aceaf8cee77c98478e8934dc283910292711a7eJohn McCall///   there is no final step.
8506b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \return null if friendship is dependent
8516b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstatic CXXBasePath *FindBestPath(Sema &S,
8526b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                 const EffectiveContext &EC,
853161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 AccessTarget &Target,
8547aceaf8cee77c98478e8934dc283910292711a7eJohn McCall                                 AccessSpecifier FinalAccess,
8556b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                 CXXBasePaths &Paths) {
8566b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // Derive the paths to the desired base.
857161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *Derived = Target.getNamingClass();
858161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *Base = Target.getDeclaringClass();
859161755a09898c95d21bfff33707da9ca41cd53c5John McCall
860161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // FIXME: fail correctly when there are dependent paths.
861161755a09898c95d21bfff33707da9ca41cd53c5John McCall  bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
862161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                          Paths);
8636b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  assert(isDerived && "derived class not actually derived from base");
8646b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  (void) isDerived;
8656b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
8666b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXBasePath *BestPath = 0;
8676b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
8687aceaf8cee77c98478e8934dc283910292711a7eJohn McCall  assert(FinalAccess != AS_none && "forbidden access after declaring class");
8697aceaf8cee77c98478e8934dc283910292711a7eJohn McCall
8700c01d18094100db92d38daa923c95661512db203John McCall  bool AnyDependent = false;
8710c01d18094100db92d38daa923c95661512db203John McCall
8726b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // Derive the friend-modified access along each path.
8736b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
8746b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall         PI != PE; ++PI) {
875161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
8766b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
8776b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // Walk through the path backwards.
8787aceaf8cee77c98478e8934dc283910292711a7eJohn McCall    AccessSpecifier PathAccess = FinalAccess;
8796b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    CXXBasePath::iterator I = PI->end(), E = PI->begin();
8806b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    while (I != E) {
8816b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      --I;
8826b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
8837aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      assert(PathAccess != AS_none);
8847aceaf8cee77c98478e8934dc283910292711a7eJohn McCall
8857aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      // If the declaration is a private member of a base class, there
8867aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      // is no level of friendship in derived classes that can make it
8877aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      // accessible.
8887aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      if (PathAccess == AS_private) {
8897aceaf8cee77c98478e8934dc283910292711a7eJohn McCall        PathAccess = AS_none;
8907aceaf8cee77c98478e8934dc283910292711a7eJohn McCall        break;
8917aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      }
8927aceaf8cee77c98478e8934dc283910292711a7eJohn McCall
893161755a09898c95d21bfff33707da9ca41cd53c5John McCall      const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
894161755a09898c95d21bfff33707da9ca41cd53c5John McCall
8956b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
896db73c684ba61fed4087af488e8610657ec638c17John McCall      PathAccess = std::max(PathAccess, BaseAccess);
897161755a09898c95d21bfff33707da9ca41cd53c5John McCall
898161755a09898c95d21bfff33707da9ca41cd53c5John McCall      switch (HasAccess(S, EC, NC, PathAccess, Target)) {
899161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_inaccessible: break;
900161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_accessible:
901161755a09898c95d21bfff33707da9ca41cd53c5John McCall        PathAccess = AS_public;
902161755a09898c95d21bfff33707da9ca41cd53c5John McCall
903161755a09898c95d21bfff33707da9ca41cd53c5John McCall        // Future tests are not against members and so do not have
904161755a09898c95d21bfff33707da9ca41cd53c5John McCall        // instance context.
905161755a09898c95d21bfff33707da9ca41cd53c5John McCall        Target.suppressInstanceContext();
906161755a09898c95d21bfff33707da9ca41cd53c5John McCall        break;
907161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_dependent:
908db73c684ba61fed4087af488e8610657ec638c17John McCall        AnyDependent = true;
909db73c684ba61fed4087af488e8610657ec638c17John McCall        goto Next;
910c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson      }
911c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson    }
912726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
9136b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // Note that we modify the path's Access field to the
9146b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // friend-modified access.
9156b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    if (BestPath == 0 || PathAccess < BestPath->Access) {
9166b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      BestPath = &*PI;
9176b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      BestPath->Access = PathAccess;
9180c01d18094100db92d38daa923c95661512db203John McCall
9190c01d18094100db92d38daa923c95661512db203John McCall      // Short-circuit if we found a public path.
9200c01d18094100db92d38daa923c95661512db203John McCall      if (BestPath->Access == AS_public)
9210c01d18094100db92d38daa923c95661512db203John McCall        return BestPath;
922c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson    }
9230c01d18094100db92d38daa923c95661512db203John McCall
9240c01d18094100db92d38daa923c95661512db203John McCall  Next: ;
925c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson  }
926c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson
9270c01d18094100db92d38daa923c95661512db203John McCall  assert((!BestPath || BestPath->Access != AS_public) &&
9280c01d18094100db92d38daa923c95661512db203John McCall         "fell out of loop with public path");
9290c01d18094100db92d38daa923c95661512db203John McCall
9300c01d18094100db92d38daa923c95661512db203John McCall  // We didn't find a public path, but at least one path was subject
9310c01d18094100db92d38daa923c95661512db203John McCall  // to dependent friendship, so delay the check.
9320c01d18094100db92d38daa923c95661512db203John McCall  if (AnyDependent)
9330c01d18094100db92d38daa923c95661512db203John McCall    return 0;
9340c01d18094100db92d38daa923c95661512db203John McCall
9356b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  return BestPath;
936726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl}
937726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
938fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall/// Given that an entity has protected natural access, check whether
939fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall/// access might be denied because of the protected member access
940fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall/// restriction.
941fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall///
942fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall/// \return true if a note was emitted
943fe24e05a87e48fa3318b65d1a92c542107639fd9John McCallstatic bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
944fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall                                       AccessTarget &Target) {
945fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  // Only applies to instance accesses.
946fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  if (!Target.hasInstanceContext())
947fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    return false;
948fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  assert(Target.isMemberAccess());
949fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  NamedDecl *D = Target.getTargetDecl();
950fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
951fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  const CXXRecordDecl *DeclaringClass = Target.getDeclaringClass();
952fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  DeclaringClass = DeclaringClass->getCanonicalDecl();
953fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
954fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  for (EffectiveContext::record_iterator
955fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
956fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    const CXXRecordDecl *ECRecord = *I;
957fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    switch (IsDerivedFromInclusive(ECRecord, DeclaringClass)) {
958fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_accessible: break;
959fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_inaccessible: continue;
960fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_dependent: continue;
961fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    }
962fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
963fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    // The effective context is a subclass of the declaring class.
964fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    // If that class isn't a superclass of the instance context,
965fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    // then the [class.protected] restriction applies.
966fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
967fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    // To get this exactly right, this might need to be checked more
968fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    // holistically;  it's not necessarily the case that gaining
969fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    // access here would grant us access overall.
970fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
971fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
972fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    assert(InstanceContext && "diagnosing dependent access");
973fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
974fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
975fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_accessible: continue;
976fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_dependent: continue;
977fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_inaccessible:
978fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall      S.Diag(D->getLocation(), diag::note_access_protected_restricted)
979fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall        << (InstanceContext != Target.getNamingClass()->getCanonicalDecl())
980fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall        << S.Context.getTypeDeclType(InstanceContext)
981fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall        << S.Context.getTypeDeclType(ECRecord);
982fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall      return true;
983fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    }
984fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  }
985fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
986fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  return false;
987fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall}
988fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
9896b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Diagnose the path which caused the given declaration or base class
9906b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// to become inaccessible.
9916b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstatic void DiagnoseAccessPath(Sema &S,
9926b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                               const EffectiveContext &EC,
993161755a09898c95d21bfff33707da9ca41cd53c5John McCall                               AccessTarget &Entity) {
994db73c684ba61fed4087af488e8610657ec638c17John McCall  AccessSpecifier Access = Entity.getAccess();
995161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
996db73c684ba61fed4087af488e8610657ec638c17John McCall  NamingClass = NamingClass->getCanonicalDecl();
997db73c684ba61fed4087af488e8610657ec638c17John McCall
998161755a09898c95d21bfff33707da9ca41cd53c5John McCall  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);
999161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1000db73c684ba61fed4087af488e8610657ec638c17John McCall
10016b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // Easy case: the decl's natural access determined its path access.
10026b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // We have to check against AS_private here in case Access is AS_none,
10036b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // indicating a non-public member of a private base class.
10046b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (D && (Access == D->getAccess() || D->getAccess() == AS_private)) {
1005161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (HasAccess(S, EC, DeclaringClass, D->getAccess(), Entity)) {
1006161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: {
1007fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall      if (Access == AS_protected &&
1008fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall          TryDiagnoseProtectedAccess(S, EC, Entity))
1009fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall        return;
1010fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
1011aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      // Find an original declaration.
1012aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      while (D->isOutOfLine()) {
1013aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        NamedDecl *PrevDecl = 0;
1014162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        if (VarDecl *VD = dyn_cast<VarDecl>(D))
1015162e1c1b487352434552147967c3dd296ebee2f7Richard Smith          PrevDecl = VD->getPreviousDeclaration();
1016162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1017162e1c1b487352434552147967c3dd296ebee2f7Richard Smith          PrevDecl = FD->getPreviousDeclaration();
1018162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
1019162e1c1b487352434552147967c3dd296ebee2f7Richard Smith          PrevDecl = TND->getPreviousDeclaration();
1020162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
1021aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall          if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1022aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall            break;
1023162e1c1b487352434552147967c3dd296ebee2f7Richard Smith          PrevDecl = TD->getPreviousDeclaration();
1024aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        }
1025aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        if (!PrevDecl) break;
1026aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        D = PrevDecl;
1027aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      }
1028aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall
1029aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
1030aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      Decl *ImmediateChild;
1031aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      if (D->getDeclContext() == DeclaringClass)
1032aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        ImmediateChild = D;
1033aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      else {
1034aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        DeclContext *DC = D->getDeclContext();
1035aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        while (DC->getParent() != DeclaringClass)
1036aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall          DC = DC->getParent();
1037aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        ImmediateChild = cast<Decl>(DC);
1038aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      }
1039aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall
1040aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      // Check whether there's an AccessSpecDecl preceding this in the
1041aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      // chain of the DeclContext.
1042aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      bool Implicit = true;
1043aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      for (CXXRecordDecl::decl_iterator
1044aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall             I = DeclaringClass->decls_begin(), E = DeclaringClass->decls_end();
1045aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall           I != E; ++I) {
1046aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        if (*I == ImmediateChild) break;
1047aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        if (isa<AccessSpecDecl>(*I)) {
1048aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall          Implicit = false;
1049aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall          break;
1050aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        }
1051aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall      }
1052aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall
10536b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      S.Diag(D->getLocation(), diag::note_access_natural)
10546b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall        << (unsigned) (Access == AS_protected)
1055aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall        << Implicit;
10566b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      return;
10576b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
1058726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
1059161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible: break;
1060726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
1061161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
1062161755a09898c95d21bfff33707da9ca41cd53c5John McCall      llvm_unreachable("can't diagnose dependent access failures");
10636b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      return;
10646b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
10656b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
1066c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson
10676b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXBasePaths Paths;
1068161755a09898c95d21bfff33707da9ca41cd53c5John McCall  CXXBasePath &Path = *FindBestPath(S, EC, Entity, AS_public, Paths);
1069726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
10706b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXBasePath::iterator I = Path.end(), E = Path.begin();
10716b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  while (I != E) {
10726b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    --I;
1073c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson
10746b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    const CXXBaseSpecifier *BS = I->Base;
10756b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    AccessSpecifier BaseAccess = BS->getAccessSpecifier();
10766b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
10776b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // If this is public inheritance, or the derived class is a friend,
10786b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // skip this step.
10796b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    if (BaseAccess == AS_public)
10806b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      continue;
10816b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
10826b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    switch (GetFriendKind(S, EC, I->Class)) {
1083161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible: continue;
1084161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: break;
1085161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
1086161755a09898c95d21bfff33707da9ca41cd53c5John McCall      llvm_unreachable("can't diagnose dependent access failures");
10876b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
10886b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
10896b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // Check whether this base specifier is the tighest point
10906b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // constraining access.  We have to check against AS_private for
10916b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // the same reasons as above.
10926b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    if (BaseAccess == AS_private || BaseAccess >= Access) {
10936b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
10946b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      // We're constrained by inheritance, but we want to say
10956b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      // "declared private here" if we're diagnosing a hierarchy
10966b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      // conversion and this is the final step.
10976b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      unsigned diagnostic;
10986b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      if (D) diagnostic = diag::note_access_constrained_by_path;
10996b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      else if (I + 1 == Path.end()) diagnostic = diag::note_access_natural;
11006b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      else diagnostic = diag::note_access_constrained_by_path;
11016b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
11026b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      S.Diag(BS->getSourceRange().getBegin(), diagnostic)
11036b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall        << BS->getSourceRange()
11046b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall        << (BaseAccess == AS_protected)
11056b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall        << (BS->getAccessSpecifierAsWritten() == AS_none);
110676ef658c703faf72c00f324fb9edc03169718e3eDouglas Gregor
110776ef658c703faf72c00f324fb9edc03169718e3eDouglas Gregor      if (D)
110876ef658c703faf72c00f324fb9edc03169718e3eDouglas Gregor        S.Diag(D->getLocation(), diag::note_field_decl);
110976ef658c703faf72c00f324fb9edc03169718e3eDouglas Gregor
11106b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      return;
11116b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
1112c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson  }
1113726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
11146b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  llvm_unreachable("access not apparently constrained by path");
111529f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson}
111692f883177b162928a8e632e4e3b93fafd2b26072John McCall
1117db73c684ba61fed4087af488e8610657ec638c17John McCallstatic void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
1118db73c684ba61fed4087af488e8610657ec638c17John McCall                              const EffectiveContext &EC,
1119161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              AccessTarget &Entity) {
1120db73c684ba61fed4087af488e8610657ec638c17John McCall  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
1121161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1122161755a09898c95d21bfff33707da9ca41cd53c5John McCall  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);
11236b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
112458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  S.Diag(Loc, Entity.getDiag())
1125db73c684ba61fed4087af488e8610657ec638c17John McCall    << (Entity.getAccess() == AS_protected)
1126db73c684ba61fed4087af488e8610657ec638c17John McCall    << (D ? D->getDeclName() : DeclarationName())
112758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << S.Context.getTypeDeclType(NamingClass)
112858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << S.Context.getTypeDeclType(DeclaringClass);
1129db73c684ba61fed4087af488e8610657ec638c17John McCall  DiagnoseAccessPath(S, EC, Entity);
11306b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
113192f883177b162928a8e632e4e3b93fafd2b26072John McCall
1132db73c684ba61fed4087af488e8610657ec638c17John McCall/// Determines whether the accessed entity is accessible.  Public members
1133db73c684ba61fed4087af488e8610657ec638c17John McCall/// have been weeded out by this point.
1134161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult IsAccessible(Sema &S,
1135161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 const EffectiveContext &EC,
1136161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 AccessTarget &Entity) {
1137db73c684ba61fed4087af488e8610657ec638c17John McCall  // Determine the actual naming class.
1138db73c684ba61fed4087af488e8610657ec638c17John McCall  CXXRecordDecl *NamingClass = Entity.getNamingClass();
1139db73c684ba61fed4087af488e8610657ec638c17John McCall  while (NamingClass->isAnonymousStructOrUnion())
1140db73c684ba61fed4087af488e8610657ec638c17John McCall    NamingClass = cast<CXXRecordDecl>(NamingClass->getParent());
1141db73c684ba61fed4087af488e8610657ec638c17John McCall  NamingClass = NamingClass->getCanonicalDecl();
114292f883177b162928a8e632e4e3b93fafd2b26072John McCall
1143db73c684ba61fed4087af488e8610657ec638c17John McCall  AccessSpecifier UnprivilegedAccess = Entity.getAccess();
1144db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(UnprivilegedAccess != AS_public && "public access not weeded out");
114592f883177b162928a8e632e4e3b93fafd2b26072John McCall
1146db73c684ba61fed4087af488e8610657ec638c17John McCall  // Before we try to recalculate access paths, try to white-list
1147db73c684ba61fed4087af488e8610657ec638c17John McCall  // accesses which just trade in on the final step, i.e. accesses
1148db73c684ba61fed4087af488e8610657ec638c17John McCall  // which don't require [M4] or [B4]. These are by far the most
1149161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // common forms of privileged access.
1150db73c684ba61fed4087af488e8610657ec638c17John McCall  if (UnprivilegedAccess != AS_none) {
1151161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1152161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
1153db73c684ba61fed4087af488e8610657ec638c17John McCall      // This is actually an interesting policy decision.  We don't
1154db73c684ba61fed4087af488e8610657ec638c17John McCall      // *have* to delay immediately here: we can do the full access
1155db73c684ba61fed4087af488e8610657ec638c17John McCall      // calculation in the hope that friendship on some intermediate
1156db73c684ba61fed4087af488e8610657ec638c17John McCall      // class will make the declaration accessible non-dependently.
1157db73c684ba61fed4087af488e8610657ec638c17John McCall      // But that's not cheap, and odds are very good (note: assertion
1158db73c684ba61fed4087af488e8610657ec638c17John McCall      // made without data) that the friend declaration will determine
1159db73c684ba61fed4087af488e8610657ec638c17John McCall      // access.
1160161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_dependent;
1161db73c684ba61fed4087af488e8610657ec638c17John McCall
1162161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible: return AR_accessible;
1163161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: break;
1164db73c684ba61fed4087af488e8610657ec638c17John McCall    }
1165db73c684ba61fed4087af488e8610657ec638c17John McCall  }
116692f883177b162928a8e632e4e3b93fafd2b26072John McCall
1167161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1168db73c684ba61fed4087af488e8610657ec638c17John McCall
1169db73c684ba61fed4087af488e8610657ec638c17John McCall  // We lower member accesses to base accesses by pretending that the
1170db73c684ba61fed4087af488e8610657ec638c17John McCall  // member is a base class of its declaring class.
1171db73c684ba61fed4087af488e8610657ec638c17John McCall  AccessSpecifier FinalAccess;
11726b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
11736b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (Entity.isMemberAccess()) {
1174db73c684ba61fed4087af488e8610657ec638c17John McCall    // Determine if the declaration is accessible from EC when named
1175db73c684ba61fed4087af488e8610657ec638c17John McCall    // in its declaring class.
11766b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    NamedDecl *Target = Entity.getTargetDecl();
1177161755a09898c95d21bfff33707da9ca41cd53c5John McCall    const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
11786b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1179db73c684ba61fed4087af488e8610657ec638c17John McCall    FinalAccess = Target->getAccess();
1180161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1181161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible:
1182161755a09898c95d21bfff33707da9ca41cd53c5John McCall      FinalAccess = AS_public;
1183161755a09898c95d21bfff33707da9ca41cd53c5John McCall      break;
1184161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: break;
1185161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent: return AR_dependent; // see above
11866b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
11872f514480c448708ec382a684cf5e035d3a827ec8John McCall
1188db73c684ba61fed4087af488e8610657ec638c17John McCall    if (DeclaringClass == NamingClass)
1189161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
1190161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1191161755a09898c95d21bfff33707da9ca41cd53c5John McCall    Entity.suppressInstanceContext();
1192db73c684ba61fed4087af488e8610657ec638c17John McCall  } else {
1193db73c684ba61fed4087af488e8610657ec638c17John McCall    FinalAccess = AS_public;
11946b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
11952f514480c448708ec382a684cf5e035d3a827ec8John McCall
1196161755a09898c95d21bfff33707da9ca41cd53c5John McCall  assert(Entity.getDeclaringClass() != NamingClass);
11976b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
11986b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // Append the declaration's access if applicable.
11996b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXBasePaths Paths;
1200161755a09898c95d21bfff33707da9ca41cd53c5John McCall  CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
12010c01d18094100db92d38daa923c95661512db203John McCall  if (!Path)
1202161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_dependent;
120392f883177b162928a8e632e4e3b93fafd2b26072John McCall
1204db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(Path->Access <= UnprivilegedAccess &&
1205db73c684ba61fed4087af488e8610657ec638c17John McCall         "access along best path worse than direct?");
1206db73c684ba61fed4087af488e8610657ec638c17John McCall  if (Path->Access == AS_public)
1207161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_accessible;
1208161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return AR_inaccessible;
12090c01d18094100db92d38daa923c95661512db203John McCall}
12100c01d18094100db92d38daa923c95661512db203John McCall
1211161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic void DelayDependentAccess(Sema &S,
1212161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 const EffectiveContext &EC,
1213161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 SourceLocation Loc,
1214161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 const AccessTarget &Entity) {
12150c01d18094100db92d38daa923c95661512db203John McCall  assert(EC.isDependent() && "delaying non-dependent access");
12167ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  DeclContext *DC = EC.getInnerContext();
12170c01d18094100db92d38daa923c95661512db203John McCall  assert(DC->isDependentContext() && "delaying non-dependent access");
12180c01d18094100db92d38daa923c95661512db203John McCall  DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access,
12190c01d18094100db92d38daa923c95661512db203John McCall                              Loc,
12200c01d18094100db92d38daa923c95661512db203John McCall                              Entity.isMemberAccess(),
12210c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getAccess(),
12220c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getTargetDecl(),
12230c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getNamingClass(),
1224161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              Entity.getBaseObjectType(),
12250c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getDiag());
12266b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
12276b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
12286b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Checks access to an entity from the given effective context.
1229161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult CheckEffectiveAccess(Sema &S,
1230161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                         const EffectiveContext &EC,
1231161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                         SourceLocation Loc,
1232161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                         AccessTarget &Entity) {
1233db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(Entity.getAccess() != AS_public && "called for public access!");
123492f883177b162928a8e632e4e3b93fafd2b26072John McCall
1235db73c684ba61fed4087af488e8610657ec638c17John McCall  switch (IsAccessible(S, EC, Entity)) {
1236161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_dependent:
1237161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DelayDependentAccess(S, EC, Loc, Entity);
1238161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_dependent;
12390c01d18094100db92d38daa923c95661512db203John McCall
1240161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_inaccessible:
1241db73c684ba61fed4087af488e8610657ec638c17John McCall    if (!Entity.isQuiet())
1242db73c684ba61fed4087af488e8610657ec638c17John McCall      DiagnoseBadAccess(S, Loc, EC, Entity);
1243161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_inaccessible;
124492f883177b162928a8e632e4e3b93fafd2b26072John McCall
1245161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_accessible:
1246161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_accessible;
1247db73c684ba61fed4087af488e8610657ec638c17John McCall  }
1248db73c684ba61fed4087af488e8610657ec638c17John McCall
1249161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // silence unnecessary warning
1250161755a09898c95d21bfff33707da9ca41cd53c5John McCall  llvm_unreachable("invalid access result");
1251161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return AR_accessible;
12526b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
125392f883177b162928a8e632e4e3b93fafd2b26072John McCall
12546b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstatic Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
1255161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                      AccessTarget &Entity) {
12566b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // If the access path is public, it's accessible everywhere.
12576b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (Entity.getAccess() == AS_public)
12586b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return Sema::AR_accessible;
125992f883177b162928a8e632e4e3b93fafd2b26072John McCall
1260926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  if (S.SuppressAccessChecking)
1261926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth    return Sema::AR_accessible;
1262926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
1263eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If we're currently parsing a declaration, we may need to delay
1264eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // access control checking, because our effective context might be
1265eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // different based on what the declaration comes out as.
1266eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  //
1267eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // For example, we might be parsing a declaration with a scope
1268eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // specifier, like this:
1269eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  //   A::private_type A::foo() { ... }
1270eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  //
1271eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Or we might be parsing something that will turn out to be a friend:
1272eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  //   void foo(A::private_type);
1273eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  //   void B::foo(A::private_type);
1274eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
1275eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
12766b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return Sema::AR_delayed;
127792f883177b162928a8e632e4e3b93fafd2b26072John McCall  }
127892f883177b162928a8e632e4e3b93fafd2b26072John McCall
1279161755a09898c95d21bfff33707da9ca41cd53c5John McCall  EffectiveContext EC(S.CurContext);
1280161755a09898c95d21bfff33707da9ca41cd53c5John McCall  switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
1281161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_accessible: return Sema::AR_accessible;
1282161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_inaccessible: return Sema::AR_inaccessible;
1283161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_dependent: return Sema::AR_dependent;
1284161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
1285161755a09898c95d21bfff33707da9ca41cd53c5John McCall  llvm_unreachable("falling off end");
1286161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return Sema::AR_accessible;
128792f883177b162928a8e632e4e3b93fafd2b26072John McCall}
128892f883177b162928a8e632e4e3b93fafd2b26072John McCall
12894bfd680597862e437fcba739dce58531d0b15d6eJohn McCallvoid Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *decl) {
12904bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  // Access control for names used in the declarations of functions
12914bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  // and function templates should normally be evaluated in the context
12924bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  // of the declaration, just in case it's a friend of something.
12934bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  // However, this does not apply to local extern declarations.
12944bfd680597862e437fcba739dce58531d0b15d6eJohn McCall
12954bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  DeclContext *DC = decl->getDeclContext();
12964bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
12974bfd680597862e437fcba739dce58531d0b15d6eJohn McCall    if (!DC->isFunctionOrMethod()) DC = fn;
12984bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  } else if (FunctionTemplateDecl *fnt = dyn_cast<FunctionTemplateDecl>(decl)) {
12994bfd680597862e437fcba739dce58531d0b15d6eJohn McCall    // Never a local declaration.
13004bfd680597862e437fcba739dce58531d0b15d6eJohn McCall    DC = fnt->getTemplatedDecl();
13014bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  }
13024bfd680597862e437fcba739dce58531d0b15d6eJohn McCall
1303630eb01b2568d0958118eb1a0ded02bebecb2b0fChandler Carruth  EffectiveContext EC(DC);
13042f514480c448708ec382a684cf5e035d3a827ec8John McCall
1305161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Target(DD.getAccessData());
1306161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1307161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
13082f514480c448708ec382a684cf5e035d3a827ec8John McCall    DD.Triggered = true;
13092f514480c448708ec382a684cf5e035d3a827ec8John McCall}
13102f514480c448708ec382a684cf5e035d3a827ec8John McCall
13110c01d18094100db92d38daa923c95661512db203John McCallvoid Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD,
13120c01d18094100db92d38daa923c95661512db203John McCall                        const MultiLevelTemplateArgumentList &TemplateArgs) {
13130c01d18094100db92d38daa923c95661512db203John McCall  SourceLocation Loc = DD.getAccessLoc();
13140c01d18094100db92d38daa923c95661512db203John McCall  AccessSpecifier Access = DD.getAccess();
13150c01d18094100db92d38daa923c95661512db203John McCall
13160c01d18094100db92d38daa923c95661512db203John McCall  Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
13170c01d18094100db92d38daa923c95661512db203John McCall                                       TemplateArgs);
13180c01d18094100db92d38daa923c95661512db203John McCall  if (!NamingD) return;
13190c01d18094100db92d38daa923c95661512db203John McCall  Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
13200c01d18094100db92d38daa923c95661512db203John McCall                                       TemplateArgs);
13210c01d18094100db92d38daa923c95661512db203John McCall  if (!TargetD) return;
13220c01d18094100db92d38daa923c95661512db203John McCall
13230c01d18094100db92d38daa923c95661512db203John McCall  if (DD.isAccessToMember()) {
1324161755a09898c95d21bfff33707da9ca41cd53c5John McCall    CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
1325161755a09898c95d21bfff33707da9ca41cd53c5John McCall    NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1326161755a09898c95d21bfff33707da9ca41cd53c5John McCall    QualType BaseObjectType = DD.getAccessBaseObjectType();
1327161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (!BaseObjectType.isNull()) {
1328161755a09898c95d21bfff33707da9ca41cd53c5John McCall      BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1329161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 DeclarationName());
1330161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (BaseObjectType.isNull()) return;
1331161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
1332161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1333161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget Entity(Context,
1334161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        AccessTarget::Member,
1335161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        NamingClass,
1336161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        DeclAccessPair::make(TargetDecl, Access),
1337161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        BaseObjectType);
13380c01d18094100db92d38daa923c95661512db203John McCall    Entity.setDiag(DD.getDiagnostic());
13390c01d18094100db92d38daa923c95661512db203John McCall    CheckAccess(*this, Loc, Entity);
13400c01d18094100db92d38daa923c95661512db203John McCall  } else {
1341161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget Entity(Context,
1342161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        AccessTarget::Base,
1343161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        cast<CXXRecordDecl>(TargetD),
1344161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        cast<CXXRecordDecl>(NamingD),
1345161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        Access);
13460c01d18094100db92d38daa923c95661512db203John McCall    Entity.setDiag(DD.getDiagnostic());
13470c01d18094100db92d38daa923c95661512db203John McCall    CheckAccess(*this, Loc, Entity);
13480c01d18094100db92d38daa923c95661512db203John McCall  }
13490c01d18094100db92d38daa923c95661512db203John McCall}
13500c01d18094100db92d38daa923c95661512db203John McCall
13516b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
13529aa472c45d2bd81b7b52c225e8acc560d716db97John McCall                                                     DeclAccessPair Found) {
135358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  if (!getLangOptions().AccessControl ||
135458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall      !E->getNamingClass() ||
13559aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
13566b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
1357c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
1358161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1359161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      Found, QualType());
136058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(diag::err_access) << E->getSourceRange();
136158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
136258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, E->getNameLoc(), Entity);
1363c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall}
1364c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
1365c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall/// Perform access-control checking on a previously-unresolved member
1366c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall/// access which has now been resolved to a member.
13676b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
13689aa472c45d2bd81b7b52c225e8acc560d716db97John McCall                                                     DeclAccessPair Found) {
136958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  if (!getLangOptions().AccessControl ||
13709aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
13716b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
1372c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
1373161755a09898c95d21bfff33707da9ca41cd53c5John McCall  QualType BaseType = E->getBaseType();
1374161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (E->isArrow())
1375161755a09898c95d21bfff33707da9ca41cd53c5John McCall    BaseType = BaseType->getAs<PointerType>()->getPointeeType();
1376161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1377161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1378161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      Found, BaseType);
137958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(diag::err_access) << E->getSourceRange();
138058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
138158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, E->getMemberLoc(), Entity);
1382c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall}
1383c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
13846b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
138558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                               CXXDestructorDecl *Dtor,
138658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                               const PartialDiagnostic &PDiag) {
13874f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall  if (!getLangOptions().AccessControl)
13886b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
13894f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall
139058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // There's never a path involved when checking implicit destructor access.
13914f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall  AccessSpecifier Access = Dtor->getAccess();
13924f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall  if (Access == AS_public)
13936b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
13944f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall
139558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  CXXRecordDecl *NamingClass = Dtor->getParent();
1396161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1397161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      DeclAccessPair::make(Dtor, Access),
1398161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      QualType());
139958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(PDiag); // TODO: avoid copy
140058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
140158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, Loc, Entity);
14024f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall}
14034f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall
1404b13b737a2450167c82e148590e8019b839ce6b98John McCall/// Checks access to a constructor.
14056b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
140657d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                CXXConstructorDecl *Constructor,
140757d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                const InitializedEntity &Entity,
140857d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                AccessSpecifier Access,
140957d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                bool IsCopyBindingRefToTemp) {
141058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  if (!getLangOptions().AccessControl ||
141158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall      Access == AS_public)
14126b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
1413b13b737a2450167c82e148590e8019b839ce6b98John McCall
14146b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXRecordDecl *NamingClass = Constructor->getParent();
14159a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson  AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass,
14169a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson                            DeclAccessPair::make(Constructor, Access),
14179a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson                            QualType());
14189a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson  switch (Entity.getKind()) {
14199a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson  default:
142057d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin    AccessEntity.setDiag(IsCopyBindingRefToTemp
142157d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                         ? diag::ext_rvalue_to_reference_access_ctor
142257d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                         : diag::err_access_ctor);
14239a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson    break;
14249a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson
14253b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson  case InitializedEntity::EK_Base:
14263b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson    AccessEntity.setDiag(PDiag(diag::err_access_base)
14273b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson                          << Entity.isInheritedVirtualBase()
14283b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson                          << Entity.getBaseSpecifier()->getType()
14293b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson                          << getSpecialMember(Constructor));
14309a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson    break;
14313b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson
1432b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson  case InitializedEntity::EK_Member: {
1433b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson    const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
14340e313bd4795c005f23c43f127039fd948c3e0bd9Anders Carlsson    AccessEntity.setDiag(PDiag(diag::err_access_field)
14350e313bd4795c005f23c43f127039fd948c3e0bd9Anders Carlsson                          << Field->getType()
14360e313bd4795c005f23c43f127039fd948c3e0bd9Anders Carlsson                          << getSpecialMember(Constructor));
1437b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson    break;
1438b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson  }
143958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
1440711f34adb886cce8ba86c7b1b6513a1eaaf63bb5Anders Carlsson  }
1441711f34adb886cce8ba86c7b1b6513a1eaaf63bb5Anders Carlsson
14429a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson  return CheckAccess(*this, UseLoc, AccessEntity);
1443b13b737a2450167c82e148590e8019b839ce6b98John McCall}
1444b13b737a2450167c82e148590e8019b839ce6b98John McCall
1445b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall/// Checks direct (i.e. non-inherited) access to an arbitrary class
1446b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall/// member.
1447b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCallSema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc,
1448b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall                                                 NamedDecl *Target,
1449b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall                                           const PartialDiagnostic &Diag) {
1450b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall  AccessSpecifier Access = Target->getAccess();
1451b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall  if (!getLangOptions().AccessControl ||
1452b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall      Access == AS_public)
1453b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall    return AR_accessible;
1454b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall
1455b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Target->getDeclContext());
1456161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1457161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      DeclAccessPair::make(Target, Access),
1458161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      QualType());
1459b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall  Entity.setDiag(Diag);
1460b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall  return CheckAccess(*this, UseLoc, Entity);
1461b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall}
1462b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall
1463b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall
146490c8c57bcd84083df85f76aac2aa62acb85eb077John McCall/// Checks access to an overloaded operator new or delete.
146590c8c57bcd84083df85f76aac2aa62acb85eb077John McCallSema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
146690c8c57bcd84083df85f76aac2aa62acb85eb077John McCall                                               SourceRange PlacementRange,
146790c8c57bcd84083df85f76aac2aa62acb85eb077John McCall                                               CXXRecordDecl *NamingClass,
14689aa472c45d2bd81b7b52c225e8acc560d716db97John McCall                                               DeclAccessPair Found) {
146990c8c57bcd84083df85f76aac2aa62acb85eb077John McCall  if (!getLangOptions().AccessControl ||
147090c8c57bcd84083df85f76aac2aa62acb85eb077John McCall      !NamingClass ||
14719aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
147290c8c57bcd84083df85f76aac2aa62acb85eb077John McCall    return AR_accessible;
147390c8c57bcd84083df85f76aac2aa62acb85eb077John McCall
1474161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1475161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      QualType());
147690c8c57bcd84083df85f76aac2aa62acb85eb077John McCall  Entity.setDiag(diag::err_access)
147790c8c57bcd84083df85f76aac2aa62acb85eb077John McCall    << PlacementRange;
147890c8c57bcd84083df85f76aac2aa62acb85eb077John McCall
147990c8c57bcd84083df85f76aac2aa62acb85eb077John McCall  return CheckAccess(*this, OpLoc, Entity);
148090c8c57bcd84083df85f76aac2aa62acb85eb077John McCall}
148190c8c57bcd84083df85f76aac2aa62acb85eb077John McCall
1482b13b737a2450167c82e148590e8019b839ce6b98John McCall/// Checks access to an overloaded member operator, including
1483b13b737a2450167c82e148590e8019b839ce6b98John McCall/// conversion operators.
14846b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
14856b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                                   Expr *ObjectExpr,
148658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                                   Expr *ArgExpr,
14879aa472c45d2bd81b7b52c225e8acc560d716db97John McCall                                                   DeclAccessPair Found) {
148858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  if (!getLangOptions().AccessControl ||
14899aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
14906b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
14915357b615364c17ea024c757354c58ae2a520d216John McCall
14925357b615364c17ea024c757354c58ae2a520d216John McCall  const RecordType *RT = ObjectExpr->getType()->getAs<RecordType>();
14935357b615364c17ea024c757354c58ae2a520d216John McCall  assert(RT && "found member operator but object expr not of record type");
14945357b615364c17ea024c757354c58ae2a520d216John McCall  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
14955357b615364c17ea024c757354c58ae2a520d216John McCall
1496161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1497161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      ObjectExpr->getType());
149858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(diag::err_access)
149958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << ObjectExpr->getSourceRange()
150058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange());
150158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
150258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, OpLoc, Entity);
15036b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
15045357b615364c17ea024c757354c58ae2a520d216John McCall
15056bb8017bb9e828d118e15e59d71c66bba323c364John McCallSema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
15066bb8017bb9e828d118e15e59d71c66bba323c364John McCall                                                    DeclAccessPair Found) {
15076bb8017bb9e828d118e15e59d71c66bba323c364John McCall  if (!getLangOptions().AccessControl ||
1508e2f5ba9d80cfadbb3e1dafb9f375eb526f669b85John McCall      Found.getAccess() == AS_none ||
15096bb8017bb9e828d118e15e59d71c66bba323c364John McCall      Found.getAccess() == AS_public)
15106bb8017bb9e828d118e15e59d71c66bba323c364John McCall    return AR_accessible;
15116bb8017bb9e828d118e15e59d71c66bba323c364John McCall
15129c72c6088d591ace8503b842d39448c2040f3033John McCall  OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
1513e9ee23edd17c4bb7f271e67f8790792b4de677fcJohn McCall  CXXRecordDecl *NamingClass = Ovl->getNamingClass();
15146bb8017bb9e828d118e15e59d71c66bba323c364John McCall
1515161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1516161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      Context.getTypeDeclType(NamingClass));
15176bb8017bb9e828d118e15e59d71c66bba323c364John McCall  Entity.setDiag(diag::err_access)
15186bb8017bb9e828d118e15e59d71c66bba323c364John McCall    << Ovl->getSourceRange();
15196bb8017bb9e828d118e15e59d71c66bba323c364John McCall
15206bb8017bb9e828d118e15e59d71c66bba323c364John McCall  return CheckAccess(*this, Ovl->getNameLoc(), Entity);
15216bb8017bb9e828d118e15e59d71c66bba323c364John McCall}
15226bb8017bb9e828d118e15e59d71c66bba323c364John McCall
15236b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Checks access for a hierarchy conversion.
15246b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///
15256b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \param IsBaseToDerived whether this is a base-to-derived conversion (true)
15266b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///     or a derived-to-base conversion (false)
15276b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \param ForceCheck true if this check should be performed even if access
15286b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///     control is disabled;  some things rely on this for semantics
15296b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \param ForceUnprivileged true if this check should proceed as if the
15306b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///     context had no special privileges
15316b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \param ADK controls the kind of diagnostics that are used
15326b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
15336b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              QualType Base,
15346b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              QualType Derived,
15356b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              const CXXBasePath &Path,
153658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                              unsigned DiagID,
15376b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              bool ForceCheck,
153858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                              bool ForceUnprivileged) {
15396b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (!ForceCheck && !getLangOptions().AccessControl)
15406b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
15416b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
15426b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (Path.Access == AS_public)
15436b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
15446b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
15456b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXRecordDecl *BaseD, *DerivedD;
15466b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  BaseD = cast<CXXRecordDecl>(Base->getAs<RecordType>()->getDecl());
15476b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  DerivedD = cast<CXXRecordDecl>(Derived->getAs<RecordType>()->getDecl());
154858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
1549161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
1550161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      Path.Access);
155158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  if (DiagID)
155258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    Entity.setDiag(DiagID) << Derived << Base;
15536b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1554161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (ForceUnprivileged) {
1555161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (CheckEffectiveAccess(*this, EffectiveContext(),
1556161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 AccessLoc, Entity)) {
1557161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case ::AR_accessible: return Sema::AR_accessible;
1558161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case ::AR_inaccessible: return Sema::AR_inaccessible;
1559161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case ::AR_dependent: return Sema::AR_dependent;
1560161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
1561161755a09898c95d21bfff33707da9ca41cd53c5John McCall    llvm_unreachable("unexpected result from CheckEffectiveAccess");
1562161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
156358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, AccessLoc, Entity);
15645357b615364c17ea024c757354c58ae2a520d216John McCall}
15655357b615364c17ea024c757354c58ae2a520d216John McCall
156692f883177b162928a8e632e4e3b93fafd2b26072John McCall/// Checks access to all the declarations in the given result set.
15676b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallvoid Sema::CheckLookupAccess(const LookupResult &R) {
15686b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  assert(getLangOptions().AccessControl
15696b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall         && "performing access check without access control");
15706b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  assert(R.getNamingClass() && "performing access check without naming class");
15716b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
157258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
157358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    if (I.getAccess() != AS_public) {
1574161755a09898c95d21bfff33707da9ca41cd53c5John McCall      AccessTarget Entity(Context, AccessedEntity::Member,
1575161755a09898c95d21bfff33707da9ca41cd53c5John McCall                          R.getNamingClass(), I.getPair(),
1576161755a09898c95d21bfff33707da9ca41cd53c5John McCall                          R.getBaseObjectType());
157758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall      Entity.setDiag(diag::err_access);
157858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
157958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall      CheckAccess(*this, R.getNameLoc(), Entity);
158058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    }
158158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  }
158292f883177b162928a8e632e4e3b93fafd2b26072John McCall}
1583926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
1584926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruthvoid Sema::ActOnStartSuppressingAccessChecks() {
1585926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  assert(!SuppressAccessChecking &&
1586926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth         "Tried to start access check suppression when already started.");
1587926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  SuppressAccessChecking = true;
1588926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth}
1589926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
1590926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruthvoid Sema::ActOnStopSuppressingAccessChecks() {
1591926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  assert(SuppressAccessChecking &&
1592926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth         "Tried to stop access check suprression when already stopped.");
1593926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  SuppressAccessChecking = false;
1594926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth}
1595