SemaAccess.cpp revision 57d12fd4a2bc739c4a4d62a364b7f08cd483c59e
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
14c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson#include "Sema.h"
159a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson#include "SemaInit.h"
1692f883177b162928a8e632e4e3b93fafd2b26072John McCall#include "Lookup.h"
17c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson#include "clang/AST/ASTContext.h"
18a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor#include "clang/AST/CXXInheritance.h"
19a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor#include "clang/AST/DeclCXX.h"
20d60e22e601852ae1345f01514318a0951dc09f89John McCall#include "clang/AST/DeclFriend.h"
210c01d18094100db92d38daa923c95661512db203John McCall#include "clang/AST/DependentDiagnostic.h"
22c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall#include "clang/AST/ExprCXX.h"
23c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
24c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlssonusing namespace clang;
25c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson
26161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// A copy of Sema's enum without AR_delayed.
27161755a09898c95d21bfff33707da9ca41cd53c5John McCallenum AccessResult {
28161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AR_accessible,
29161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AR_inaccessible,
30161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AR_dependent
31161755a09898c95d21bfff33707da9ca41cd53c5John McCall};
32161755a09898c95d21bfff33707da9ca41cd53c5John McCall
3329f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson/// SetMemberAccessSpecifier - Set the access specifier of a member.
3429f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson/// Returns true on error (when the previous member decl access specifier
3529f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson/// is different from the new member decl access specifier).
361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpbool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
37c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson                                    NamedDecl *PrevMemberDecl,
38c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson                                    AccessSpecifier LexicalAS) {
39c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  if (!PrevMemberDecl) {
40c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    // Use the lexical access specifier.
41c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    MemberDecl->setAccess(LexicalAS);
42c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    return false;
43c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  }
441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
45c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  // C++ [class.access.spec]p3: When a member is redeclared its access
46c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  // specifier must be same as its initial declaration.
47c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Diag(MemberDecl->getLocation(),
491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump         diag::err_class_redeclared_with_different_access)
50c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson      << MemberDecl << LexicalAS;
51c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
52c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson      << PrevMemberDecl << PrevMemberDecl->getAccess();
5344e067bd8f923ba8e7c24b2189e06717d70015c8John McCall
5444e067bd8f923ba8e7c24b2189e06717d70015c8John McCall    MemberDecl->setAccess(LexicalAS);
55c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    return true;
56c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  }
571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
58c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  MemberDecl->setAccess(PrevMemberDecl->getAccess());
59c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  return false;
60c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson}
6129f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson
62161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic CXXRecordDecl *FindDeclaringClass(NamedDecl *D) {
63161755a09898c95d21bfff33707da9ca41cd53c5John McCall  DeclContext *DC = D->getDeclContext();
64161755a09898c95d21bfff33707da9ca41cd53c5John McCall
65161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // This can only happen at top: enum decls only "publish" their
66161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // immediate members.
67161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (isa<EnumDecl>(DC))
68161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DC = cast<EnumDecl>(DC)->getDeclContext();
69161755a09898c95d21bfff33707da9ca41cd53c5John McCall
70161755a09898c95d21bfff33707da9ca41cd53c5John McCall  CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
71161755a09898c95d21bfff33707da9ca41cd53c5John McCall  while (DeclaringClass->isAnonymousStructOrUnion())
72161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
73161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return DeclaringClass;
74161755a09898c95d21bfff33707da9ca41cd53c5John McCall}
75161755a09898c95d21bfff33707da9ca41cd53c5John McCall
766b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallnamespace {
776b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstruct EffectiveContext {
782cc2675d426af23476a9722c08c1b6c5266bd653John McCall  EffectiveContext() : Inner(0), Dependent(false) {}
796b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
807ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  explicit EffectiveContext(DeclContext *DC)
817ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall    : Inner(DC),
827ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall      Dependent(DC->isDependentContext()) {
830c01d18094100db92d38daa923c95661512db203John McCall
8488b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    // C++ [class.access.nest]p1:
8588b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    //   A nested class is a member and as such has the same access
8688b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    //   rights as any other member.
8788b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    // C++ [class.access]p2:
8888b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    //   A member of a class can also access all the names to which
892cc2675d426af23476a9722c08c1b6c5266bd653John McCall    //   the class has access.  A local class of a member function
902cc2675d426af23476a9722c08c1b6c5266bd653John McCall    //   may access the same names that the member function itself
912cc2675d426af23476a9722c08c1b6c5266bd653John McCall    //   may access.
922cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // This almost implies that the privileges of nesting are transitive.
932cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // Technically it says nothing about the local classes of non-member
942cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // functions (which can gain privileges through friendship), but we
952cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // take that as an oversight.
962cc2675d426af23476a9722c08c1b6c5266bd653John McCall    while (true) {
972cc2675d426af23476a9722c08c1b6c5266bd653John McCall      if (isa<CXXRecordDecl>(DC)) {
982cc2675d426af23476a9722c08c1b6c5266bd653John McCall        CXXRecordDecl *Record = cast<CXXRecordDecl>(DC)->getCanonicalDecl();
992cc2675d426af23476a9722c08c1b6c5266bd653John McCall        Records.push_back(Record);
1002cc2675d426af23476a9722c08c1b6c5266bd653John McCall        DC = Record->getDeclContext();
1012cc2675d426af23476a9722c08c1b6c5266bd653John McCall      } else if (isa<FunctionDecl>(DC)) {
1022cc2675d426af23476a9722c08c1b6c5266bd653John McCall        FunctionDecl *Function = cast<FunctionDecl>(DC)->getCanonicalDecl();
1032cc2675d426af23476a9722c08c1b6c5266bd653John McCall        Functions.push_back(Function);
1042cc2675d426af23476a9722c08c1b6c5266bd653John McCall        DC = Function->getDeclContext();
1052cc2675d426af23476a9722c08c1b6c5266bd653John McCall      } else if (DC->isFileContext()) {
1062cc2675d426af23476a9722c08c1b6c5266bd653John McCall        break;
1072cc2675d426af23476a9722c08c1b6c5266bd653John McCall      } else {
1082cc2675d426af23476a9722c08c1b6c5266bd653John McCall        DC = DC->getParent();
1092cc2675d426af23476a9722c08c1b6c5266bd653John McCall      }
11088b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    }
1116b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
1126b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1130c01d18094100db92d38daa923c95661512db203John McCall  bool isDependent() const { return Dependent; }
1140c01d18094100db92d38daa923c95661512db203John McCall
11588b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall  bool includesClass(const CXXRecordDecl *R) const {
11688b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    R = R->getCanonicalDecl();
11788b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    return std::find(Records.begin(), Records.end(), R)
11888b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall             != Records.end();
1196b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
1206b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1217ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  /// Retrieves the innermost "useful" context.  Can be null if we're
1227ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  /// doing access-control without privileges.
1237ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  DeclContext *getInnerContext() const {
1247ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall    return Inner;
1250c01d18094100db92d38daa923c95661512db203John McCall  }
1260c01d18094100db92d38daa923c95661512db203John McCall
1270c01d18094100db92d38daa923c95661512db203John McCall  typedef llvm::SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
1280c01d18094100db92d38daa923c95661512db203John McCall
1297ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  DeclContext *Inner;
1302cc2675d426af23476a9722c08c1b6c5266bd653John McCall  llvm::SmallVector<FunctionDecl*, 4> Functions;
13188b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall  llvm::SmallVector<CXXRecordDecl*, 4> Records;
1320c01d18094100db92d38daa923c95661512db203John McCall  bool Dependent;
1336b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall};
134161755a09898c95d21bfff33707da9ca41cd53c5John McCall
135161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// Like Sema's AccessedEntity, but kindly lets us scribble all over
136161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// it.
137161755a09898c95d21bfff33707da9ca41cd53c5John McCallstruct AccessTarget : public Sema::AccessedEntity {
138161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget(const Sema::AccessedEntity &Entity)
139161755a09898c95d21bfff33707da9ca41cd53c5John McCall    : AccessedEntity(Entity) {
140161755a09898c95d21bfff33707da9ca41cd53c5John McCall    initialize();
141161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
142161755a09898c95d21bfff33707da9ca41cd53c5John McCall
143161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget(ASTContext &Context,
144161755a09898c95d21bfff33707da9ca41cd53c5John McCall               MemberNonce _,
145161755a09898c95d21bfff33707da9ca41cd53c5John McCall               CXXRecordDecl *NamingClass,
146161755a09898c95d21bfff33707da9ca41cd53c5John McCall               DeclAccessPair FoundDecl,
147161755a09898c95d21bfff33707da9ca41cd53c5John McCall               QualType BaseObjectType)
148161755a09898c95d21bfff33707da9ca41cd53c5John McCall    : AccessedEntity(Context, Member, NamingClass, FoundDecl, BaseObjectType) {
149161755a09898c95d21bfff33707da9ca41cd53c5John McCall    initialize();
150161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
151161755a09898c95d21bfff33707da9ca41cd53c5John McCall
152161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget(ASTContext &Context,
153161755a09898c95d21bfff33707da9ca41cd53c5John McCall               BaseNonce _,
154161755a09898c95d21bfff33707da9ca41cd53c5John McCall               CXXRecordDecl *BaseClass,
155161755a09898c95d21bfff33707da9ca41cd53c5John McCall               CXXRecordDecl *DerivedClass,
156161755a09898c95d21bfff33707da9ca41cd53c5John McCall               AccessSpecifier Access)
157161755a09898c95d21bfff33707da9ca41cd53c5John McCall    : AccessedEntity(Context, Base, BaseClass, DerivedClass, Access) {
158161755a09898c95d21bfff33707da9ca41cd53c5John McCall    initialize();
159161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
160161755a09898c95d21bfff33707da9ca41cd53c5John McCall
161161755a09898c95d21bfff33707da9ca41cd53c5John McCall  bool hasInstanceContext() const {
162161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return HasInstanceContext;
163161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
164161755a09898c95d21bfff33707da9ca41cd53c5John McCall
165161755a09898c95d21bfff33707da9ca41cd53c5John McCall  class SavedInstanceContext {
166161755a09898c95d21bfff33707da9ca41cd53c5John McCall  public:
167161755a09898c95d21bfff33707da9ca41cd53c5John McCall    ~SavedInstanceContext() {
168161755a09898c95d21bfff33707da9ca41cd53c5John McCall      Target.HasInstanceContext = Has;
169161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
170161755a09898c95d21bfff33707da9ca41cd53c5John McCall
171161755a09898c95d21bfff33707da9ca41cd53c5John McCall  private:
172c91cc66e92b084acd1fdbaa1c3c74242741b3d46John McCall    friend struct AccessTarget;
173161755a09898c95d21bfff33707da9ca41cd53c5John McCall    explicit SavedInstanceContext(AccessTarget &Target)
174161755a09898c95d21bfff33707da9ca41cd53c5John McCall      : Target(Target), Has(Target.HasInstanceContext) {}
175161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget &Target;
176161755a09898c95d21bfff33707da9ca41cd53c5John McCall    bool Has;
177161755a09898c95d21bfff33707da9ca41cd53c5John McCall  };
178161755a09898c95d21bfff33707da9ca41cd53c5John McCall
179161755a09898c95d21bfff33707da9ca41cd53c5John McCall  SavedInstanceContext saveInstanceContext() {
180161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return SavedInstanceContext(*this);
181161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
182161755a09898c95d21bfff33707da9ca41cd53c5John McCall
183161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void suppressInstanceContext() {
184161755a09898c95d21bfff33707da9ca41cd53c5John McCall    HasInstanceContext = false;
185161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
186161755a09898c95d21bfff33707da9ca41cd53c5John McCall
187161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
188161755a09898c95d21bfff33707da9ca41cd53c5John McCall    assert(HasInstanceContext);
189161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (CalculatedInstanceContext)
190161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return InstanceContext;
191161755a09898c95d21bfff33707da9ca41cd53c5John McCall
192161755a09898c95d21bfff33707da9ca41cd53c5John McCall    CalculatedInstanceContext = true;
193161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DeclContext *IC = S.computeDeclContext(getBaseObjectType());
194161755a09898c95d21bfff33707da9ca41cd53c5John McCall    InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl() : 0);
195161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return InstanceContext;
196161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
197161755a09898c95d21bfff33707da9ca41cd53c5John McCall
198161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *getDeclaringClass() const {
199161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return DeclaringClass;
200161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
201161755a09898c95d21bfff33707da9ca41cd53c5John McCall
202161755a09898c95d21bfff33707da9ca41cd53c5John McCallprivate:
203161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void initialize() {
204161755a09898c95d21bfff33707da9ca41cd53c5John McCall    HasInstanceContext = (isMemberAccess() &&
205161755a09898c95d21bfff33707da9ca41cd53c5John McCall                          !getBaseObjectType().isNull() &&
206161755a09898c95d21bfff33707da9ca41cd53c5John McCall                          getTargetDecl()->isCXXInstanceMember());
207161755a09898c95d21bfff33707da9ca41cd53c5John McCall    CalculatedInstanceContext = false;
208161755a09898c95d21bfff33707da9ca41cd53c5John McCall    InstanceContext = 0;
209161755a09898c95d21bfff33707da9ca41cd53c5John McCall
210161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (isMemberAccess())
211161755a09898c95d21bfff33707da9ca41cd53c5John McCall      DeclaringClass = FindDeclaringClass(getTargetDecl());
212161755a09898c95d21bfff33707da9ca41cd53c5John McCall    else
213161755a09898c95d21bfff33707da9ca41cd53c5John McCall      DeclaringClass = getBaseClass();
214161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DeclaringClass = DeclaringClass->getCanonicalDecl();
215161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
216161755a09898c95d21bfff33707da9ca41cd53c5John McCall
217161755a09898c95d21bfff33707da9ca41cd53c5John McCall  bool HasInstanceContext : 1;
218161755a09898c95d21bfff33707da9ca41cd53c5John McCall  mutable bool CalculatedInstanceContext : 1;
219161755a09898c95d21bfff33707da9ca41cd53c5John McCall  mutable const CXXRecordDecl *InstanceContext;
220161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *DeclaringClass;
221161755a09898c95d21bfff33707da9ca41cd53c5John McCall};
222161755a09898c95d21bfff33707da9ca41cd53c5John McCall
2236b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
224726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
22501ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall/// Checks whether one class might instantiate to the other.
22601ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCallstatic bool MightInstantiateTo(const CXXRecordDecl *From,
22701ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall                               const CXXRecordDecl *To) {
22801ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  // Declaration names are always preserved by instantiation.
22901ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (From->getDeclName() != To->getDeclName())
23001ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall    return false;
23101ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
23201ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
23301ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
23401ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (FromDC == ToDC) return true;
23501ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
23601ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
23701ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  // Be conservative.
23801ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  return true;
23901ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall}
24001ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
241161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// Checks whether one class is derived from another, inclusively.
242161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// Properly indicates when it couldn't be determined due to
243161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// dependence.
244161755a09898c95d21bfff33707da9ca41cd53c5John McCall///
245161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// This should probably be donated to AST or at least Sema.
246161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived,
247161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                           const CXXRecordDecl *Target) {
248161755a09898c95d21bfff33707da9ca41cd53c5John McCall  assert(Derived->getCanonicalDecl() == Derived);
249161755a09898c95d21bfff33707da9ca41cd53c5John McCall  assert(Target->getCanonicalDecl() == Target);
250c1b621daf98d83075a466c6f4ad9904dc845dd09John McCall
251161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (Derived == Target) return AR_accessible;
252c1b621daf98d83075a466c6f4ad9904dc845dd09John McCall
25301ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  bool CheckDependent = Derived->isDependentContext();
25401ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (CheckDependent && MightInstantiateTo(Derived, Target))
25501ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall    return AR_dependent;
25601ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
257161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
258161755a09898c95d21bfff33707da9ca41cd53c5John McCall  llvm::SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
259161755a09898c95d21bfff33707da9ca41cd53c5John McCall
260161755a09898c95d21bfff33707da9ca41cd53c5John McCall  while (true) {
261161755a09898c95d21bfff33707da9ca41cd53c5John McCall    for (CXXRecordDecl::base_class_const_iterator
262161755a09898c95d21bfff33707da9ca41cd53c5John McCall           I = Derived->bases_begin(), E = Derived->bases_end(); I != E; ++I) {
263161755a09898c95d21bfff33707da9ca41cd53c5John McCall
264161755a09898c95d21bfff33707da9ca41cd53c5John McCall      const CXXRecordDecl *RD;
265161755a09898c95d21bfff33707da9ca41cd53c5John McCall
266161755a09898c95d21bfff33707da9ca41cd53c5John McCall      QualType T = I->getType();
267161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (const RecordType *RT = T->getAs<RecordType>()) {
268161755a09898c95d21bfff33707da9ca41cd53c5John McCall        RD = cast<CXXRecordDecl>(RT->getDecl());
26901ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall      } else if (const InjectedClassNameType *IT
27001ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall                   = T->getAs<InjectedClassNameType>()) {
27101ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall        RD = IT->getDecl();
272161755a09898c95d21bfff33707da9ca41cd53c5John McCall      } else {
273161755a09898c95d21bfff33707da9ca41cd53c5John McCall        assert(T->isDependentType() && "non-dependent base wasn't a record?");
274161755a09898c95d21bfff33707da9ca41cd53c5John McCall        OnFailure = AR_dependent;
275161755a09898c95d21bfff33707da9ca41cd53c5John McCall        continue;
276161755a09898c95d21bfff33707da9ca41cd53c5John McCall      }
277161755a09898c95d21bfff33707da9ca41cd53c5John McCall
278161755a09898c95d21bfff33707da9ca41cd53c5John McCall      RD = RD->getCanonicalDecl();
279161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (RD == Target) return AR_accessible;
28001ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall      if (CheckDependent && MightInstantiateTo(RD, Target))
28101ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall        OnFailure = AR_dependent;
28201ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
283161755a09898c95d21bfff33707da9ca41cd53c5John McCall      Queue.push_back(RD);
284161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
285161755a09898c95d21bfff33707da9ca41cd53c5John McCall
286161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (Queue.empty()) break;
287161755a09898c95d21bfff33707da9ca41cd53c5John McCall
288161755a09898c95d21bfff33707da9ca41cd53c5John McCall    Derived = Queue.back();
289161755a09898c95d21bfff33707da9ca41cd53c5John McCall    Queue.pop_back();
290161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
291161755a09898c95d21bfff33707da9ca41cd53c5John McCall
292161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return OnFailure;
2936b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
2946b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
295161755a09898c95d21bfff33707da9ca41cd53c5John McCall
2960c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S, DeclContext *Context,
2970c01d18094100db92d38daa923c95661512db203John McCall                               DeclContext *Friend) {
2980c01d18094100db92d38daa923c95661512db203John McCall  if (Friend == Context)
2990c01d18094100db92d38daa923c95661512db203John McCall    return true;
3000c01d18094100db92d38daa923c95661512db203John McCall
3010c01d18094100db92d38daa923c95661512db203John McCall  assert(!Friend->isDependentContext() &&
3020c01d18094100db92d38daa923c95661512db203John McCall         "can't handle friends with dependent contexts here");
3030c01d18094100db92d38daa923c95661512db203John McCall
3040c01d18094100db92d38daa923c95661512db203John McCall  if (!Context->isDependentContext())
3050c01d18094100db92d38daa923c95661512db203John McCall    return false;
3060c01d18094100db92d38daa923c95661512db203John McCall
3070c01d18094100db92d38daa923c95661512db203John McCall  if (Friend->isFileContext())
3080c01d18094100db92d38daa923c95661512db203John McCall    return false;
3090c01d18094100db92d38daa923c95661512db203John McCall
3100c01d18094100db92d38daa923c95661512db203John McCall  // TODO: this is very conservative
3110c01d18094100db92d38daa923c95661512db203John McCall  return true;
3120c01d18094100db92d38daa923c95661512db203John McCall}
3130c01d18094100db92d38daa923c95661512db203John McCall
3140c01d18094100db92d38daa923c95661512db203John McCall// Asks whether the type in 'context' can ever instantiate to the type
3150c01d18094100db92d38daa923c95661512db203John McCall// in 'friend'.
3160c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) {
3170c01d18094100db92d38daa923c95661512db203John McCall  if (Friend == Context)
3180c01d18094100db92d38daa923c95661512db203John McCall    return true;
3190c01d18094100db92d38daa923c95661512db203John McCall
3200c01d18094100db92d38daa923c95661512db203John McCall  if (!Friend->isDependentType() && !Context->isDependentType())
3210c01d18094100db92d38daa923c95661512db203John McCall    return false;
3220c01d18094100db92d38daa923c95661512db203John McCall
3230c01d18094100db92d38daa923c95661512db203John McCall  // TODO: this is very conservative.
3240c01d18094100db92d38daa923c95661512db203John McCall  return true;
3250c01d18094100db92d38daa923c95661512db203John McCall}
3260c01d18094100db92d38daa923c95661512db203John McCall
3270c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S,
3280c01d18094100db92d38daa923c95661512db203John McCall                               FunctionDecl *Context,
3290c01d18094100db92d38daa923c95661512db203John McCall                               FunctionDecl *Friend) {
3300c01d18094100db92d38daa923c95661512db203John McCall  if (Context->getDeclName() != Friend->getDeclName())
3310c01d18094100db92d38daa923c95661512db203John McCall    return false;
3320c01d18094100db92d38daa923c95661512db203John McCall
3330c01d18094100db92d38daa923c95661512db203John McCall  if (!MightInstantiateTo(S,
3340c01d18094100db92d38daa923c95661512db203John McCall                          Context->getDeclContext(),
3350c01d18094100db92d38daa923c95661512db203John McCall                          Friend->getDeclContext()))
3360c01d18094100db92d38daa923c95661512db203John McCall    return false;
3370c01d18094100db92d38daa923c95661512db203John McCall
3380c01d18094100db92d38daa923c95661512db203John McCall  CanQual<FunctionProtoType> FriendTy
3390c01d18094100db92d38daa923c95661512db203John McCall    = S.Context.getCanonicalType(Friend->getType())
3400c01d18094100db92d38daa923c95661512db203John McCall         ->getAs<FunctionProtoType>();
3410c01d18094100db92d38daa923c95661512db203John McCall  CanQual<FunctionProtoType> ContextTy
3420c01d18094100db92d38daa923c95661512db203John McCall    = S.Context.getCanonicalType(Context->getType())
3430c01d18094100db92d38daa923c95661512db203John McCall         ->getAs<FunctionProtoType>();
3440c01d18094100db92d38daa923c95661512db203John McCall
3450c01d18094100db92d38daa923c95661512db203John McCall  // There isn't any way that I know of to add qualifiers
3460c01d18094100db92d38daa923c95661512db203John McCall  // during instantiation.
3470c01d18094100db92d38daa923c95661512db203John McCall  if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
3480c01d18094100db92d38daa923c95661512db203John McCall    return false;
3490c01d18094100db92d38daa923c95661512db203John McCall
3500c01d18094100db92d38daa923c95661512db203John McCall  if (FriendTy->getNumArgs() != ContextTy->getNumArgs())
3510c01d18094100db92d38daa923c95661512db203John McCall    return false;
3520c01d18094100db92d38daa923c95661512db203John McCall
3530c01d18094100db92d38daa923c95661512db203John McCall  if (!MightInstantiateTo(S,
3540c01d18094100db92d38daa923c95661512db203John McCall                          ContextTy->getResultType(),
3550c01d18094100db92d38daa923c95661512db203John McCall                          FriendTy->getResultType()))
3560c01d18094100db92d38daa923c95661512db203John McCall    return false;
3570c01d18094100db92d38daa923c95661512db203John McCall
3580c01d18094100db92d38daa923c95661512db203John McCall  for (unsigned I = 0, E = FriendTy->getNumArgs(); I != E; ++I)
3590c01d18094100db92d38daa923c95661512db203John McCall    if (!MightInstantiateTo(S,
3600c01d18094100db92d38daa923c95661512db203John McCall                            ContextTy->getArgType(I),
3610c01d18094100db92d38daa923c95661512db203John McCall                            FriendTy->getArgType(I)))
3620c01d18094100db92d38daa923c95661512db203John McCall      return false;
3630c01d18094100db92d38daa923c95661512db203John McCall
3640c01d18094100db92d38daa923c95661512db203John McCall  return true;
3650c01d18094100db92d38daa923c95661512db203John McCall}
3660c01d18094100db92d38daa923c95661512db203John McCall
3670c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S,
3680c01d18094100db92d38daa923c95661512db203John McCall                               FunctionTemplateDecl *Context,
3690c01d18094100db92d38daa923c95661512db203John McCall                               FunctionTemplateDecl *Friend) {
3700c01d18094100db92d38daa923c95661512db203John McCall  return MightInstantiateTo(S,
3710c01d18094100db92d38daa923c95661512db203John McCall                            Context->getTemplatedDecl(),
3720c01d18094100db92d38daa923c95661512db203John McCall                            Friend->getTemplatedDecl());
3730c01d18094100db92d38daa923c95661512db203John McCall}
3740c01d18094100db92d38daa923c95661512db203John McCall
375161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
376161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
377161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const CXXRecordDecl *Friend) {
378a742db0032d8f458fe229600d2082981a1fb1481John McCall  if (EC.includesClass(Friend))
379161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_accessible;
380a742db0032d8f458fe229600d2082981a1fb1481John McCall
3810c01d18094100db92d38daa923c95661512db203John McCall  if (EC.isDependent()) {
3820c01d18094100db92d38daa923c95661512db203John McCall    CanQualType FriendTy
3830c01d18094100db92d38daa923c95661512db203John McCall      = S.Context.getCanonicalType(S.Context.getTypeDeclType(Friend));
3840c01d18094100db92d38daa923c95661512db203John McCall
3850c01d18094100db92d38daa923c95661512db203John McCall    for (EffectiveContext::record_iterator
3860c01d18094100db92d38daa923c95661512db203John McCall           I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
3870c01d18094100db92d38daa923c95661512db203John McCall      CanQualType ContextTy
3880c01d18094100db92d38daa923c95661512db203John McCall        = S.Context.getCanonicalType(S.Context.getTypeDeclType(*I));
3890c01d18094100db92d38daa923c95661512db203John McCall      if (MightInstantiateTo(S, ContextTy, FriendTy))
390161755a09898c95d21bfff33707da9ca41cd53c5John McCall        return AR_dependent;
3910c01d18094100db92d38daa923c95661512db203John McCall    }
3920c01d18094100db92d38daa923c95661512db203John McCall  }
3930c01d18094100db92d38daa923c95661512db203John McCall
394161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return AR_inaccessible;
395a742db0032d8f458fe229600d2082981a1fb1481John McCall}
396a742db0032d8f458fe229600d2082981a1fb1481John McCall
397161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
398161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
399161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  CanQualType Friend) {
4000c01d18094100db92d38daa923c95661512db203John McCall  if (const RecordType *RT = Friend->getAs<RecordType>())
4010c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
402a742db0032d8f458fe229600d2082981a1fb1481John McCall
4030c01d18094100db92d38daa923c95661512db203John McCall  // TODO: we can do better than this
4040c01d18094100db92d38daa923c95661512db203John McCall  if (Friend->isDependentType())
405161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_dependent;
406a742db0032d8f458fe229600d2082981a1fb1481John McCall
407161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return AR_inaccessible;
4080c01d18094100db92d38daa923c95661512db203John McCall}
409a742db0032d8f458fe229600d2082981a1fb1481John McCall
4100c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend class template matches
4110c01d18094100db92d38daa923c95661512db203John McCall/// anything in the effective context.
412161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
413161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
414161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  ClassTemplateDecl *Friend) {
415161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
416a742db0032d8f458fe229600d2082981a1fb1481John McCall
41793ba8579c341d5329175f1413cdc3b35a36592d2John McCall  // Check whether the friend is the template of a class in the
41893ba8579c341d5329175f1413cdc3b35a36592d2John McCall  // context chain.
4190c01d18094100db92d38daa923c95661512db203John McCall  for (llvm::SmallVectorImpl<CXXRecordDecl*>::const_iterator
4200c01d18094100db92d38daa923c95661512db203John McCall         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
4210c01d18094100db92d38daa923c95661512db203John McCall    CXXRecordDecl *Record = *I;
422a742db0032d8f458fe229600d2082981a1fb1481John McCall
42393ba8579c341d5329175f1413cdc3b35a36592d2John McCall    // Figure out whether the current class has a template:
4240c01d18094100db92d38daa923c95661512db203John McCall    ClassTemplateDecl *CTD;
425a742db0032d8f458fe229600d2082981a1fb1481John McCall
4260c01d18094100db92d38daa923c95661512db203John McCall    // A specialization of the template...
4270c01d18094100db92d38daa923c95661512db203John McCall    if (isa<ClassTemplateSpecializationDecl>(Record)) {
4280c01d18094100db92d38daa923c95661512db203John McCall      CTD = cast<ClassTemplateSpecializationDecl>(Record)
4290c01d18094100db92d38daa923c95661512db203John McCall        ->getSpecializedTemplate();
430a742db0032d8f458fe229600d2082981a1fb1481John McCall
4310c01d18094100db92d38daa923c95661512db203John McCall    // ... or the template pattern itself.
4320c01d18094100db92d38daa923c95661512db203John McCall    } else {
4330c01d18094100db92d38daa923c95661512db203John McCall      CTD = Record->getDescribedClassTemplate();
4340c01d18094100db92d38daa923c95661512db203John McCall      if (!CTD) continue;
435a742db0032d8f458fe229600d2082981a1fb1481John McCall    }
436a742db0032d8f458fe229600d2082981a1fb1481John McCall
4370c01d18094100db92d38daa923c95661512db203John McCall    // It's a match.
4380c01d18094100db92d38daa923c95661512db203John McCall    if (Friend == CTD->getCanonicalDecl())
439161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
4400c01d18094100db92d38daa923c95661512db203John McCall
44193ba8579c341d5329175f1413cdc3b35a36592d2John McCall    // If the context isn't dependent, it can't be a dependent match.
44293ba8579c341d5329175f1413cdc3b35a36592d2John McCall    if (!EC.isDependent())
44393ba8579c341d5329175f1413cdc3b35a36592d2John McCall      continue;
44493ba8579c341d5329175f1413cdc3b35a36592d2John McCall
4450c01d18094100db92d38daa923c95661512db203John McCall    // If the template names don't match, it can't be a dependent
4460c01d18094100db92d38daa923c95661512db203John McCall    // match.  This isn't true in C++0x because of template aliases.
4470c01d18094100db92d38daa923c95661512db203John McCall    if (!S.LangOpts.CPlusPlus0x && CTD->getDeclName() != Friend->getDeclName())
4480c01d18094100db92d38daa923c95661512db203John McCall      continue;
4490c01d18094100db92d38daa923c95661512db203John McCall
4500c01d18094100db92d38daa923c95661512db203John McCall    // If the class's context can't instantiate to the friend's
4510c01d18094100db92d38daa923c95661512db203John McCall    // context, it can't be a dependent match.
4520c01d18094100db92d38daa923c95661512db203John McCall    if (!MightInstantiateTo(S, CTD->getDeclContext(),
4530c01d18094100db92d38daa923c95661512db203John McCall                            Friend->getDeclContext()))
4540c01d18094100db92d38daa923c95661512db203John McCall      continue;
4550c01d18094100db92d38daa923c95661512db203John McCall
4560c01d18094100db92d38daa923c95661512db203John McCall    // Otherwise, it's a dependent match.
457161755a09898c95d21bfff33707da9ca41cd53c5John McCall    OnFailure = AR_dependent;
458a742db0032d8f458fe229600d2082981a1fb1481John McCall  }
459a742db0032d8f458fe229600d2082981a1fb1481John McCall
4600c01d18094100db92d38daa923c95661512db203John McCall  return OnFailure;
4610c01d18094100db92d38daa923c95661512db203John McCall}
462a742db0032d8f458fe229600d2082981a1fb1481John McCall
4630c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend function matches anything in
4640c01d18094100db92d38daa923c95661512db203John McCall/// the effective context.
465161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
466161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
467161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  FunctionDecl *Friend) {
468161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
469a742db0032d8f458fe229600d2082981a1fb1481John McCall
4702cc2675d426af23476a9722c08c1b6c5266bd653John McCall  for (llvm::SmallVectorImpl<FunctionDecl*>::const_iterator
4712cc2675d426af23476a9722c08c1b6c5266bd653John McCall         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
4722cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (Friend == *I)
473161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
4740c01d18094100db92d38daa923c95661512db203John McCall
4752cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
476161755a09898c95d21bfff33707da9ca41cd53c5John McCall      OnFailure = AR_dependent;
4772cc2675d426af23476a9722c08c1b6c5266bd653John McCall  }
4780c01d18094100db92d38daa923c95661512db203John McCall
4792cc2675d426af23476a9722c08c1b6c5266bd653John McCall  return OnFailure;
4800c01d18094100db92d38daa923c95661512db203John McCall}
4810c01d18094100db92d38daa923c95661512db203John McCall
4820c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend function template matches
4830c01d18094100db92d38daa923c95661512db203John McCall/// anything in the effective context.
484161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
485161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
486161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  FunctionTemplateDecl *Friend) {
487161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (EC.Functions.empty()) return AR_inaccessible;
4882cc2675d426af23476a9722c08c1b6c5266bd653John McCall
489161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
4900c01d18094100db92d38daa923c95661512db203John McCall
4912cc2675d426af23476a9722c08c1b6c5266bd653John McCall  for (llvm::SmallVectorImpl<FunctionDecl*>::const_iterator
4922cc2675d426af23476a9722c08c1b6c5266bd653John McCall         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
493a742db0032d8f458fe229600d2082981a1fb1481John McCall
4942cc2675d426af23476a9722c08c1b6c5266bd653John McCall    FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
4952cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (!FTD)
4962cc2675d426af23476a9722c08c1b6c5266bd653John McCall      FTD = (*I)->getDescribedFunctionTemplate();
4972cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (!FTD)
4982cc2675d426af23476a9722c08c1b6c5266bd653John McCall      continue;
499a742db0032d8f458fe229600d2082981a1fb1481John McCall
5002cc2675d426af23476a9722c08c1b6c5266bd653John McCall    FTD = FTD->getCanonicalDecl();
501a742db0032d8f458fe229600d2082981a1fb1481John McCall
5022cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (Friend == FTD)
503161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
5042cc2675d426af23476a9722c08c1b6c5266bd653John McCall
5052cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
506161755a09898c95d21bfff33707da9ca41cd53c5John McCall      OnFailure = AR_dependent;
5072cc2675d426af23476a9722c08c1b6c5266bd653John McCall  }
5082cc2675d426af23476a9722c08c1b6c5266bd653John McCall
5092cc2675d426af23476a9722c08c1b6c5266bd653John McCall  return OnFailure;
510a742db0032d8f458fe229600d2082981a1fb1481John McCall}
511a742db0032d8f458fe229600d2082981a1fb1481John McCall
5120c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend declaration matches anything
5130c01d18094100db92d38daa923c95661512db203John McCall/// in the effective context.
514161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
515161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
516161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  FriendDecl *FriendD) {
51732f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  if (TypeSourceInfo *T = FriendD->getFriendType())
51832f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall    return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
5190c01d18094100db92d38daa923c95661512db203John McCall
5200c01d18094100db92d38daa923c95661512db203John McCall  NamedDecl *Friend
5210c01d18094100db92d38daa923c95661512db203John McCall    = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
5220c01d18094100db92d38daa923c95661512db203John McCall
5230c01d18094100db92d38daa923c95661512db203John McCall  // FIXME: declarations with dependent or templated scope.
5240c01d18094100db92d38daa923c95661512db203John McCall
5250c01d18094100db92d38daa923c95661512db203John McCall  if (isa<ClassTemplateDecl>(Friend))
5260c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
5270c01d18094100db92d38daa923c95661512db203John McCall
5280c01d18094100db92d38daa923c95661512db203John McCall  if (isa<FunctionTemplateDecl>(Friend))
5290c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
5300c01d18094100db92d38daa923c95661512db203John McCall
5310c01d18094100db92d38daa923c95661512db203John McCall  if (isa<CXXRecordDecl>(Friend))
5320c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
5330c01d18094100db92d38daa923c95661512db203John McCall
5340c01d18094100db92d38daa923c95661512db203John McCall  assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
5350c01d18094100db92d38daa923c95661512db203John McCall  return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
5360c01d18094100db92d38daa923c95661512db203John McCall}
5370c01d18094100db92d38daa923c95661512db203John McCall
538161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult GetFriendKind(Sema &S,
539161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
540161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const CXXRecordDecl *Class) {
541161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
54288b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall
543d60e22e601852ae1345f01514318a0951dc09f89John McCall  // Okay, check friends.
544d60e22e601852ae1345f01514318a0951dc09f89John McCall  for (CXXRecordDecl::friend_iterator I = Class->friend_begin(),
545d60e22e601852ae1345f01514318a0951dc09f89John McCall         E = Class->friend_end(); I != E; ++I) {
546d60e22e601852ae1345f01514318a0951dc09f89John McCall    FriendDecl *Friend = *I;
547d60e22e601852ae1345f01514318a0951dc09f89John McCall
548a742db0032d8f458fe229600d2082981a1fb1481John McCall    switch (MatchesFriend(S, EC, Friend)) {
549161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible:
550161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
55188b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall
552161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible:
553161755a09898c95d21bfff33707da9ca41cd53c5John McCall      continue;
554d60e22e601852ae1345f01514318a0951dc09f89John McCall
555161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
556161755a09898c95d21bfff33707da9ca41cd53c5John McCall      OnFailure = AR_dependent;
557a742db0032d8f458fe229600d2082981a1fb1481John McCall      break;
558a742db0032d8f458fe229600d2082981a1fb1481John McCall    }
559d60e22e601852ae1345f01514318a0951dc09f89John McCall  }
560d60e22e601852ae1345f01514318a0951dc09f89John McCall
561d60e22e601852ae1345f01514318a0951dc09f89John McCall  // That's it, give up.
56288b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall  return OnFailure;
5636b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
5646b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
565161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult HasAccess(Sema &S,
566161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              const EffectiveContext &EC,
567161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              const CXXRecordDecl *NamingClass,
568161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              AccessSpecifier Access,
569161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              const AccessTarget &Target) {
570db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(NamingClass->getCanonicalDecl() == NamingClass &&
571db73c684ba61fed4087af488e8610657ec638c17John McCall         "declaration should be canonicalized before being passed here");
572db73c684ba61fed4087af488e8610657ec638c17John McCall
573161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (Access == AS_public) return AR_accessible;
574db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(Access == AS_private || Access == AS_protected);
575db73c684ba61fed4087af488e8610657ec638c17John McCall
576161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
577161755a09898c95d21bfff33707da9ca41cd53c5John McCall
578db73c684ba61fed4087af488e8610657ec638c17John McCall  for (EffectiveContext::record_iterator
579db73c684ba61fed4087af488e8610657ec638c17John McCall         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
580db73c684ba61fed4087af488e8610657ec638c17John McCall    // All the declarations in EC have been canonicalized, so pointer
581db73c684ba61fed4087af488e8610657ec638c17John McCall    // equality from this point on will work fine.
582db73c684ba61fed4087af488e8610657ec638c17John McCall    const CXXRecordDecl *ECRecord = *I;
583db73c684ba61fed4087af488e8610657ec638c17John McCall
584db73c684ba61fed4087af488e8610657ec638c17John McCall    // [B2] and [M2]
585161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (Access == AS_private) {
586161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (ECRecord == NamingClass)
587161755a09898c95d21bfff33707da9ca41cd53c5John McCall        return AR_accessible;
588db73c684ba61fed4087af488e8610657ec638c17John McCall
58901ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall      if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
59001ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall        OnFailure = AR_dependent;
59101ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
592db73c684ba61fed4087af488e8610657ec638c17John McCall    // [B3] and [M3]
593161755a09898c95d21bfff33707da9ca41cd53c5John McCall    } else {
594161755a09898c95d21bfff33707da9ca41cd53c5John McCall      assert(Access == AS_protected);
595161755a09898c95d21bfff33707da9ca41cd53c5John McCall      switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
596161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_accessible: break;
597161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_inaccessible: continue;
598161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_dependent: OnFailure = AR_dependent; continue;
599161755a09898c95d21bfff33707da9ca41cd53c5John McCall      }
600161755a09898c95d21bfff33707da9ca41cd53c5John McCall
601161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (!Target.hasInstanceContext())
602161755a09898c95d21bfff33707da9ca41cd53c5John McCall        return AR_accessible;
603161755a09898c95d21bfff33707da9ca41cd53c5John McCall
604161755a09898c95d21bfff33707da9ca41cd53c5John McCall      const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
605161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (!InstanceContext) {
606161755a09898c95d21bfff33707da9ca41cd53c5John McCall        OnFailure = AR_dependent;
607161755a09898c95d21bfff33707da9ca41cd53c5John McCall        continue;
608161755a09898c95d21bfff33707da9ca41cd53c5John McCall      }
609161755a09898c95d21bfff33707da9ca41cd53c5John McCall
610161755a09898c95d21bfff33707da9ca41cd53c5John McCall      // C++ [class.protected]p1:
611161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   An additional access check beyond those described earlier in
612161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   [class.access] is applied when a non-static data member or
613161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   non-static member function is a protected member of its naming
614161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   class.  As described earlier, access to a protected member is
615161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   granted because the reference occurs in a friend or member of
616161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   some class C.  If the access is to form a pointer to member,
617161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   the nested-name-specifier shall name C or a class derived from
618161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   C. All other accesses involve a (possibly implicit) object
619161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   expression. In this case, the class of the object expression
620161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   shall be C or a class derived from C.
621161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //
622161755a09898c95d21bfff33707da9ca41cd53c5John McCall      // We interpret this as a restriction on [M3].  Most of the
623161755a09898c95d21bfff33707da9ca41cd53c5John McCall      // conditions are encoded by not having any instance context.
624161755a09898c95d21bfff33707da9ca41cd53c5John McCall      switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
625161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_accessible: return AR_accessible;
626161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_inaccessible: continue;
627161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_dependent: OnFailure = AR_dependent; continue;
628161755a09898c95d21bfff33707da9ca41cd53c5John McCall      }
629161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
630db73c684ba61fed4087af488e8610657ec638c17John McCall  }
631db73c684ba61fed4087af488e8610657ec638c17John McCall
632161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (!NamingClass->hasFriends())
633161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return OnFailure;
634161755a09898c95d21bfff33707da9ca41cd53c5John McCall
635161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // Don't consider friends if we're under the [class.protected]
636161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // restriction, above.
637161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (Access == AS_protected && Target.hasInstanceContext()) {
638161755a09898c95d21bfff33707da9ca41cd53c5John McCall    const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
639161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (!InstanceContext) return AR_dependent;
640161755a09898c95d21bfff33707da9ca41cd53c5John McCall
641161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (IsDerivedFromInclusive(InstanceContext, NamingClass)) {
642161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible: break;
643161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: return OnFailure;
644161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent: return AR_dependent;
645161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
646161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
647161755a09898c95d21bfff33707da9ca41cd53c5John McCall
648161755a09898c95d21bfff33707da9ca41cd53c5John McCall  switch (GetFriendKind(S, EC, NamingClass)) {
649161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_accessible: return AR_accessible;
650161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_inaccessible: return OnFailure;
651161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_dependent: return AR_dependent;
652161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
653161755a09898c95d21bfff33707da9ca41cd53c5John McCall
654161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // Silence bogus warnings
655161755a09898c95d21bfff33707da9ca41cd53c5John McCall  llvm_unreachable("impossible friendship kind");
656161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return OnFailure;
657db73c684ba61fed4087af488e8610657ec638c17John McCall}
658db73c684ba61fed4087af488e8610657ec638c17John McCall
6596b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Finds the best path from the naming class to the declaring class,
6606b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// taking friend declarations into account.
6616b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///
662db73c684ba61fed4087af488e8610657ec638c17John McCall/// C++0x [class.access.base]p5:
663db73c684ba61fed4087af488e8610657ec638c17John McCall///   A member m is accessible at the point R when named in class N if
664db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M1] m as a member of N is public, or
665db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M2] m as a member of N is private, and R occurs in a member or
666db73c684ba61fed4087af488e8610657ec638c17John McCall///        friend of class N, or
667db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M3] m as a member of N is protected, and R occurs in a member or
668db73c684ba61fed4087af488e8610657ec638c17John McCall///        friend of class N, or in a member or friend of a class P
669db73c684ba61fed4087af488e8610657ec638c17John McCall///        derived from N, where m as a member of P is public, private,
670db73c684ba61fed4087af488e8610657ec638c17John McCall///        or protected, or
671db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M4] there exists a base class B of N that is accessible at R, and
672db73c684ba61fed4087af488e8610657ec638c17John McCall///        m is accessible at R when named in class B.
673db73c684ba61fed4087af488e8610657ec638c17John McCall///
674db73c684ba61fed4087af488e8610657ec638c17John McCall/// C++0x [class.access.base]p4:
675db73c684ba61fed4087af488e8610657ec638c17John McCall///   A base class B of N is accessible at R, if
676db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B1] an invented public member of B would be a public member of N, or
677db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B2] R occurs in a member or friend of class N, and an invented public
678db73c684ba61fed4087af488e8610657ec638c17John McCall///        member of B would be a private or protected member of N, or
679db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B3] R occurs in a member or friend of a class P derived from N, and an
680db73c684ba61fed4087af488e8610657ec638c17John McCall///        invented public member of B would be a private or protected member
681db73c684ba61fed4087af488e8610657ec638c17John McCall///        of P, or
682db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B4] there exists a class S such that B is a base class of S accessible
683db73c684ba61fed4087af488e8610657ec638c17John McCall///        at R and S is a base class of N accessible at R.
684db73c684ba61fed4087af488e8610657ec638c17John McCall///
685db73c684ba61fed4087af488e8610657ec638c17John McCall/// Along a single inheritance path we can restate both of these
686db73c684ba61fed4087af488e8610657ec638c17John McCall/// iteratively:
687db73c684ba61fed4087af488e8610657ec638c17John McCall///
688db73c684ba61fed4087af488e8610657ec638c17John McCall/// First, we note that M1-4 are equivalent to B1-4 if the member is
689db73c684ba61fed4087af488e8610657ec638c17John McCall/// treated as a notional base of its declaring class with inheritance
690db73c684ba61fed4087af488e8610657ec638c17John McCall/// access equivalent to the member's access.  Therefore we need only
691db73c684ba61fed4087af488e8610657ec638c17John McCall/// ask whether a class B is accessible from a class N in context R.
692db73c684ba61fed4087af488e8610657ec638c17John McCall///
693db73c684ba61fed4087af488e8610657ec638c17John McCall/// Let B_1 .. B_n be the inheritance path in question (i.e. where
694db73c684ba61fed4087af488e8610657ec638c17John McCall/// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
695db73c684ba61fed4087af488e8610657ec638c17John McCall/// B_i).  For i in 1..n, we will calculate ACAB(i), the access to the
696db73c684ba61fed4087af488e8610657ec638c17John McCall/// closest accessible base in the path:
697db73c684ba61fed4087af488e8610657ec638c17John McCall///   Access(a, b) = (* access on the base specifier from a to b *)
698db73c684ba61fed4087af488e8610657ec638c17John McCall///   Merge(a, forbidden) = forbidden
699db73c684ba61fed4087af488e8610657ec638c17John McCall///   Merge(a, private) = forbidden
700db73c684ba61fed4087af488e8610657ec638c17John McCall///   Merge(a, b) = min(a,b)
701db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, forbidden) = false
702db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, private) = (R is c) || IsFriend(c, R)
703db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
704db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, public) = true
705db73c684ba61fed4087af488e8610657ec638c17John McCall///   ACAB(n) = public
706db73c684ba61fed4087af488e8610657ec638c17John McCall///   ACAB(i) =
707db73c684ba61fed4087af488e8610657ec638c17John McCall///     let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
708db73c684ba61fed4087af488e8610657ec638c17John McCall///     if Accessible(B_i, AccessToBase) then public else AccessToBase
709db73c684ba61fed4087af488e8610657ec638c17John McCall///
710db73c684ba61fed4087af488e8610657ec638c17John McCall/// B is an accessible base of N at R iff ACAB(1) = public.
711db73c684ba61fed4087af488e8610657ec638c17John McCall///
712161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// \param FinalAccess the access of the "final step", or AS_public if
7137aceaf8cee77c98478e8934dc283910292711a7eJohn McCall///   there is no final step.
7146b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \return null if friendship is dependent
7156b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstatic CXXBasePath *FindBestPath(Sema &S,
7166b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                 const EffectiveContext &EC,
717161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 AccessTarget &Target,
7187aceaf8cee77c98478e8934dc283910292711a7eJohn McCall                                 AccessSpecifier FinalAccess,
7196b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                 CXXBasePaths &Paths) {
7206b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // Derive the paths to the desired base.
721161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *Derived = Target.getNamingClass();
722161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *Base = Target.getDeclaringClass();
723161755a09898c95d21bfff33707da9ca41cd53c5John McCall
724161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // FIXME: fail correctly when there are dependent paths.
725161755a09898c95d21bfff33707da9ca41cd53c5John McCall  bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
726161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                          Paths);
7276b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  assert(isDerived && "derived class not actually derived from base");
7286b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  (void) isDerived;
7296b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
7306b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXBasePath *BestPath = 0;
7316b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
7327aceaf8cee77c98478e8934dc283910292711a7eJohn McCall  assert(FinalAccess != AS_none && "forbidden access after declaring class");
7337aceaf8cee77c98478e8934dc283910292711a7eJohn McCall
7340c01d18094100db92d38daa923c95661512db203John McCall  bool AnyDependent = false;
7350c01d18094100db92d38daa923c95661512db203John McCall
7366b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // Derive the friend-modified access along each path.
7376b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
7386b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall         PI != PE; ++PI) {
739161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
7406b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
7416b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // Walk through the path backwards.
7427aceaf8cee77c98478e8934dc283910292711a7eJohn McCall    AccessSpecifier PathAccess = FinalAccess;
7436b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    CXXBasePath::iterator I = PI->end(), E = PI->begin();
7446b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    while (I != E) {
7456b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      --I;
7466b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
7477aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      assert(PathAccess != AS_none);
7487aceaf8cee77c98478e8934dc283910292711a7eJohn McCall
7497aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      // If the declaration is a private member of a base class, there
7507aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      // is no level of friendship in derived classes that can make it
7517aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      // accessible.
7527aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      if (PathAccess == AS_private) {
7537aceaf8cee77c98478e8934dc283910292711a7eJohn McCall        PathAccess = AS_none;
7547aceaf8cee77c98478e8934dc283910292711a7eJohn McCall        break;
7557aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      }
7567aceaf8cee77c98478e8934dc283910292711a7eJohn McCall
757161755a09898c95d21bfff33707da9ca41cd53c5John McCall      const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
758161755a09898c95d21bfff33707da9ca41cd53c5John McCall
7596b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
760db73c684ba61fed4087af488e8610657ec638c17John McCall      PathAccess = std::max(PathAccess, BaseAccess);
761161755a09898c95d21bfff33707da9ca41cd53c5John McCall
762161755a09898c95d21bfff33707da9ca41cd53c5John McCall      switch (HasAccess(S, EC, NC, PathAccess, Target)) {
763161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_inaccessible: break;
764161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_accessible:
765161755a09898c95d21bfff33707da9ca41cd53c5John McCall        PathAccess = AS_public;
766161755a09898c95d21bfff33707da9ca41cd53c5John McCall
767161755a09898c95d21bfff33707da9ca41cd53c5John McCall        // Future tests are not against members and so do not have
768161755a09898c95d21bfff33707da9ca41cd53c5John McCall        // instance context.
769161755a09898c95d21bfff33707da9ca41cd53c5John McCall        Target.suppressInstanceContext();
770161755a09898c95d21bfff33707da9ca41cd53c5John McCall        break;
771161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_dependent:
772db73c684ba61fed4087af488e8610657ec638c17John McCall        AnyDependent = true;
773db73c684ba61fed4087af488e8610657ec638c17John McCall        goto Next;
774c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson      }
775c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson    }
776726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
7776b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // Note that we modify the path's Access field to the
7786b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // friend-modified access.
7796b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    if (BestPath == 0 || PathAccess < BestPath->Access) {
7806b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      BestPath = &*PI;
7816b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      BestPath->Access = PathAccess;
7820c01d18094100db92d38daa923c95661512db203John McCall
7830c01d18094100db92d38daa923c95661512db203John McCall      // Short-circuit if we found a public path.
7840c01d18094100db92d38daa923c95661512db203John McCall      if (BestPath->Access == AS_public)
7850c01d18094100db92d38daa923c95661512db203John McCall        return BestPath;
786c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson    }
7870c01d18094100db92d38daa923c95661512db203John McCall
7880c01d18094100db92d38daa923c95661512db203John McCall  Next: ;
789c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson  }
790c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson
7910c01d18094100db92d38daa923c95661512db203John McCall  assert((!BestPath || BestPath->Access != AS_public) &&
7920c01d18094100db92d38daa923c95661512db203John McCall         "fell out of loop with public path");
7930c01d18094100db92d38daa923c95661512db203John McCall
7940c01d18094100db92d38daa923c95661512db203John McCall  // We didn't find a public path, but at least one path was subject
7950c01d18094100db92d38daa923c95661512db203John McCall  // to dependent friendship, so delay the check.
7960c01d18094100db92d38daa923c95661512db203John McCall  if (AnyDependent)
7970c01d18094100db92d38daa923c95661512db203John McCall    return 0;
7980c01d18094100db92d38daa923c95661512db203John McCall
7996b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  return BestPath;
800726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl}
801726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
8026b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Diagnose the path which caused the given declaration or base class
8036b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// to become inaccessible.
8046b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstatic void DiagnoseAccessPath(Sema &S,
8056b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                               const EffectiveContext &EC,
806161755a09898c95d21bfff33707da9ca41cd53c5John McCall                               AccessTarget &Entity) {
807db73c684ba61fed4087af488e8610657ec638c17John McCall  AccessSpecifier Access = Entity.getAccess();
808161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
809db73c684ba61fed4087af488e8610657ec638c17John McCall  NamingClass = NamingClass->getCanonicalDecl();
810db73c684ba61fed4087af488e8610657ec638c17John McCall
811161755a09898c95d21bfff33707da9ca41cd53c5John McCall  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);
812161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
813db73c684ba61fed4087af488e8610657ec638c17John McCall
8146b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // Easy case: the decl's natural access determined its path access.
8156b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // We have to check against AS_private here in case Access is AS_none,
8166b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // indicating a non-public member of a private base class.
8176b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (D && (Access == D->getAccess() || D->getAccess() == AS_private)) {
818161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (HasAccess(S, EC, DeclaringClass, D->getAccess(), Entity)) {
819161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: {
8206b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      S.Diag(D->getLocation(), diag::note_access_natural)
8216b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall        << (unsigned) (Access == AS_protected)
8226b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall        << /*FIXME: not implicitly*/ 0;
8236b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      return;
8246b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
825726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
826161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible: break;
827726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
828161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
829161755a09898c95d21bfff33707da9ca41cd53c5John McCall      llvm_unreachable("can't diagnose dependent access failures");
8306b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      return;
8316b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
8326b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
833c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson
8346b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXBasePaths Paths;
835161755a09898c95d21bfff33707da9ca41cd53c5John McCall  CXXBasePath &Path = *FindBestPath(S, EC, Entity, AS_public, Paths);
836726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
8376b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXBasePath::iterator I = Path.end(), E = Path.begin();
8386b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  while (I != E) {
8396b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    --I;
840c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson
8416b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    const CXXBaseSpecifier *BS = I->Base;
8426b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    AccessSpecifier BaseAccess = BS->getAccessSpecifier();
8436b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
8446b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // If this is public inheritance, or the derived class is a friend,
8456b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // skip this step.
8466b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    if (BaseAccess == AS_public)
8476b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      continue;
8486b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
8496b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    switch (GetFriendKind(S, EC, I->Class)) {
850161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible: continue;
851161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: break;
852161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
853161755a09898c95d21bfff33707da9ca41cd53c5John McCall      llvm_unreachable("can't diagnose dependent access failures");
8546b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
8556b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
8566b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // Check whether this base specifier is the tighest point
8576b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // constraining access.  We have to check against AS_private for
8586b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // the same reasons as above.
8596b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    if (BaseAccess == AS_private || BaseAccess >= Access) {
8606b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
8616b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      // We're constrained by inheritance, but we want to say
8626b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      // "declared private here" if we're diagnosing a hierarchy
8636b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      // conversion and this is the final step.
8646b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      unsigned diagnostic;
8656b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      if (D) diagnostic = diag::note_access_constrained_by_path;
8666b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      else if (I + 1 == Path.end()) diagnostic = diag::note_access_natural;
8676b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      else diagnostic = diag::note_access_constrained_by_path;
8686b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
8696b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      S.Diag(BS->getSourceRange().getBegin(), diagnostic)
8706b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall        << BS->getSourceRange()
8716b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall        << (BaseAccess == AS_protected)
8726b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall        << (BS->getAccessSpecifierAsWritten() == AS_none);
87376ef658c703faf72c00f324fb9edc03169718e3eDouglas Gregor
87476ef658c703faf72c00f324fb9edc03169718e3eDouglas Gregor      if (D)
87576ef658c703faf72c00f324fb9edc03169718e3eDouglas Gregor        S.Diag(D->getLocation(), diag::note_field_decl);
87676ef658c703faf72c00f324fb9edc03169718e3eDouglas Gregor
8776b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      return;
8786b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
879c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson  }
880726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
8816b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  llvm_unreachable("access not apparently constrained by path");
88229f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson}
88392f883177b162928a8e632e4e3b93fafd2b26072John McCall
884db73c684ba61fed4087af488e8610657ec638c17John McCallstatic void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
885db73c684ba61fed4087af488e8610657ec638c17John McCall                              const EffectiveContext &EC,
886161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              AccessTarget &Entity) {
887db73c684ba61fed4087af488e8610657ec638c17John McCall  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
888161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
889161755a09898c95d21bfff33707da9ca41cd53c5John McCall  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);
8906b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
89158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  S.Diag(Loc, Entity.getDiag())
892db73c684ba61fed4087af488e8610657ec638c17John McCall    << (Entity.getAccess() == AS_protected)
893db73c684ba61fed4087af488e8610657ec638c17John McCall    << (D ? D->getDeclName() : DeclarationName())
89458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << S.Context.getTypeDeclType(NamingClass)
89558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << S.Context.getTypeDeclType(DeclaringClass);
896db73c684ba61fed4087af488e8610657ec638c17John McCall  DiagnoseAccessPath(S, EC, Entity);
8976b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
89892f883177b162928a8e632e4e3b93fafd2b26072John McCall
899db73c684ba61fed4087af488e8610657ec638c17John McCall/// Determines whether the accessed entity is accessible.  Public members
900db73c684ba61fed4087af488e8610657ec638c17John McCall/// have been weeded out by this point.
901161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult IsAccessible(Sema &S,
902161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 const EffectiveContext &EC,
903161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 AccessTarget &Entity) {
904db73c684ba61fed4087af488e8610657ec638c17John McCall  // Determine the actual naming class.
905db73c684ba61fed4087af488e8610657ec638c17John McCall  CXXRecordDecl *NamingClass = Entity.getNamingClass();
906db73c684ba61fed4087af488e8610657ec638c17John McCall  while (NamingClass->isAnonymousStructOrUnion())
907db73c684ba61fed4087af488e8610657ec638c17John McCall    NamingClass = cast<CXXRecordDecl>(NamingClass->getParent());
908db73c684ba61fed4087af488e8610657ec638c17John McCall  NamingClass = NamingClass->getCanonicalDecl();
90992f883177b162928a8e632e4e3b93fafd2b26072John McCall
910db73c684ba61fed4087af488e8610657ec638c17John McCall  AccessSpecifier UnprivilegedAccess = Entity.getAccess();
911db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(UnprivilegedAccess != AS_public && "public access not weeded out");
91292f883177b162928a8e632e4e3b93fafd2b26072John McCall
913db73c684ba61fed4087af488e8610657ec638c17John McCall  // Before we try to recalculate access paths, try to white-list
914db73c684ba61fed4087af488e8610657ec638c17John McCall  // accesses which just trade in on the final step, i.e. accesses
915db73c684ba61fed4087af488e8610657ec638c17John McCall  // which don't require [M4] or [B4]. These are by far the most
916161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // common forms of privileged access.
917db73c684ba61fed4087af488e8610657ec638c17John McCall  if (UnprivilegedAccess != AS_none) {
918161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
919161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
920db73c684ba61fed4087af488e8610657ec638c17John McCall      // This is actually an interesting policy decision.  We don't
921db73c684ba61fed4087af488e8610657ec638c17John McCall      // *have* to delay immediately here: we can do the full access
922db73c684ba61fed4087af488e8610657ec638c17John McCall      // calculation in the hope that friendship on some intermediate
923db73c684ba61fed4087af488e8610657ec638c17John McCall      // class will make the declaration accessible non-dependently.
924db73c684ba61fed4087af488e8610657ec638c17John McCall      // But that's not cheap, and odds are very good (note: assertion
925db73c684ba61fed4087af488e8610657ec638c17John McCall      // made without data) that the friend declaration will determine
926db73c684ba61fed4087af488e8610657ec638c17John McCall      // access.
927161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_dependent;
928db73c684ba61fed4087af488e8610657ec638c17John McCall
929161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible: return AR_accessible;
930161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: break;
931db73c684ba61fed4087af488e8610657ec638c17John McCall    }
932db73c684ba61fed4087af488e8610657ec638c17John McCall  }
93392f883177b162928a8e632e4e3b93fafd2b26072John McCall
934161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
935db73c684ba61fed4087af488e8610657ec638c17John McCall
936db73c684ba61fed4087af488e8610657ec638c17John McCall  // We lower member accesses to base accesses by pretending that the
937db73c684ba61fed4087af488e8610657ec638c17John McCall  // member is a base class of its declaring class.
938db73c684ba61fed4087af488e8610657ec638c17John McCall  AccessSpecifier FinalAccess;
9396b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
9406b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (Entity.isMemberAccess()) {
941db73c684ba61fed4087af488e8610657ec638c17John McCall    // Determine if the declaration is accessible from EC when named
942db73c684ba61fed4087af488e8610657ec638c17John McCall    // in its declaring class.
9436b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    NamedDecl *Target = Entity.getTargetDecl();
944161755a09898c95d21bfff33707da9ca41cd53c5John McCall    const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
9456b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
946db73c684ba61fed4087af488e8610657ec638c17John McCall    FinalAccess = Target->getAccess();
947161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
948161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible:
949161755a09898c95d21bfff33707da9ca41cd53c5John McCall      FinalAccess = AS_public;
950161755a09898c95d21bfff33707da9ca41cd53c5John McCall      break;
951161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: break;
952161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent: return AR_dependent; // see above
9536b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
9542f514480c448708ec382a684cf5e035d3a827ec8John McCall
955db73c684ba61fed4087af488e8610657ec638c17John McCall    if (DeclaringClass == NamingClass)
956161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
957161755a09898c95d21bfff33707da9ca41cd53c5John McCall
958161755a09898c95d21bfff33707da9ca41cd53c5John McCall    Entity.suppressInstanceContext();
959db73c684ba61fed4087af488e8610657ec638c17John McCall  } else {
960db73c684ba61fed4087af488e8610657ec638c17John McCall    FinalAccess = AS_public;
9616b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
9622f514480c448708ec382a684cf5e035d3a827ec8John McCall
963161755a09898c95d21bfff33707da9ca41cd53c5John McCall  assert(Entity.getDeclaringClass() != NamingClass);
9646b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
9656b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // Append the declaration's access if applicable.
9666b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXBasePaths Paths;
967161755a09898c95d21bfff33707da9ca41cd53c5John McCall  CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
9680c01d18094100db92d38daa923c95661512db203John McCall  if (!Path)
969161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_dependent;
97092f883177b162928a8e632e4e3b93fafd2b26072John McCall
971db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(Path->Access <= UnprivilegedAccess &&
972db73c684ba61fed4087af488e8610657ec638c17John McCall         "access along best path worse than direct?");
973db73c684ba61fed4087af488e8610657ec638c17John McCall  if (Path->Access == AS_public)
974161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_accessible;
975161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return AR_inaccessible;
9760c01d18094100db92d38daa923c95661512db203John McCall}
9770c01d18094100db92d38daa923c95661512db203John McCall
978161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic void DelayDependentAccess(Sema &S,
979161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 const EffectiveContext &EC,
980161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 SourceLocation Loc,
981161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 const AccessTarget &Entity) {
9820c01d18094100db92d38daa923c95661512db203John McCall  assert(EC.isDependent() && "delaying non-dependent access");
9837ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  DeclContext *DC = EC.getInnerContext();
9840c01d18094100db92d38daa923c95661512db203John McCall  assert(DC->isDependentContext() && "delaying non-dependent access");
9850c01d18094100db92d38daa923c95661512db203John McCall  DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access,
9860c01d18094100db92d38daa923c95661512db203John McCall                              Loc,
9870c01d18094100db92d38daa923c95661512db203John McCall                              Entity.isMemberAccess(),
9880c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getAccess(),
9890c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getTargetDecl(),
9900c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getNamingClass(),
991161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              Entity.getBaseObjectType(),
9920c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getDiag());
9936b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
9946b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
9956b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Checks access to an entity from the given effective context.
996161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult CheckEffectiveAccess(Sema &S,
997161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                         const EffectiveContext &EC,
998161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                         SourceLocation Loc,
999161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                         AccessTarget &Entity) {
1000db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(Entity.getAccess() != AS_public && "called for public access!");
100192f883177b162928a8e632e4e3b93fafd2b26072John McCall
1002db73c684ba61fed4087af488e8610657ec638c17John McCall  switch (IsAccessible(S, EC, Entity)) {
1003161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_dependent:
1004161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DelayDependentAccess(S, EC, Loc, Entity);
1005161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_dependent;
10060c01d18094100db92d38daa923c95661512db203John McCall
1007161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_inaccessible:
1008db73c684ba61fed4087af488e8610657ec638c17John McCall    if (!Entity.isQuiet())
1009db73c684ba61fed4087af488e8610657ec638c17John McCall      DiagnoseBadAccess(S, Loc, EC, Entity);
1010161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_inaccessible;
101192f883177b162928a8e632e4e3b93fafd2b26072John McCall
1012161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_accessible:
1013161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_accessible;
1014db73c684ba61fed4087af488e8610657ec638c17John McCall  }
1015db73c684ba61fed4087af488e8610657ec638c17John McCall
1016161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // silence unnecessary warning
1017161755a09898c95d21bfff33707da9ca41cd53c5John McCall  llvm_unreachable("invalid access result");
1018161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return AR_accessible;
10196b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
102092f883177b162928a8e632e4e3b93fafd2b26072John McCall
10216b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstatic Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
1022161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                      AccessTarget &Entity) {
10236b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // If the access path is public, it's accessible everywhere.
10246b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (Entity.getAccess() == AS_public)
10256b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return Sema::AR_accessible;
102692f883177b162928a8e632e4e3b93fafd2b26072John McCall
10276b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // If we're currently parsing a top-level declaration, delay
10286b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // diagnostics.  This is the only case where parsing a declaration
10296b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // can actually change our effective context for the purposes of
10306b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // access control.
10316b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (S.CurContext->isFileContext() && S.ParsingDeclDepth) {
10326b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    S.DelayedDiagnostics.push_back(
10336b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall        Sema::DelayedDiagnostic::makeAccess(Loc, Entity));
10346b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return Sema::AR_delayed;
103592f883177b162928a8e632e4e3b93fafd2b26072John McCall  }
103692f883177b162928a8e632e4e3b93fafd2b26072John McCall
1037161755a09898c95d21bfff33707da9ca41cd53c5John McCall  EffectiveContext EC(S.CurContext);
1038161755a09898c95d21bfff33707da9ca41cd53c5John McCall  switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
1039161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_accessible: return Sema::AR_accessible;
1040161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_inaccessible: return Sema::AR_inaccessible;
1041161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_dependent: return Sema::AR_dependent;
1042161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
1043161755a09898c95d21bfff33707da9ca41cd53c5John McCall  llvm_unreachable("falling off end");
1044161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return Sema::AR_accessible;
104592f883177b162928a8e632e4e3b93fafd2b26072John McCall}
104692f883177b162928a8e632e4e3b93fafd2b26072John McCall
10472f514480c448708ec382a684cf5e035d3a827ec8John McCallvoid Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *Ctx) {
10482f514480c448708ec382a684cf5e035d3a827ec8John McCall  // Pretend we did this from the context of the newly-parsed
1049630eb01b2568d0958118eb1a0ded02bebecb2b0fChandler Carruth  // declaration. If that declaration itself forms a declaration context,
1050630eb01b2568d0958118eb1a0ded02bebecb2b0fChandler Carruth  // include it in the effective context so that parameters and return types of
1051630eb01b2568d0958118eb1a0ded02bebecb2b0fChandler Carruth  // befriended functions have that function's access priveledges.
1052630eb01b2568d0958118eb1a0ded02bebecb2b0fChandler Carruth  DeclContext *DC = Ctx->getDeclContext();
1053630eb01b2568d0958118eb1a0ded02bebecb2b0fChandler Carruth  if (isa<FunctionDecl>(Ctx))
1054630eb01b2568d0958118eb1a0ded02bebecb2b0fChandler Carruth    DC = cast<DeclContext>(Ctx);
1055630eb01b2568d0958118eb1a0ded02bebecb2b0fChandler Carruth  else if (FunctionTemplateDecl *FnTpl = dyn_cast<FunctionTemplateDecl>(Ctx))
1056630eb01b2568d0958118eb1a0ded02bebecb2b0fChandler Carruth    DC = cast<DeclContext>(FnTpl->getTemplatedDecl());
1057630eb01b2568d0958118eb1a0ded02bebecb2b0fChandler Carruth  EffectiveContext EC(DC);
10582f514480c448708ec382a684cf5e035d3a827ec8John McCall
1059161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Target(DD.getAccessData());
1060161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1061161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
10622f514480c448708ec382a684cf5e035d3a827ec8John McCall    DD.Triggered = true;
10632f514480c448708ec382a684cf5e035d3a827ec8John McCall}
10642f514480c448708ec382a684cf5e035d3a827ec8John McCall
10650c01d18094100db92d38daa923c95661512db203John McCallvoid Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD,
10660c01d18094100db92d38daa923c95661512db203John McCall                        const MultiLevelTemplateArgumentList &TemplateArgs) {
10670c01d18094100db92d38daa923c95661512db203John McCall  SourceLocation Loc = DD.getAccessLoc();
10680c01d18094100db92d38daa923c95661512db203John McCall  AccessSpecifier Access = DD.getAccess();
10690c01d18094100db92d38daa923c95661512db203John McCall
10700c01d18094100db92d38daa923c95661512db203John McCall  Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
10710c01d18094100db92d38daa923c95661512db203John McCall                                       TemplateArgs);
10720c01d18094100db92d38daa923c95661512db203John McCall  if (!NamingD) return;
10730c01d18094100db92d38daa923c95661512db203John McCall  Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
10740c01d18094100db92d38daa923c95661512db203John McCall                                       TemplateArgs);
10750c01d18094100db92d38daa923c95661512db203John McCall  if (!TargetD) return;
10760c01d18094100db92d38daa923c95661512db203John McCall
10770c01d18094100db92d38daa923c95661512db203John McCall  if (DD.isAccessToMember()) {
1078161755a09898c95d21bfff33707da9ca41cd53c5John McCall    CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
1079161755a09898c95d21bfff33707da9ca41cd53c5John McCall    NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1080161755a09898c95d21bfff33707da9ca41cd53c5John McCall    QualType BaseObjectType = DD.getAccessBaseObjectType();
1081161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (!BaseObjectType.isNull()) {
1082161755a09898c95d21bfff33707da9ca41cd53c5John McCall      BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1083161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 DeclarationName());
1084161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (BaseObjectType.isNull()) return;
1085161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
1086161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1087161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget Entity(Context,
1088161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        AccessTarget::Member,
1089161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        NamingClass,
1090161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        DeclAccessPair::make(TargetDecl, Access),
1091161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        BaseObjectType);
10920c01d18094100db92d38daa923c95661512db203John McCall    Entity.setDiag(DD.getDiagnostic());
10930c01d18094100db92d38daa923c95661512db203John McCall    CheckAccess(*this, Loc, Entity);
10940c01d18094100db92d38daa923c95661512db203John McCall  } else {
1095161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget Entity(Context,
1096161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        AccessTarget::Base,
1097161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        cast<CXXRecordDecl>(TargetD),
1098161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        cast<CXXRecordDecl>(NamingD),
1099161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        Access);
11000c01d18094100db92d38daa923c95661512db203John McCall    Entity.setDiag(DD.getDiagnostic());
11010c01d18094100db92d38daa923c95661512db203John McCall    CheckAccess(*this, Loc, Entity);
11020c01d18094100db92d38daa923c95661512db203John McCall  }
11030c01d18094100db92d38daa923c95661512db203John McCall}
11040c01d18094100db92d38daa923c95661512db203John McCall
11056b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
11069aa472c45d2bd81b7b52c225e8acc560d716db97John McCall                                                     DeclAccessPair Found) {
110758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  if (!getLangOptions().AccessControl ||
110858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall      !E->getNamingClass() ||
11099aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
11106b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
1111c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
1112161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1113161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      Found, QualType());
111458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(diag::err_access) << E->getSourceRange();
111558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
111658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, E->getNameLoc(), Entity);
1117c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall}
1118c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
1119c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall/// Perform access-control checking on a previously-unresolved member
1120c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall/// access which has now been resolved to a member.
11216b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
11229aa472c45d2bd81b7b52c225e8acc560d716db97John McCall                                                     DeclAccessPair Found) {
112358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  if (!getLangOptions().AccessControl ||
11249aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
11256b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
1126c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
1127161755a09898c95d21bfff33707da9ca41cd53c5John McCall  QualType BaseType = E->getBaseType();
1128161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (E->isArrow())
1129161755a09898c95d21bfff33707da9ca41cd53c5John McCall    BaseType = BaseType->getAs<PointerType>()->getPointeeType();
1130161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1131161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1132161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      Found, BaseType);
113358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(diag::err_access) << E->getSourceRange();
113458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
113558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, E->getMemberLoc(), Entity);
1136c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall}
1137c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
11386b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
113958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                               CXXDestructorDecl *Dtor,
114058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                               const PartialDiagnostic &PDiag) {
11414f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall  if (!getLangOptions().AccessControl)
11426b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
11434f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall
114458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // There's never a path involved when checking implicit destructor access.
11454f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall  AccessSpecifier Access = Dtor->getAccess();
11464f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall  if (Access == AS_public)
11476b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
11484f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall
114958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  CXXRecordDecl *NamingClass = Dtor->getParent();
1150161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1151161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      DeclAccessPair::make(Dtor, Access),
1152161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      QualType());
115358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(PDiag); // TODO: avoid copy
115458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
115558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, Loc, Entity);
11564f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall}
11574f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall
1158b13b737a2450167c82e148590e8019b839ce6b98John McCall/// Checks access to a constructor.
11596b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
116057d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                CXXConstructorDecl *Constructor,
116157d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                const InitializedEntity &Entity,
116257d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                AccessSpecifier Access,
116357d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                bool IsCopyBindingRefToTemp) {
116458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  if (!getLangOptions().AccessControl ||
116558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall      Access == AS_public)
11666b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
1167b13b737a2450167c82e148590e8019b839ce6b98John McCall
11686b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXRecordDecl *NamingClass = Constructor->getParent();
11699a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson  AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass,
11709a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson                            DeclAccessPair::make(Constructor, Access),
11719a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson                            QualType());
11729a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson  switch (Entity.getKind()) {
11739a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson  default:
117457d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin    AccessEntity.setDiag(IsCopyBindingRefToTemp
117557d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                         ? diag::ext_rvalue_to_reference_access_ctor
117657d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                         : diag::err_access_ctor);
11779a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson    break;
11789a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson
11793b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson  case InitializedEntity::EK_Base:
11803b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson    AccessEntity.setDiag(PDiag(diag::err_access_base)
11813b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson                          << Entity.isInheritedVirtualBase()
11823b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson                          << Entity.getBaseSpecifier()->getType()
11833b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson                          << getSpecialMember(Constructor));
11849a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson    break;
11853b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson
1186b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson  case InitializedEntity::EK_Member: {
1187b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson    const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
11880e313bd4795c005f23c43f127039fd948c3e0bd9Anders Carlsson    AccessEntity.setDiag(PDiag(diag::err_access_field)
11890e313bd4795c005f23c43f127039fd948c3e0bd9Anders Carlsson                          << Field->getType()
11900e313bd4795c005f23c43f127039fd948c3e0bd9Anders Carlsson                          << getSpecialMember(Constructor));
1191b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson    break;
1192b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson  }
119358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
1194711f34adb886cce8ba86c7b1b6513a1eaaf63bb5Anders Carlsson  }
1195711f34adb886cce8ba86c7b1b6513a1eaaf63bb5Anders Carlsson
11969a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson  return CheckAccess(*this, UseLoc, AccessEntity);
1197b13b737a2450167c82e148590e8019b839ce6b98John McCall}
1198b13b737a2450167c82e148590e8019b839ce6b98John McCall
1199b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall/// Checks direct (i.e. non-inherited) access to an arbitrary class
1200b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall/// member.
1201b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCallSema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc,
1202b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall                                                 NamedDecl *Target,
1203b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall                                           const PartialDiagnostic &Diag) {
1204b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall  AccessSpecifier Access = Target->getAccess();
1205b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall  if (!getLangOptions().AccessControl ||
1206b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall      Access == AS_public)
1207b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall    return AR_accessible;
1208b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall
1209b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Target->getDeclContext());
1210161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1211161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      DeclAccessPair::make(Target, Access),
1212161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      QualType());
1213b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall  Entity.setDiag(Diag);
1214b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall  return CheckAccess(*this, UseLoc, Entity);
1215b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall}
1216b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall
1217b020748a9954c995f2e616f50bb9ed4fe2df1f72John McCall
121890c8c57bcd84083df85f76aac2aa62acb85eb077John McCall/// Checks access to an overloaded operator new or delete.
121990c8c57bcd84083df85f76aac2aa62acb85eb077John McCallSema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
122090c8c57bcd84083df85f76aac2aa62acb85eb077John McCall                                               SourceRange PlacementRange,
122190c8c57bcd84083df85f76aac2aa62acb85eb077John McCall                                               CXXRecordDecl *NamingClass,
12229aa472c45d2bd81b7b52c225e8acc560d716db97John McCall                                               DeclAccessPair Found) {
122390c8c57bcd84083df85f76aac2aa62acb85eb077John McCall  if (!getLangOptions().AccessControl ||
122490c8c57bcd84083df85f76aac2aa62acb85eb077John McCall      !NamingClass ||
12259aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
122690c8c57bcd84083df85f76aac2aa62acb85eb077John McCall    return AR_accessible;
122790c8c57bcd84083df85f76aac2aa62acb85eb077John McCall
1228161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1229161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      QualType());
123090c8c57bcd84083df85f76aac2aa62acb85eb077John McCall  Entity.setDiag(diag::err_access)
123190c8c57bcd84083df85f76aac2aa62acb85eb077John McCall    << PlacementRange;
123290c8c57bcd84083df85f76aac2aa62acb85eb077John McCall
123390c8c57bcd84083df85f76aac2aa62acb85eb077John McCall  return CheckAccess(*this, OpLoc, Entity);
123490c8c57bcd84083df85f76aac2aa62acb85eb077John McCall}
123590c8c57bcd84083df85f76aac2aa62acb85eb077John McCall
1236b13b737a2450167c82e148590e8019b839ce6b98John McCall/// Checks access to an overloaded member operator, including
1237b13b737a2450167c82e148590e8019b839ce6b98John McCall/// conversion operators.
12386b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
12396b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                                   Expr *ObjectExpr,
124058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                                   Expr *ArgExpr,
12419aa472c45d2bd81b7b52c225e8acc560d716db97John McCall                                                   DeclAccessPair Found) {
124258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  if (!getLangOptions().AccessControl ||
12439aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
12446b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
12455357b615364c17ea024c757354c58ae2a520d216John McCall
12465357b615364c17ea024c757354c58ae2a520d216John McCall  const RecordType *RT = ObjectExpr->getType()->getAs<RecordType>();
12475357b615364c17ea024c757354c58ae2a520d216John McCall  assert(RT && "found member operator but object expr not of record type");
12485357b615364c17ea024c757354c58ae2a520d216John McCall  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
12495357b615364c17ea024c757354c58ae2a520d216John McCall
1250161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1251161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      ObjectExpr->getType());
125258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(diag::err_access)
125358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << ObjectExpr->getSourceRange()
125458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange());
125558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
125658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, OpLoc, Entity);
12576b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
12585357b615364c17ea024c757354c58ae2a520d216John McCall
12596bb8017bb9e828d118e15e59d71c66bba323c364John McCallSema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
12606bb8017bb9e828d118e15e59d71c66bba323c364John McCall                                                    DeclAccessPair Found) {
12616bb8017bb9e828d118e15e59d71c66bba323c364John McCall  if (!getLangOptions().AccessControl ||
1262e2f5ba9d80cfadbb3e1dafb9f375eb526f669b85John McCall      Found.getAccess() == AS_none ||
12636bb8017bb9e828d118e15e59d71c66bba323c364John McCall      Found.getAccess() == AS_public)
12646bb8017bb9e828d118e15e59d71c66bba323c364John McCall    return AR_accessible;
12656bb8017bb9e828d118e15e59d71c66bba323c364John McCall
12666bb8017bb9e828d118e15e59d71c66bba323c364John McCall  OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).getPointer();
1267e9ee23edd17c4bb7f271e67f8790792b4de677fcJohn McCall  CXXRecordDecl *NamingClass = Ovl->getNamingClass();
12686bb8017bb9e828d118e15e59d71c66bba323c364John McCall
1269161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1270161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      Context.getTypeDeclType(NamingClass));
12716bb8017bb9e828d118e15e59d71c66bba323c364John McCall  Entity.setDiag(diag::err_access)
12726bb8017bb9e828d118e15e59d71c66bba323c364John McCall    << Ovl->getSourceRange();
12736bb8017bb9e828d118e15e59d71c66bba323c364John McCall
12746bb8017bb9e828d118e15e59d71c66bba323c364John McCall  return CheckAccess(*this, Ovl->getNameLoc(), Entity);
12756bb8017bb9e828d118e15e59d71c66bba323c364John McCall}
12766bb8017bb9e828d118e15e59d71c66bba323c364John McCall
12776b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Checks access for a hierarchy conversion.
12786b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///
12796b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \param IsBaseToDerived whether this is a base-to-derived conversion (true)
12806b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///     or a derived-to-base conversion (false)
12816b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \param ForceCheck true if this check should be performed even if access
12826b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///     control is disabled;  some things rely on this for semantics
12836b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \param ForceUnprivileged true if this check should proceed as if the
12846b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///     context had no special privileges
12856b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \param ADK controls the kind of diagnostics that are used
12866b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
12876b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              QualType Base,
12886b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              QualType Derived,
12896b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              const CXXBasePath &Path,
129058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                              unsigned DiagID,
12916b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              bool ForceCheck,
129258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                              bool ForceUnprivileged) {
12936b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (!ForceCheck && !getLangOptions().AccessControl)
12946b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
12956b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
12966b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (Path.Access == AS_public)
12976b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
12986b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
12996b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXRecordDecl *BaseD, *DerivedD;
13006b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  BaseD = cast<CXXRecordDecl>(Base->getAs<RecordType>()->getDecl());
13016b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  DerivedD = cast<CXXRecordDecl>(Derived->getAs<RecordType>()->getDecl());
130258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
1303161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
1304161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      Path.Access);
130558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  if (DiagID)
130658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    Entity.setDiag(DiagID) << Derived << Base;
13076b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1308161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (ForceUnprivileged) {
1309161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (CheckEffectiveAccess(*this, EffectiveContext(),
1310161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 AccessLoc, Entity)) {
1311161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case ::AR_accessible: return Sema::AR_accessible;
1312161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case ::AR_inaccessible: return Sema::AR_inaccessible;
1313161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case ::AR_dependent: return Sema::AR_dependent;
1314161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
1315161755a09898c95d21bfff33707da9ca41cd53c5John McCall    llvm_unreachable("unexpected result from CheckEffectiveAccess");
1316161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
131758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, AccessLoc, Entity);
13185357b615364c17ea024c757354c58ae2a520d216John McCall}
13195357b615364c17ea024c757354c58ae2a520d216John McCall
132092f883177b162928a8e632e4e3b93fafd2b26072John McCall/// Checks access to all the declarations in the given result set.
13216b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallvoid Sema::CheckLookupAccess(const LookupResult &R) {
13226b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  assert(getLangOptions().AccessControl
13236b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall         && "performing access check without access control");
13246b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  assert(R.getNamingClass() && "performing access check without naming class");
13256b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
132658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
132758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    if (I.getAccess() != AS_public) {
1328161755a09898c95d21bfff33707da9ca41cd53c5John McCall      AccessTarget Entity(Context, AccessedEntity::Member,
1329161755a09898c95d21bfff33707da9ca41cd53c5John McCall                          R.getNamingClass(), I.getPair(),
1330161755a09898c95d21bfff33707da9ca41cd53c5John McCall                          R.getBaseObjectType());
133158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall      Entity.setDiag(diag::err_access);
133258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
133358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall      CheckAccess(*this, R.getNameLoc(), Entity);
133458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    }
133558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  }
133692f883177b162928a8e632e4e3b93fafd2b26072John McCall}
1337