129f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson//===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===//
260d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//
360d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//                     The LLVM Compiler Infrastructure
460d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//
560d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson// This file is distributed under the University of Illinois Open Source
660d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson// License. See LICENSE.TXT for details.
760d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//
860d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//===----------------------------------------------------------------------===//
960d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//
1060d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson// This file provides Sema routines for C++ access control semantics.
1160d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//
1260d6b0d35e3c7c09554f8a4618b97a5d8d0c67a6Anders Carlsson//===----------------------------------------------------------------------===//
13c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson
142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h"
15c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson#include "clang/AST/ASTContext.h"
16a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor#include "clang/AST/CXXInheritance.h"
17a8f32e0965ee19ecc53cd796e34268377a20357cDouglas Gregor#include "clang/AST/DeclCXX.h"
18d60e22e601852ae1345f01514318a0951dc09f89John McCall#include "clang/AST/DeclFriend.h"
19f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor#include "clang/AST/DeclObjC.h"
200c01d18094100db92d38daa923c95661512db203John McCall#include "clang/AST/DependentDiagnostic.h"
21c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall#include "clang/AST/ExprCXX.h"
2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/DelayedDiagnostic.h"
2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Initialization.h"
2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Lookup.h"
25c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
26c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlssonusing namespace clang;
279c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallusing namespace sema;
28c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson
29161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// A copy of Sema's enum without AR_delayed.
30161755a09898c95d21bfff33707da9ca41cd53c5John McCallenum AccessResult {
31161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AR_accessible,
32161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AR_inaccessible,
33161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AR_dependent
34161755a09898c95d21bfff33707da9ca41cd53c5John McCall};
35161755a09898c95d21bfff33707da9ca41cd53c5John McCall
3629f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson/// SetMemberAccessSpecifier - Set the access specifier of a member.
3729f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson/// Returns true on error (when the previous member decl access specifier
3829f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson/// is different from the new member decl access specifier).
391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpbool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
40c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson                                    NamedDecl *PrevMemberDecl,
41c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson                                    AccessSpecifier LexicalAS) {
42c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  if (!PrevMemberDecl) {
43c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    // Use the lexical access specifier.
44c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    MemberDecl->setAccess(LexicalAS);
45c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    return false;
46c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  }
471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  // C++ [class.access.spec]p3: When a member is redeclared its access
49c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  // specifier must be same as its initial declaration.
50c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Diag(MemberDecl->getLocation(),
521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump         diag::err_class_redeclared_with_different_access)
53c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson      << MemberDecl << LexicalAS;
54c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
55c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson      << PrevMemberDecl << PrevMemberDecl->getAccess();
5644e067bd8f923ba8e7c24b2189e06717d70015c8John McCall
5744e067bd8f923ba8e7c24b2189e06717d70015c8John McCall    MemberDecl->setAccess(LexicalAS);
58c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson    return true;
59c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  }
601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  MemberDecl->setAccess(PrevMemberDecl->getAccess());
62c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson  return false;
63c60e88819a273d54faa71a2cd6c3d79dd48c12e0Anders Carlsson}
6429f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson
65161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic CXXRecordDecl *FindDeclaringClass(NamedDecl *D) {
66161755a09898c95d21bfff33707da9ca41cd53c5John McCall  DeclContext *DC = D->getDeclContext();
67161755a09898c95d21bfff33707da9ca41cd53c5John McCall
68161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // This can only happen at top: enum decls only "publish" their
69161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // immediate members.
70161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (isa<EnumDecl>(DC))
71161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DC = cast<EnumDecl>(DC)->getDeclContext();
72161755a09898c95d21bfff33707da9ca41cd53c5John McCall
73161755a09898c95d21bfff33707da9ca41cd53c5John McCall  CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
74161755a09898c95d21bfff33707da9ca41cd53c5John McCall  while (DeclaringClass->isAnonymousStructOrUnion())
75161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
76161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return DeclaringClass;
77161755a09898c95d21bfff33707da9ca41cd53c5John McCall}
78161755a09898c95d21bfff33707da9ca41cd53c5John McCall
796b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallnamespace {
806b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstruct EffectiveContext {
816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  EffectiveContext() : Inner(nullptr), Dependent(false) {}
826b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
837ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  explicit EffectiveContext(DeclContext *DC)
847ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall    : Inner(DC),
857ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall      Dependent(DC->isDependentContext()) {
860c01d18094100db92d38daa923c95661512db203John McCall
87cad7e43c5aba88bf6affc155b02d8609485db41bRichard Smith    // C++11 [class.access.nest]p1:
8888b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    //   A nested class is a member and as such has the same access
8988b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    //   rights as any other member.
90cad7e43c5aba88bf6affc155b02d8609485db41bRichard Smith    // C++11 [class.access]p2:
9188b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    //   A member of a class can also access all the names to which
922cc2675d426af23476a9722c08c1b6c5266bd653John McCall    //   the class has access.  A local class of a member function
932cc2675d426af23476a9722c08c1b6c5266bd653John McCall    //   may access the same names that the member function itself
942cc2675d426af23476a9722c08c1b6c5266bd653John McCall    //   may access.
952cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // This almost implies that the privileges of nesting are transitive.
962cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // Technically it says nothing about the local classes of non-member
972cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // functions (which can gain privileges through friendship), but we
982cc2675d426af23476a9722c08c1b6c5266bd653John McCall    // take that as an oversight.
992cc2675d426af23476a9722c08c1b6c5266bd653John McCall    while (true) {
1008bddeb57d134c0e5f14e319271aa9015886a8ac7John McCall      // We want to add canonical declarations to the EC lists for
1018bddeb57d134c0e5f14e319271aa9015886a8ac7John McCall      // simplicity of checking, but we need to walk up through the
1028bddeb57d134c0e5f14e319271aa9015886a8ac7John McCall      // actual current DC chain.  Otherwise, something like a local
1038bddeb57d134c0e5f14e319271aa9015886a8ac7John McCall      // extern or friend which happens to be the canonical
1048bddeb57d134c0e5f14e319271aa9015886a8ac7John McCall      // declaration will really mess us up.
1058bddeb57d134c0e5f14e319271aa9015886a8ac7John McCall
1062cc2675d426af23476a9722c08c1b6c5266bd653John McCall      if (isa<CXXRecordDecl>(DC)) {
1078bddeb57d134c0e5f14e319271aa9015886a8ac7John McCall        CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
1088bddeb57d134c0e5f14e319271aa9015886a8ac7John McCall        Records.push_back(Record->getCanonicalDecl());
1092cc2675d426af23476a9722c08c1b6c5266bd653John McCall        DC = Record->getDeclContext();
1102cc2675d426af23476a9722c08c1b6c5266bd653John McCall      } else if (isa<FunctionDecl>(DC)) {
1118bddeb57d134c0e5f14e319271aa9015886a8ac7John McCall        FunctionDecl *Function = cast<FunctionDecl>(DC);
1128bddeb57d134c0e5f14e319271aa9015886a8ac7John McCall        Functions.push_back(Function->getCanonicalDecl());
113ac57f0b9097e04f70a631549383a2944f74ad844Douglas Gregor        if (Function->getFriendObjectKind())
114ac57f0b9097e04f70a631549383a2944f74ad844Douglas Gregor          DC = Function->getLexicalDeclContext();
115ac57f0b9097e04f70a631549383a2944f74ad844Douglas Gregor        else
116ac57f0b9097e04f70a631549383a2944f74ad844Douglas Gregor          DC = Function->getDeclContext();
1172cc2675d426af23476a9722c08c1b6c5266bd653John McCall      } else if (DC->isFileContext()) {
1182cc2675d426af23476a9722c08c1b6c5266bd653John McCall        break;
1192cc2675d426af23476a9722c08c1b6c5266bd653John McCall      } else {
1202cc2675d426af23476a9722c08c1b6c5266bd653John McCall        DC = DC->getParent();
1212cc2675d426af23476a9722c08c1b6c5266bd653John McCall      }
12288b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    }
1236b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
1246b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1250c01d18094100db92d38daa923c95661512db203John McCall  bool isDependent() const { return Dependent; }
1260c01d18094100db92d38daa923c95661512db203John McCall
12788b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall  bool includesClass(const CXXRecordDecl *R) const {
12888b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    R = R->getCanonicalDecl();
12988b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall    return std::find(Records.begin(), Records.end(), R)
13088b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall             != Records.end();
1316b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
1326b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1337ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  /// Retrieves the innermost "useful" context.  Can be null if we're
1347ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  /// doing access-control without privileges.
1357ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  DeclContext *getInnerContext() const {
1367ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall    return Inner;
1370c01d18094100db92d38daa923c95661512db203John McCall  }
1380c01d18094100db92d38daa923c95661512db203John McCall
1395f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
1400c01d18094100db92d38daa923c95661512db203John McCall
1417ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  DeclContext *Inner;
1425f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<FunctionDecl*, 4> Functions;
1435f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<CXXRecordDecl*, 4> Records;
1440c01d18094100db92d38daa923c95661512db203John McCall  bool Dependent;
1456b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall};
146161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1476bb4dcb412d53d05a80017df81d41e447e2aa3eaNico Weber/// Like sema::AccessedEntity, but kindly lets us scribble all over
148161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// it.
1499c3087b0b0bea2fd782205c1274ebfc4290265e0John McCallstruct AccessTarget : public AccessedEntity {
1509c3087b0b0bea2fd782205c1274ebfc4290265e0John McCall  AccessTarget(const AccessedEntity &Entity)
151161755a09898c95d21bfff33707da9ca41cd53c5John McCall    : AccessedEntity(Entity) {
152161755a09898c95d21bfff33707da9ca41cd53c5John McCall    initialize();
153161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
154161755a09898c95d21bfff33707da9ca41cd53c5John McCall
155161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget(ASTContext &Context,
156161755a09898c95d21bfff33707da9ca41cd53c5John McCall               MemberNonce _,
157161755a09898c95d21bfff33707da9ca41cd53c5John McCall               CXXRecordDecl *NamingClass,
158161755a09898c95d21bfff33707da9ca41cd53c5John McCall               DeclAccessPair FoundDecl,
15924dd9ad9001d1aa16223de135d7e4ed34e94b207Erik Verbruggen               QualType BaseObjectType)
160478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer    : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,
161478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer                     FoundDecl, BaseObjectType) {
162161755a09898c95d21bfff33707da9ca41cd53c5John McCall    initialize();
163161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
164161755a09898c95d21bfff33707da9ca41cd53c5John McCall
165161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget(ASTContext &Context,
166161755a09898c95d21bfff33707da9ca41cd53c5John McCall               BaseNonce _,
167161755a09898c95d21bfff33707da9ca41cd53c5John McCall               CXXRecordDecl *BaseClass,
168161755a09898c95d21bfff33707da9ca41cd53c5John McCall               CXXRecordDecl *DerivedClass,
169161755a09898c95d21bfff33707da9ca41cd53c5John McCall               AccessSpecifier Access)
170478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer    : AccessedEntity(Context.getDiagAllocator(), Base, BaseClass, DerivedClass,
171478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer                     Access) {
172161755a09898c95d21bfff33707da9ca41cd53c5John McCall    initialize();
173161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
174161755a09898c95d21bfff33707da9ca41cd53c5John McCall
175b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  bool isInstanceMember() const {
176b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
177b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  }
178b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
179161755a09898c95d21bfff33707da9ca41cd53c5John McCall  bool hasInstanceContext() const {
180161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return HasInstanceContext;
181161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
182161755a09898c95d21bfff33707da9ca41cd53c5John McCall
183161755a09898c95d21bfff33707da9ca41cd53c5John McCall  class SavedInstanceContext {
184161755a09898c95d21bfff33707da9ca41cd53c5John McCall  public:
185161755a09898c95d21bfff33707da9ca41cd53c5John McCall    ~SavedInstanceContext() {
186161755a09898c95d21bfff33707da9ca41cd53c5John McCall      Target.HasInstanceContext = Has;
187161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
188161755a09898c95d21bfff33707da9ca41cd53c5John McCall
189161755a09898c95d21bfff33707da9ca41cd53c5John McCall  private:
190c91cc66e92b084acd1fdbaa1c3c74242741b3d46John McCall    friend struct AccessTarget;
191161755a09898c95d21bfff33707da9ca41cd53c5John McCall    explicit SavedInstanceContext(AccessTarget &Target)
192161755a09898c95d21bfff33707da9ca41cd53c5John McCall      : Target(Target), Has(Target.HasInstanceContext) {}
193161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget &Target;
194161755a09898c95d21bfff33707da9ca41cd53c5John McCall    bool Has;
195161755a09898c95d21bfff33707da9ca41cd53c5John McCall  };
196161755a09898c95d21bfff33707da9ca41cd53c5John McCall
197161755a09898c95d21bfff33707da9ca41cd53c5John McCall  SavedInstanceContext saveInstanceContext() {
198161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return SavedInstanceContext(*this);
199161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
200161755a09898c95d21bfff33707da9ca41cd53c5John McCall
201161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void suppressInstanceContext() {
202161755a09898c95d21bfff33707da9ca41cd53c5John McCall    HasInstanceContext = false;
203161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
204161755a09898c95d21bfff33707da9ca41cd53c5John McCall
205161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
206161755a09898c95d21bfff33707da9ca41cd53c5John McCall    assert(HasInstanceContext);
207161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (CalculatedInstanceContext)
208161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return InstanceContext;
209161755a09898c95d21bfff33707da9ca41cd53c5John McCall
210161755a09898c95d21bfff33707da9ca41cd53c5John McCall    CalculatedInstanceContext = true;
211161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DeclContext *IC = S.computeDeclContext(getBaseObjectType());
2126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
2136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                          : nullptr);
214161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return InstanceContext;
215161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
216161755a09898c95d21bfff33707da9ca41cd53c5John McCall
217161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *getDeclaringClass() const {
218161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return DeclaringClass;
219161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
220161755a09898c95d21bfff33707da9ca41cd53c5John McCall
221714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  /// The "effective" naming class is the canonical non-anonymous
222714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  /// class containing the actual naming class.
223714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  const CXXRecordDecl *getEffectiveNamingClass() const {
224714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    const CXXRecordDecl *namingClass = getNamingClass();
225714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    while (namingClass->isAnonymousStructOrUnion())
226714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      namingClass = cast<CXXRecordDecl>(namingClass->getParent());
227714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    return namingClass->getCanonicalDecl();
228714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  }
229714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
230161755a09898c95d21bfff33707da9ca41cd53c5John McCallprivate:
231161755a09898c95d21bfff33707da9ca41cd53c5John McCall  void initialize() {
232161755a09898c95d21bfff33707da9ca41cd53c5John McCall    HasInstanceContext = (isMemberAccess() &&
233161755a09898c95d21bfff33707da9ca41cd53c5John McCall                          !getBaseObjectType().isNull() &&
234161755a09898c95d21bfff33707da9ca41cd53c5John McCall                          getTargetDecl()->isCXXInstanceMember());
235161755a09898c95d21bfff33707da9ca41cd53c5John McCall    CalculatedInstanceContext = false;
2366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    InstanceContext = nullptr;
237161755a09898c95d21bfff33707da9ca41cd53c5John McCall
238161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (isMemberAccess())
239161755a09898c95d21bfff33707da9ca41cd53c5John McCall      DeclaringClass = FindDeclaringClass(getTargetDecl());
240161755a09898c95d21bfff33707da9ca41cd53c5John McCall    else
241161755a09898c95d21bfff33707da9ca41cd53c5John McCall      DeclaringClass = getBaseClass();
242161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DeclaringClass = DeclaringClass->getCanonicalDecl();
243161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
244161755a09898c95d21bfff33707da9ca41cd53c5John McCall
245161755a09898c95d21bfff33707da9ca41cd53c5John McCall  bool HasInstanceContext : 1;
246161755a09898c95d21bfff33707da9ca41cd53c5John McCall  mutable bool CalculatedInstanceContext : 1;
247161755a09898c95d21bfff33707da9ca41cd53c5John McCall  mutable const CXXRecordDecl *InstanceContext;
248161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *DeclaringClass;
249161755a09898c95d21bfff33707da9ca41cd53c5John McCall};
250161755a09898c95d21bfff33707da9ca41cd53c5John McCall
2516b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
252726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
25301ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall/// Checks whether one class might instantiate to the other.
25401ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCallstatic bool MightInstantiateTo(const CXXRecordDecl *From,
25501ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall                               const CXXRecordDecl *To) {
25601ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  // Declaration names are always preserved by instantiation.
25701ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (From->getDeclName() != To->getDeclName())
25801ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall    return false;
25901ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
26001ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
26101ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
26201ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (FromDC == ToDC) return true;
26301ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
26401ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
26501ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  // Be conservative.
26601ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  return true;
26701ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall}
26801ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
269161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// Checks whether one class is derived from another, inclusively.
270161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// Properly indicates when it couldn't be determined due to
271161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// dependence.
272161755a09898c95d21bfff33707da9ca41cd53c5John McCall///
273161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// This should probably be donated to AST or at least Sema.
274161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived,
275161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                           const CXXRecordDecl *Target) {
276161755a09898c95d21bfff33707da9ca41cd53c5John McCall  assert(Derived->getCanonicalDecl() == Derived);
277161755a09898c95d21bfff33707da9ca41cd53c5John McCall  assert(Target->getCanonicalDecl() == Target);
278c1b621daf98d83075a466c6f4ad9904dc845dd09John McCall
279161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (Derived == Target) return AR_accessible;
280c1b621daf98d83075a466c6f4ad9904dc845dd09John McCall
28101ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  bool CheckDependent = Derived->isDependentContext();
28201ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall  if (CheckDependent && MightInstantiateTo(Derived, Target))
28301ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall    return AR_dependent;
28401ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
285161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
2865f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
287161755a09898c95d21bfff33707da9ca41cd53c5John McCall
288161755a09898c95d21bfff33707da9ca41cd53c5John McCall  while (true) {
2897432b90e88ac9e219f6e8a3151c097b0b7da933cDouglas Gregor    if (Derived->isDependentContext() && !Derived->hasDefinition())
2907432b90e88ac9e219f6e8a3151c097b0b7da933cDouglas Gregor      return AR_dependent;
2917432b90e88ac9e219f6e8a3151c097b0b7da933cDouglas Gregor
292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto &I : Derived->bases()) {
293161755a09898c95d21bfff33707da9ca41cd53c5John McCall      const CXXRecordDecl *RD;
294161755a09898c95d21bfff33707da9ca41cd53c5John McCall
295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      QualType T = I.getType();
296161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (const RecordType *RT = T->getAs<RecordType>()) {
297161755a09898c95d21bfff33707da9ca41cd53c5John McCall        RD = cast<CXXRecordDecl>(RT->getDecl());
29801ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall      } else if (const InjectedClassNameType *IT
29901ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall                   = T->getAs<InjectedClassNameType>()) {
30001ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall        RD = IT->getDecl();
301161755a09898c95d21bfff33707da9ca41cd53c5John McCall      } else {
302161755a09898c95d21bfff33707da9ca41cd53c5John McCall        assert(T->isDependentType() && "non-dependent base wasn't a record?");
303161755a09898c95d21bfff33707da9ca41cd53c5John McCall        OnFailure = AR_dependent;
304161755a09898c95d21bfff33707da9ca41cd53c5John McCall        continue;
305161755a09898c95d21bfff33707da9ca41cd53c5John McCall      }
306161755a09898c95d21bfff33707da9ca41cd53c5John McCall
307161755a09898c95d21bfff33707da9ca41cd53c5John McCall      RD = RD->getCanonicalDecl();
308161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (RD == Target) return AR_accessible;
30901ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall      if (CheckDependent && MightInstantiateTo(RD, Target))
31001ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall        OnFailure = AR_dependent;
31101ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
312161755a09898c95d21bfff33707da9ca41cd53c5John McCall      Queue.push_back(RD);
313161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
314161755a09898c95d21bfff33707da9ca41cd53c5John McCall
315161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (Queue.empty()) break;
316161755a09898c95d21bfff33707da9ca41cd53c5John McCall
317344472ebeded2fca2ed5013b9e87f81d09bfa908Robert Wilhelm    Derived = Queue.pop_back_val();
318161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
319161755a09898c95d21bfff33707da9ca41cd53c5John McCall
320161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return OnFailure;
3216b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
3226b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
323161755a09898c95d21bfff33707da9ca41cd53c5John McCall
3240c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S, DeclContext *Context,
3250c01d18094100db92d38daa923c95661512db203John McCall                               DeclContext *Friend) {
3260c01d18094100db92d38daa923c95661512db203John McCall  if (Friend == Context)
3270c01d18094100db92d38daa923c95661512db203John McCall    return true;
3280c01d18094100db92d38daa923c95661512db203John McCall
3290c01d18094100db92d38daa923c95661512db203John McCall  assert(!Friend->isDependentContext() &&
3300c01d18094100db92d38daa923c95661512db203John McCall         "can't handle friends with dependent contexts here");
3310c01d18094100db92d38daa923c95661512db203John McCall
3320c01d18094100db92d38daa923c95661512db203John McCall  if (!Context->isDependentContext())
3330c01d18094100db92d38daa923c95661512db203John McCall    return false;
3340c01d18094100db92d38daa923c95661512db203John McCall
3350c01d18094100db92d38daa923c95661512db203John McCall  if (Friend->isFileContext())
3360c01d18094100db92d38daa923c95661512db203John McCall    return false;
3370c01d18094100db92d38daa923c95661512db203John McCall
3380c01d18094100db92d38daa923c95661512db203John McCall  // TODO: this is very conservative
3390c01d18094100db92d38daa923c95661512db203John McCall  return true;
3400c01d18094100db92d38daa923c95661512db203John McCall}
3410c01d18094100db92d38daa923c95661512db203John McCall
3420c01d18094100db92d38daa923c95661512db203John McCall// Asks whether the type in 'context' can ever instantiate to the type
3430c01d18094100db92d38daa923c95661512db203John McCall// in 'friend'.
3440c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) {
3450c01d18094100db92d38daa923c95661512db203John McCall  if (Friend == Context)
3460c01d18094100db92d38daa923c95661512db203John McCall    return true;
3470c01d18094100db92d38daa923c95661512db203John McCall
3480c01d18094100db92d38daa923c95661512db203John McCall  if (!Friend->isDependentType() && !Context->isDependentType())
3490c01d18094100db92d38daa923c95661512db203John McCall    return false;
3500c01d18094100db92d38daa923c95661512db203John McCall
3510c01d18094100db92d38daa923c95661512db203John McCall  // TODO: this is very conservative.
3520c01d18094100db92d38daa923c95661512db203John McCall  return true;
3530c01d18094100db92d38daa923c95661512db203John McCall}
3540c01d18094100db92d38daa923c95661512db203John McCall
3550c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S,
3560c01d18094100db92d38daa923c95661512db203John McCall                               FunctionDecl *Context,
3570c01d18094100db92d38daa923c95661512db203John McCall                               FunctionDecl *Friend) {
3580c01d18094100db92d38daa923c95661512db203John McCall  if (Context->getDeclName() != Friend->getDeclName())
3590c01d18094100db92d38daa923c95661512db203John McCall    return false;
3600c01d18094100db92d38daa923c95661512db203John McCall
3610c01d18094100db92d38daa923c95661512db203John McCall  if (!MightInstantiateTo(S,
3620c01d18094100db92d38daa923c95661512db203John McCall                          Context->getDeclContext(),
3630c01d18094100db92d38daa923c95661512db203John McCall                          Friend->getDeclContext()))
3640c01d18094100db92d38daa923c95661512db203John McCall    return false;
3650c01d18094100db92d38daa923c95661512db203John McCall
3660c01d18094100db92d38daa923c95661512db203John McCall  CanQual<FunctionProtoType> FriendTy
3670c01d18094100db92d38daa923c95661512db203John McCall    = S.Context.getCanonicalType(Friend->getType())
3680c01d18094100db92d38daa923c95661512db203John McCall         ->getAs<FunctionProtoType>();
3690c01d18094100db92d38daa923c95661512db203John McCall  CanQual<FunctionProtoType> ContextTy
3700c01d18094100db92d38daa923c95661512db203John McCall    = S.Context.getCanonicalType(Context->getType())
3710c01d18094100db92d38daa923c95661512db203John McCall         ->getAs<FunctionProtoType>();
3720c01d18094100db92d38daa923c95661512db203John McCall
3730c01d18094100db92d38daa923c95661512db203John McCall  // There isn't any way that I know of to add qualifiers
3740c01d18094100db92d38daa923c95661512db203John McCall  // during instantiation.
3750c01d18094100db92d38daa923c95661512db203John McCall  if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
3760c01d18094100db92d38daa923c95661512db203John McCall    return false;
3770c01d18094100db92d38daa923c95661512db203John McCall
378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (FriendTy->getNumParams() != ContextTy->getNumParams())
3790c01d18094100db92d38daa923c95661512db203John McCall    return false;
3800c01d18094100db92d38daa923c95661512db203John McCall
381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (!MightInstantiateTo(S, ContextTy->getReturnType(),
382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                          FriendTy->getReturnType()))
3830c01d18094100db92d38daa923c95661512db203John McCall    return false;
3840c01d18094100db92d38daa923c95661512db203John McCall
385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!MightInstantiateTo(S, ContextTy->getParamType(I),
387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                            FriendTy->getParamType(I)))
3880c01d18094100db92d38daa923c95661512db203John McCall      return false;
3890c01d18094100db92d38daa923c95661512db203John McCall
3900c01d18094100db92d38daa923c95661512db203John McCall  return true;
3910c01d18094100db92d38daa923c95661512db203John McCall}
3920c01d18094100db92d38daa923c95661512db203John McCall
3930c01d18094100db92d38daa923c95661512db203John McCallstatic bool MightInstantiateTo(Sema &S,
3940c01d18094100db92d38daa923c95661512db203John McCall                               FunctionTemplateDecl *Context,
3950c01d18094100db92d38daa923c95661512db203John McCall                               FunctionTemplateDecl *Friend) {
3960c01d18094100db92d38daa923c95661512db203John McCall  return MightInstantiateTo(S,
3970c01d18094100db92d38daa923c95661512db203John McCall                            Context->getTemplatedDecl(),
3980c01d18094100db92d38daa923c95661512db203John McCall                            Friend->getTemplatedDecl());
3990c01d18094100db92d38daa923c95661512db203John McCall}
4000c01d18094100db92d38daa923c95661512db203John McCall
401161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
402161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
403161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const CXXRecordDecl *Friend) {
404a742db0032d8f458fe229600d2082981a1fb1481John McCall  if (EC.includesClass(Friend))
405161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_accessible;
406a742db0032d8f458fe229600d2082981a1fb1481John McCall
4070c01d18094100db92d38daa923c95661512db203John McCall  if (EC.isDependent()) {
4080c01d18094100db92d38daa923c95661512db203John McCall    CanQualType FriendTy
4090c01d18094100db92d38daa923c95661512db203John McCall      = S.Context.getCanonicalType(S.Context.getTypeDeclType(Friend));
4100c01d18094100db92d38daa923c95661512db203John McCall
4110c01d18094100db92d38daa923c95661512db203John McCall    for (EffectiveContext::record_iterator
4120c01d18094100db92d38daa923c95661512db203John McCall           I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
4130c01d18094100db92d38daa923c95661512db203John McCall      CanQualType ContextTy
4140c01d18094100db92d38daa923c95661512db203John McCall        = S.Context.getCanonicalType(S.Context.getTypeDeclType(*I));
4150c01d18094100db92d38daa923c95661512db203John McCall      if (MightInstantiateTo(S, ContextTy, FriendTy))
416161755a09898c95d21bfff33707da9ca41cd53c5John McCall        return AR_dependent;
4170c01d18094100db92d38daa923c95661512db203John McCall    }
4180c01d18094100db92d38daa923c95661512db203John McCall  }
4190c01d18094100db92d38daa923c95661512db203John McCall
420161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return AR_inaccessible;
421a742db0032d8f458fe229600d2082981a1fb1481John McCall}
422a742db0032d8f458fe229600d2082981a1fb1481John McCall
423161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
424161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
425161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  CanQualType Friend) {
4260c01d18094100db92d38daa923c95661512db203John McCall  if (const RecordType *RT = Friend->getAs<RecordType>())
4270c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
428a742db0032d8f458fe229600d2082981a1fb1481John McCall
4290c01d18094100db92d38daa923c95661512db203John McCall  // TODO: we can do better than this
4300c01d18094100db92d38daa923c95661512db203John McCall  if (Friend->isDependentType())
431161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_dependent;
432a742db0032d8f458fe229600d2082981a1fb1481John McCall
433161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return AR_inaccessible;
4340c01d18094100db92d38daa923c95661512db203John McCall}
435a742db0032d8f458fe229600d2082981a1fb1481John McCall
4360c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend class template matches
4370c01d18094100db92d38daa923c95661512db203John McCall/// anything in the effective context.
438161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
439161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
440161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  ClassTemplateDecl *Friend) {
441161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
442a742db0032d8f458fe229600d2082981a1fb1481John McCall
44393ba8579c341d5329175f1413cdc3b35a36592d2John McCall  // Check whether the friend is the template of a class in the
44493ba8579c341d5329175f1413cdc3b35a36592d2John McCall  // context chain.
4455f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVectorImpl<CXXRecordDecl*>::const_iterator
4460c01d18094100db92d38daa923c95661512db203John McCall         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
4470c01d18094100db92d38daa923c95661512db203John McCall    CXXRecordDecl *Record = *I;
448a742db0032d8f458fe229600d2082981a1fb1481John McCall
44993ba8579c341d5329175f1413cdc3b35a36592d2John McCall    // Figure out whether the current class has a template:
4500c01d18094100db92d38daa923c95661512db203John McCall    ClassTemplateDecl *CTD;
451a742db0032d8f458fe229600d2082981a1fb1481John McCall
4520c01d18094100db92d38daa923c95661512db203John McCall    // A specialization of the template...
4530c01d18094100db92d38daa923c95661512db203John McCall    if (isa<ClassTemplateSpecializationDecl>(Record)) {
4540c01d18094100db92d38daa923c95661512db203John McCall      CTD = cast<ClassTemplateSpecializationDecl>(Record)
4550c01d18094100db92d38daa923c95661512db203John McCall        ->getSpecializedTemplate();
456a742db0032d8f458fe229600d2082981a1fb1481John McCall
4570c01d18094100db92d38daa923c95661512db203John McCall    // ... or the template pattern itself.
4580c01d18094100db92d38daa923c95661512db203John McCall    } else {
4590c01d18094100db92d38daa923c95661512db203John McCall      CTD = Record->getDescribedClassTemplate();
4600c01d18094100db92d38daa923c95661512db203John McCall      if (!CTD) continue;
461a742db0032d8f458fe229600d2082981a1fb1481John McCall    }
462a742db0032d8f458fe229600d2082981a1fb1481John McCall
4630c01d18094100db92d38daa923c95661512db203John McCall    // It's a match.
4640c01d18094100db92d38daa923c95661512db203John McCall    if (Friend == CTD->getCanonicalDecl())
465161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
4660c01d18094100db92d38daa923c95661512db203John McCall
46793ba8579c341d5329175f1413cdc3b35a36592d2John McCall    // If the context isn't dependent, it can't be a dependent match.
46893ba8579c341d5329175f1413cdc3b35a36592d2John McCall    if (!EC.isDependent())
46993ba8579c341d5329175f1413cdc3b35a36592d2John McCall      continue;
47093ba8579c341d5329175f1413cdc3b35a36592d2John McCall
4710c01d18094100db92d38daa923c95661512db203John McCall    // If the template names don't match, it can't be a dependent
4723e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // match.
4733e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (CTD->getDeclName() != Friend->getDeclName())
4740c01d18094100db92d38daa923c95661512db203John McCall      continue;
4750c01d18094100db92d38daa923c95661512db203John McCall
4760c01d18094100db92d38daa923c95661512db203John McCall    // If the class's context can't instantiate to the friend's
4770c01d18094100db92d38daa923c95661512db203John McCall    // context, it can't be a dependent match.
4780c01d18094100db92d38daa923c95661512db203John McCall    if (!MightInstantiateTo(S, CTD->getDeclContext(),
4790c01d18094100db92d38daa923c95661512db203John McCall                            Friend->getDeclContext()))
4800c01d18094100db92d38daa923c95661512db203John McCall      continue;
4810c01d18094100db92d38daa923c95661512db203John McCall
4820c01d18094100db92d38daa923c95661512db203John McCall    // Otherwise, it's a dependent match.
483161755a09898c95d21bfff33707da9ca41cd53c5John McCall    OnFailure = AR_dependent;
484a742db0032d8f458fe229600d2082981a1fb1481John McCall  }
485a742db0032d8f458fe229600d2082981a1fb1481John McCall
4860c01d18094100db92d38daa923c95661512db203John McCall  return OnFailure;
4870c01d18094100db92d38daa923c95661512db203John McCall}
488a742db0032d8f458fe229600d2082981a1fb1481John McCall
4890c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend function matches anything in
4900c01d18094100db92d38daa923c95661512db203John McCall/// the effective context.
491161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
492161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
493161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  FunctionDecl *Friend) {
494161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
495a742db0032d8f458fe229600d2082981a1fb1481John McCall
4965f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVectorImpl<FunctionDecl*>::const_iterator
4972cc2675d426af23476a9722c08c1b6c5266bd653John McCall         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
4982cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (Friend == *I)
499161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
5000c01d18094100db92d38daa923c95661512db203John McCall
5012cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
502161755a09898c95d21bfff33707da9ca41cd53c5John McCall      OnFailure = AR_dependent;
5032cc2675d426af23476a9722c08c1b6c5266bd653John McCall  }
5040c01d18094100db92d38daa923c95661512db203John McCall
5052cc2675d426af23476a9722c08c1b6c5266bd653John McCall  return OnFailure;
5060c01d18094100db92d38daa923c95661512db203John McCall}
5070c01d18094100db92d38daa923c95661512db203John McCall
5080c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend function template matches
5090c01d18094100db92d38daa923c95661512db203John McCall/// anything in the effective context.
510161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
511161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
512161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  FunctionTemplateDecl *Friend) {
513161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (EC.Functions.empty()) return AR_inaccessible;
5142cc2675d426af23476a9722c08c1b6c5266bd653John McCall
515161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
5160c01d18094100db92d38daa923c95661512db203John McCall
5175f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVectorImpl<FunctionDecl*>::const_iterator
5182cc2675d426af23476a9722c08c1b6c5266bd653John McCall         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
519a742db0032d8f458fe229600d2082981a1fb1481John McCall
5202cc2675d426af23476a9722c08c1b6c5266bd653John McCall    FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
5212cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (!FTD)
5222cc2675d426af23476a9722c08c1b6c5266bd653John McCall      FTD = (*I)->getDescribedFunctionTemplate();
5232cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (!FTD)
5242cc2675d426af23476a9722c08c1b6c5266bd653John McCall      continue;
525a742db0032d8f458fe229600d2082981a1fb1481John McCall
5262cc2675d426af23476a9722c08c1b6c5266bd653John McCall    FTD = FTD->getCanonicalDecl();
527a742db0032d8f458fe229600d2082981a1fb1481John McCall
5282cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (Friend == FTD)
529161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
5302cc2675d426af23476a9722c08c1b6c5266bd653John McCall
5312cc2675d426af23476a9722c08c1b6c5266bd653John McCall    if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
532161755a09898c95d21bfff33707da9ca41cd53c5John McCall      OnFailure = AR_dependent;
5332cc2675d426af23476a9722c08c1b6c5266bd653John McCall  }
5342cc2675d426af23476a9722c08c1b6c5266bd653John McCall
5352cc2675d426af23476a9722c08c1b6c5266bd653John McCall  return OnFailure;
536a742db0032d8f458fe229600d2082981a1fb1481John McCall}
537a742db0032d8f458fe229600d2082981a1fb1481John McCall
5380c01d18094100db92d38daa923c95661512db203John McCall/// Determines whether the given friend declaration matches anything
5390c01d18094100db92d38daa923c95661512db203John McCall/// in the effective context.
540161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult MatchesFriend(Sema &S,
541161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
542161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  FriendDecl *FriendD) {
5436102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  // Whitelist accesses if there's an invalid or unsupported friend
5446102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  // declaration.
5456102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall  if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend())
546337ec3d0e8cb24a591ecbecdc0a995a167f6af01John McCall    return AR_accessible;
547337ec3d0e8cb24a591ecbecdc0a995a167f6af01John McCall
54832f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  if (TypeSourceInfo *T = FriendD->getFriendType())
54932f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall    return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
5500c01d18094100db92d38daa923c95661512db203John McCall
5510c01d18094100db92d38daa923c95661512db203John McCall  NamedDecl *Friend
5520c01d18094100db92d38daa923c95661512db203John McCall    = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
5530c01d18094100db92d38daa923c95661512db203John McCall
5540c01d18094100db92d38daa923c95661512db203John McCall  // FIXME: declarations with dependent or templated scope.
5550c01d18094100db92d38daa923c95661512db203John McCall
5560c01d18094100db92d38daa923c95661512db203John McCall  if (isa<ClassTemplateDecl>(Friend))
5570c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
5580c01d18094100db92d38daa923c95661512db203John McCall
5590c01d18094100db92d38daa923c95661512db203John McCall  if (isa<FunctionTemplateDecl>(Friend))
5600c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
5610c01d18094100db92d38daa923c95661512db203John McCall
5620c01d18094100db92d38daa923c95661512db203John McCall  if (isa<CXXRecordDecl>(Friend))
5630c01d18094100db92d38daa923c95661512db203John McCall    return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
5640c01d18094100db92d38daa923c95661512db203John McCall
5650c01d18094100db92d38daa923c95661512db203John McCall  assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
5660c01d18094100db92d38daa923c95661512db203John McCall  return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
5670c01d18094100db92d38daa923c95661512db203John McCall}
5680c01d18094100db92d38daa923c95661512db203John McCall
569161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult GetFriendKind(Sema &S,
570161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const EffectiveContext &EC,
571161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                  const CXXRecordDecl *Class) {
572161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
57388b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall
574d60e22e601852ae1345f01514318a0951dc09f89John McCall  // Okay, check friends.
575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (auto *Friend : Class->friends()) {
576a742db0032d8f458fe229600d2082981a1fb1481John McCall    switch (MatchesFriend(S, EC, Friend)) {
577161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible:
578161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_accessible;
57988b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall
580161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible:
581161755a09898c95d21bfff33707da9ca41cd53c5John McCall      continue;
582d60e22e601852ae1345f01514318a0951dc09f89John McCall
583161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
584161755a09898c95d21bfff33707da9ca41cd53c5John McCall      OnFailure = AR_dependent;
585a742db0032d8f458fe229600d2082981a1fb1481John McCall      break;
586a742db0032d8f458fe229600d2082981a1fb1481John McCall    }
587d60e22e601852ae1345f01514318a0951dc09f89John McCall  }
588d60e22e601852ae1345f01514318a0951dc09f89John McCall
589d60e22e601852ae1345f01514318a0951dc09f89John McCall  // That's it, give up.
59088b6c71e3f0e68d094efcf880910caf424b46cbfJohn McCall  return OnFailure;
5916b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
5926b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
5938c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCallnamespace {
5948c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
5958c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// A helper class for checking for a friend which will grant access
5968c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// to a protected instance member.
5978c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCallstruct ProtectedFriendContext {
5988c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  Sema &S;
5998c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  const EffectiveContext &EC;
6008c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  const CXXRecordDecl *NamingClass;
6018c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  bool CheckDependent;
6028c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  bool EverDependent;
6038c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6048c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  /// The path down to the current base class.
6055f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<const CXXRecordDecl*, 20> CurPath;
6068c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6078c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
6088c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                         const CXXRecordDecl *InstanceContext,
6098c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                         const CXXRecordDecl *NamingClass)
6108c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    : S(S), EC(EC), NamingClass(NamingClass),
6118c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      CheckDependent(InstanceContext->isDependentContext() ||
6128c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                     NamingClass->isDependentContext()),
6138c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      EverDependent(false) {}
6148c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
615326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  /// Check classes in the current path for friendship, starting at
616326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  /// the given index.
617326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  bool checkFriendshipAlongPath(unsigned I) {
618326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    assert(I < CurPath.size());
619326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    for (unsigned E = CurPath.size(); I != E; ++I) {
620326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      switch (GetFriendKind(S, EC, CurPath[I])) {
6218c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      case AR_accessible:   return true;
6228c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      case AR_inaccessible: continue;
6238c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      case AR_dependent:    EverDependent = true; continue;
6248c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      }
6258c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    }
6268c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    return false;
6278c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  }
6288c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6298c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  /// Perform a search starting at the given class.
630326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  ///
631326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  /// PrivateDepth is the index of the last (least derived) class
632326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  /// along the current path such that a notional public member of
633326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  /// the final class in the path would have access in that class.
634326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
6358c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    // If we ever reach the naming class, check the current path for
6368c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    // friendship.  We can also stop recursing because we obviously
6378c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    // won't find the naming class there again.
638326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    if (Cur == NamingClass)
639326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      return checkFriendshipAlongPath(PrivateDepth);
6408c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6418c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
6428c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      EverDependent = true;
6438c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6448c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    // Recurse into the base classes.
645651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (const auto &I : Cur->bases()) {
646326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      // If this is private inheritance, then a public member of the
647326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      // base will not have any access in classes derived from Cur.
648326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      unsigned BasePrivateDepth = PrivateDepth;
649651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (I.getAccessSpecifier() == AS_private)
650326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall        BasePrivateDepth = CurPath.size() - 1;
6518c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6528c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      const CXXRecordDecl *RD;
6538c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      QualType T = I.getType();
6558c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      if (const RecordType *RT = T->getAs<RecordType>()) {
6568c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall        RD = cast<CXXRecordDecl>(RT->getDecl());
6578c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      } else if (const InjectedClassNameType *IT
6588c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                   = T->getAs<InjectedClassNameType>()) {
6598c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall        RD = IT->getDecl();
6608c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      } else {
6618c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall        assert(T->isDependentType() && "non-dependent base wasn't a record?");
6628c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall        EverDependent = true;
6638c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall        continue;
6648c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      }
6658c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6668c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall      // Recurse.  We don't need to clean up if this returns true.
667326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      CurPath.push_back(RD);
668326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
669326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall        return true;
670326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall      CurPath.pop_back();
6718c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    }
6728c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6738c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    return false;
6748c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  }
675326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall
676326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  bool findFriendship(const CXXRecordDecl *Cur) {
677326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    assert(CurPath.empty());
678326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    CurPath.push_back(Cur);
679326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall    return findFriendship(Cur, 0);
680326c8c7d6e6996c82a1da55c1c3cd6cb4b89a584John McCall  }
6818c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall};
6828c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall}
6838c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
6848c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// Search for a class P that EC is a friend of, under the constraint
685b9abd87283ac6e929b7e12a577663bc99e61d020John McCall///   InstanceContext <= P
686b9abd87283ac6e929b7e12a577663bc99e61d020John McCall/// if InstanceContext exists, or else
687b9abd87283ac6e929b7e12a577663bc99e61d020John McCall///   NamingClass <= P
6888c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// and with the additional restriction that a protected member of
689b9abd87283ac6e929b7e12a577663bc99e61d020John McCall/// NamingClass would have some natural access in P, which implicitly
690b9abd87283ac6e929b7e12a577663bc99e61d020John McCall/// imposes the constraint that P <= NamingClass.
6918c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///
692b9abd87283ac6e929b7e12a577663bc99e61d020John McCall/// This isn't quite the condition laid out in the standard.
693b9abd87283ac6e929b7e12a577663bc99e61d020John McCall/// Instead of saying that a notional protected member of NamingClass
694b9abd87283ac6e929b7e12a577663bc99e61d020John McCall/// would have to have some natural access in P, it says the actual
695b9abd87283ac6e929b7e12a577663bc99e61d020John McCall/// target has to have some natural access in P, which opens up the
696b9abd87283ac6e929b7e12a577663bc99e61d020John McCall/// possibility that the target (which is not necessarily a member
697b9abd87283ac6e929b7e12a577663bc99e61d020John McCall/// of NamingClass) might be more accessible along some path not
698b9abd87283ac6e929b7e12a577663bc99e61d020John McCall/// passing through it.  That's really a bad idea, though, because it
6998c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// introduces two problems:
700b9abd87283ac6e929b7e12a577663bc99e61d020John McCall///   - Most importantly, it breaks encapsulation because you can
701b9abd87283ac6e929b7e12a577663bc99e61d020John McCall///     access a forbidden base class's members by directly subclassing
702b9abd87283ac6e929b7e12a577663bc99e61d020John McCall///     it elsewhere.
703b9abd87283ac6e929b7e12a577663bc99e61d020John McCall///   - It also makes access substantially harder to compute because it
7048c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///     breaks the hill-climbing algorithm: knowing that the target is
7058c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///     accessible in some base class would no longer let you change
7068c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///     the question solely to whether the base class is accessible,
7078c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///     because the original target might have been more accessible
7088c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall///     because of crazy subclassing.
7098c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall/// So we don't implement that.
7108c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCallstatic AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
7118c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                                           const CXXRecordDecl *InstanceContext,
7128c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall                                           const CXXRecordDecl *NamingClass) {
7136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  assert(InstanceContext == nullptr ||
714b9abd87283ac6e929b7e12a577663bc99e61d020John McCall         InstanceContext->getCanonicalDecl() == InstanceContext);
7158c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  assert(NamingClass->getCanonicalDecl() == NamingClass);
7168c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
717b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  // If we don't have an instance context, our constraints give us
718b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  // that NamingClass <= P <= NamingClass, i.e. P == NamingClass.
719b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  // This is just the usual friendship check.
720b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  if (!InstanceContext) return GetFriendKind(S, EC, NamingClass);
721b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
7228c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
7238c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  if (PRC.findFriendship(InstanceContext)) return AR_accessible;
7248c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  if (PRC.EverDependent) return AR_dependent;
7258c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  return AR_inaccessible;
7268c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall}
7278c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall
728161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult HasAccess(Sema &S,
729161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              const EffectiveContext &EC,
730161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              const CXXRecordDecl *NamingClass,
731161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              AccessSpecifier Access,
732161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              const AccessTarget &Target) {
733db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(NamingClass->getCanonicalDecl() == NamingClass &&
734db73c684ba61fed4087af488e8610657ec638c17John McCall         "declaration should be canonicalized before being passed here");
735db73c684ba61fed4087af488e8610657ec638c17John McCall
736161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (Access == AS_public) return AR_accessible;
737db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(Access == AS_private || Access == AS_protected);
738db73c684ba61fed4087af488e8610657ec638c17John McCall
739161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessResult OnFailure = AR_inaccessible;
740161755a09898c95d21bfff33707da9ca41cd53c5John McCall
741db73c684ba61fed4087af488e8610657ec638c17John McCall  for (EffectiveContext::record_iterator
742db73c684ba61fed4087af488e8610657ec638c17John McCall         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
743db73c684ba61fed4087af488e8610657ec638c17John McCall    // All the declarations in EC have been canonicalized, so pointer
744db73c684ba61fed4087af488e8610657ec638c17John McCall    // equality from this point on will work fine.
745db73c684ba61fed4087af488e8610657ec638c17John McCall    const CXXRecordDecl *ECRecord = *I;
746db73c684ba61fed4087af488e8610657ec638c17John McCall
747db73c684ba61fed4087af488e8610657ec638c17John McCall    // [B2] and [M2]
748161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (Access == AS_private) {
749161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (ECRecord == NamingClass)
750161755a09898c95d21bfff33707da9ca41cd53c5John McCall        return AR_accessible;
751db73c684ba61fed4087af488e8610657ec638c17John McCall
75201ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall      if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
75301ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall        OnFailure = AR_dependent;
75401ebd9d1883e82c4188325900a4eb9c1e16353bbJohn McCall
755db73c684ba61fed4087af488e8610657ec638c17John McCall    // [B3] and [M3]
756161755a09898c95d21bfff33707da9ca41cd53c5John McCall    } else {
757161755a09898c95d21bfff33707da9ca41cd53c5John McCall      assert(Access == AS_protected);
758161755a09898c95d21bfff33707da9ca41cd53c5John McCall      switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
759161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_accessible: break;
760161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_inaccessible: continue;
761161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_dependent: OnFailure = AR_dependent; continue;
762161755a09898c95d21bfff33707da9ca41cd53c5John McCall      }
763161755a09898c95d21bfff33707da9ca41cd53c5John McCall
764161755a09898c95d21bfff33707da9ca41cd53c5John McCall      // C++ [class.protected]p1:
765161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   An additional access check beyond those described earlier in
766161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   [class.access] is applied when a non-static data member or
767161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   non-static member function is a protected member of its naming
768161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   class.  As described earlier, access to a protected member is
769161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   granted because the reference occurs in a friend or member of
770161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   some class C.  If the access is to form a pointer to member,
771161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   the nested-name-specifier shall name C or a class derived from
772161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   C. All other accesses involve a (possibly implicit) object
773161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   expression. In this case, the class of the object expression
774161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //   shall be C or a class derived from C.
775161755a09898c95d21bfff33707da9ca41cd53c5John McCall      //
776b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      // We interpret this as a restriction on [M3].
777b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
778b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      // In this part of the code, 'C' is just our context class ECRecord.
779b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
780b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      // These rules are different if we don't have an instance context.
781b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      if (!Target.hasInstanceContext()) {
782b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // If it's not an instance member, these restrictions don't apply.
783b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        if (!Target.isInstanceMember()) return AR_accessible;
784b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
785b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // If it's an instance member, use the pointer-to-member rule
786b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // that the naming class has to be derived from the effective
787b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // context.
788b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
789b2d899e9ae8a48c4057a48664213948934b877faFrancois Pichet        // Emulate a MSVC bug where the creation of pointer-to-member
790b2d899e9ae8a48c4057a48664213948934b877faFrancois Pichet        // to protected member of base class is allowed but only from
791b4143472c7763b84536328dee13f281df2d9040bFrancois Pichet        // static member functions.
792651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (S.getLangOpts().MSVCCompat && !EC.Functions.empty())
7932d01f2c414b8ef2ae23620ce6c9d3763c8bf73bfFrancois Pichet          if (CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
7942d01f2c414b8ef2ae23620ce6c9d3763c8bf73bfFrancois Pichet            if (MD->isStatic()) return AR_accessible;
795b2d899e9ae8a48c4057a48664213948934b877faFrancois Pichet
796b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // Despite the standard's confident wording, there is a case
797b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // where you can have an instance member that's neither in a
798b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // pointer-to-member expression nor in a member access:  when
799b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // it names a field in an unevaluated context that can't be an
800b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // implicit member.  Pending clarification, we just apply the
801b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // same naming-class restriction here.
802b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        //   FIXME: we're probably not correctly adding the
803b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        //   protected-member restriction when we retroactively convert
804b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        //   an expression to being evaluated.
805b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
806b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // We know that ECRecord derives from NamingClass.  The
807b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // restriction says to check whether NamingClass derives from
808b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // ECRecord, but that's not really necessary: two distinct
809b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // classes can't be recursively derived from each other.  So
810b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // along this path, we just need to check whether the classes
811b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // are equal.
812b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        if (NamingClass == ECRecord) return AR_accessible;
813b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
814b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        // Otherwise, this context class tells us nothing;  on to the next.
815b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        continue;
816b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      }
817b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
818b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      assert(Target.isInstanceMember());
819b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
820b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
821b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      if (!InstanceContext) {
822b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        OnFailure = AR_dependent;
823b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        continue;
824b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      }
825b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
826161755a09898c95d21bfff33707da9ca41cd53c5John McCall      switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
827161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_accessible: return AR_accessible;
828161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_inaccessible: continue;
829161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_dependent: OnFailure = AR_dependent; continue;
830161755a09898c95d21bfff33707da9ca41cd53c5John McCall      }
831161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
832db73c684ba61fed4087af488e8610657ec638c17John McCall  }
833db73c684ba61fed4087af488e8610657ec638c17John McCall
8348c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // [M3] and [B3] say that, if the target is protected in N, we grant
8358c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // access if the access occurs in a friend or member of some class P
8368c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // that's a subclass of N and where the target has some natural
8378c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // access in P.  The 'member' aspect is easy to handle because P
8388c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // would necessarily be one of the effective-context records, and we
8398c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // address that above.  The 'friend' aspect is completely ridiculous
8408c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // to implement because there are no restrictions at all on P
8418c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // *unless* the [class.protected] restriction applies.  If it does,
8428c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // however, we should ignore whether the naming class is a friend,
8438c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall  // and instead rely on whether any potential P is a friend.
844b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  if (Access == AS_protected && Target.isInstanceMember()) {
845b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    // Compute the instance context if possible.
8466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const CXXRecordDecl *InstanceContext = nullptr;
847b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    if (Target.hasInstanceContext()) {
848b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      InstanceContext = Target.resolveInstanceContext(S);
849b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      if (!InstanceContext) return AR_dependent;
850b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    }
851b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
8528c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
8538c77bcb072e7fd089f39fd7e079b6d767bf583faJohn McCall    case AR_accessible: return AR_accessible;
854161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: return OnFailure;
855161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent: return AR_dependent;
856161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
8571797a05f97671d40929224ac030c8c16fe69938cJohn McCall    llvm_unreachable("impossible friendship kind");
858161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
859161755a09898c95d21bfff33707da9ca41cd53c5John McCall
860161755a09898c95d21bfff33707da9ca41cd53c5John McCall  switch (GetFriendKind(S, EC, NamingClass)) {
861161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_accessible: return AR_accessible;
862161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_inaccessible: return OnFailure;
863161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_dependent: return AR_dependent;
864161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
865161755a09898c95d21bfff33707da9ca41cd53c5John McCall
866161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // Silence bogus warnings
867161755a09898c95d21bfff33707da9ca41cd53c5John McCall  llvm_unreachable("impossible friendship kind");
868db73c684ba61fed4087af488e8610657ec638c17John McCall}
869db73c684ba61fed4087af488e8610657ec638c17John McCall
8706b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Finds the best path from the naming class to the declaring class,
8716b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// taking friend declarations into account.
8726b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///
873db73c684ba61fed4087af488e8610657ec638c17John McCall/// C++0x [class.access.base]p5:
874db73c684ba61fed4087af488e8610657ec638c17John McCall///   A member m is accessible at the point R when named in class N if
875db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M1] m as a member of N is public, or
876db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M2] m as a member of N is private, and R occurs in a member or
877db73c684ba61fed4087af488e8610657ec638c17John McCall///        friend of class N, or
878db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M3] m as a member of N is protected, and R occurs in a member or
879db73c684ba61fed4087af488e8610657ec638c17John McCall///        friend of class N, or in a member or friend of a class P
880db73c684ba61fed4087af488e8610657ec638c17John McCall///        derived from N, where m as a member of P is public, private,
881db73c684ba61fed4087af488e8610657ec638c17John McCall///        or protected, or
882db73c684ba61fed4087af488e8610657ec638c17John McCall///   [M4] there exists a base class B of N that is accessible at R, and
883db73c684ba61fed4087af488e8610657ec638c17John McCall///        m is accessible at R when named in class B.
884db73c684ba61fed4087af488e8610657ec638c17John McCall///
885db73c684ba61fed4087af488e8610657ec638c17John McCall/// C++0x [class.access.base]p4:
886db73c684ba61fed4087af488e8610657ec638c17John McCall///   A base class B of N is accessible at R, if
887db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B1] an invented public member of B would be a public member of N, or
888db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B2] R occurs in a member or friend of class N, and an invented public
889db73c684ba61fed4087af488e8610657ec638c17John McCall///        member of B would be a private or protected member of N, or
890db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B3] R occurs in a member or friend of a class P derived from N, and an
891db73c684ba61fed4087af488e8610657ec638c17John McCall///        invented public member of B would be a private or protected member
892db73c684ba61fed4087af488e8610657ec638c17John McCall///        of P, or
893db73c684ba61fed4087af488e8610657ec638c17John McCall///   [B4] there exists a class S such that B is a base class of S accessible
894db73c684ba61fed4087af488e8610657ec638c17John McCall///        at R and S is a base class of N accessible at R.
895db73c684ba61fed4087af488e8610657ec638c17John McCall///
896db73c684ba61fed4087af488e8610657ec638c17John McCall/// Along a single inheritance path we can restate both of these
897db73c684ba61fed4087af488e8610657ec638c17John McCall/// iteratively:
898db73c684ba61fed4087af488e8610657ec638c17John McCall///
899db73c684ba61fed4087af488e8610657ec638c17John McCall/// First, we note that M1-4 are equivalent to B1-4 if the member is
900db73c684ba61fed4087af488e8610657ec638c17John McCall/// treated as a notional base of its declaring class with inheritance
901db73c684ba61fed4087af488e8610657ec638c17John McCall/// access equivalent to the member's access.  Therefore we need only
902db73c684ba61fed4087af488e8610657ec638c17John McCall/// ask whether a class B is accessible from a class N in context R.
903db73c684ba61fed4087af488e8610657ec638c17John McCall///
904db73c684ba61fed4087af488e8610657ec638c17John McCall/// Let B_1 .. B_n be the inheritance path in question (i.e. where
905db73c684ba61fed4087af488e8610657ec638c17John McCall/// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
906db73c684ba61fed4087af488e8610657ec638c17John McCall/// B_i).  For i in 1..n, we will calculate ACAB(i), the access to the
907db73c684ba61fed4087af488e8610657ec638c17John McCall/// closest accessible base in the path:
908db73c684ba61fed4087af488e8610657ec638c17John McCall///   Access(a, b) = (* access on the base specifier from a to b *)
909db73c684ba61fed4087af488e8610657ec638c17John McCall///   Merge(a, forbidden) = forbidden
910db73c684ba61fed4087af488e8610657ec638c17John McCall///   Merge(a, private) = forbidden
911db73c684ba61fed4087af488e8610657ec638c17John McCall///   Merge(a, b) = min(a,b)
912db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, forbidden) = false
913db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, private) = (R is c) || IsFriend(c, R)
914db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
915db73c684ba61fed4087af488e8610657ec638c17John McCall///   Accessible(c, public) = true
916db73c684ba61fed4087af488e8610657ec638c17John McCall///   ACAB(n) = public
917db73c684ba61fed4087af488e8610657ec638c17John McCall///   ACAB(i) =
918db73c684ba61fed4087af488e8610657ec638c17John McCall///     let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
919db73c684ba61fed4087af488e8610657ec638c17John McCall///     if Accessible(B_i, AccessToBase) then public else AccessToBase
920db73c684ba61fed4087af488e8610657ec638c17John McCall///
921f3477c13eeaf11b32a41f181398fb5deffd0dd73Sylvestre Ledru/// B is an accessible base of N at R iff ACAB(1) = public.
922db73c684ba61fed4087af488e8610657ec638c17John McCall///
923161755a09898c95d21bfff33707da9ca41cd53c5John McCall/// \param FinalAccess the access of the "final step", or AS_public if
9247aceaf8cee77c98478e8934dc283910292711a7eJohn McCall///   there is no final step.
9256b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \return null if friendship is dependent
9266b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstatic CXXBasePath *FindBestPath(Sema &S,
9276b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                 const EffectiveContext &EC,
928161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 AccessTarget &Target,
9297aceaf8cee77c98478e8934dc283910292711a7eJohn McCall                                 AccessSpecifier FinalAccess,
9306b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                 CXXBasePaths &Paths) {
9316b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // Derive the paths to the desired base.
932161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *Derived = Target.getNamingClass();
933161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *Base = Target.getDeclaringClass();
934161755a09898c95d21bfff33707da9ca41cd53c5John McCall
935161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // FIXME: fail correctly when there are dependent paths.
936161755a09898c95d21bfff33707da9ca41cd53c5John McCall  bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
937161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                          Paths);
9386b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  assert(isDerived && "derived class not actually derived from base");
9396b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  (void) isDerived;
9406b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
9416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  CXXBasePath *BestPath = nullptr;
9426b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
9437aceaf8cee77c98478e8934dc283910292711a7eJohn McCall  assert(FinalAccess != AS_none && "forbidden access after declaring class");
9447aceaf8cee77c98478e8934dc283910292711a7eJohn McCall
9450c01d18094100db92d38daa923c95661512db203John McCall  bool AnyDependent = false;
9460c01d18094100db92d38daa923c95661512db203John McCall
9476b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // Derive the friend-modified access along each path.
9486b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
9496b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall         PI != PE; ++PI) {
950161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
9516b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
9526b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // Walk through the path backwards.
9537aceaf8cee77c98478e8934dc283910292711a7eJohn McCall    AccessSpecifier PathAccess = FinalAccess;
9546b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    CXXBasePath::iterator I = PI->end(), E = PI->begin();
9556b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    while (I != E) {
9566b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      --I;
9576b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
9587aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      assert(PathAccess != AS_none);
9597aceaf8cee77c98478e8934dc283910292711a7eJohn McCall
9607aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      // If the declaration is a private member of a base class, there
9617aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      // is no level of friendship in derived classes that can make it
9627aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      // accessible.
9637aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      if (PathAccess == AS_private) {
9647aceaf8cee77c98478e8934dc283910292711a7eJohn McCall        PathAccess = AS_none;
9657aceaf8cee77c98478e8934dc283910292711a7eJohn McCall        break;
9667aceaf8cee77c98478e8934dc283910292711a7eJohn McCall      }
9677aceaf8cee77c98478e8934dc283910292711a7eJohn McCall
968161755a09898c95d21bfff33707da9ca41cd53c5John McCall      const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
969161755a09898c95d21bfff33707da9ca41cd53c5John McCall
9706b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
971db73c684ba61fed4087af488e8610657ec638c17John McCall      PathAccess = std::max(PathAccess, BaseAccess);
972161755a09898c95d21bfff33707da9ca41cd53c5John McCall
973161755a09898c95d21bfff33707da9ca41cd53c5John McCall      switch (HasAccess(S, EC, NC, PathAccess, Target)) {
974161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_inaccessible: break;
975161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_accessible:
976161755a09898c95d21bfff33707da9ca41cd53c5John McCall        PathAccess = AS_public;
977161755a09898c95d21bfff33707da9ca41cd53c5John McCall
978161755a09898c95d21bfff33707da9ca41cd53c5John McCall        // Future tests are not against members and so do not have
979161755a09898c95d21bfff33707da9ca41cd53c5John McCall        // instance context.
980161755a09898c95d21bfff33707da9ca41cd53c5John McCall        Target.suppressInstanceContext();
981161755a09898c95d21bfff33707da9ca41cd53c5John McCall        break;
982161755a09898c95d21bfff33707da9ca41cd53c5John McCall      case AR_dependent:
983db73c684ba61fed4087af488e8610657ec638c17John McCall        AnyDependent = true;
984db73c684ba61fed4087af488e8610657ec638c17John McCall        goto Next;
985c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson      }
986c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson    }
987726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
9886b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // Note that we modify the path's Access field to the
9896b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    // friend-modified access.
9906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (BestPath == nullptr || PathAccess < BestPath->Access) {
9916b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      BestPath = &*PI;
9926b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall      BestPath->Access = PathAccess;
9930c01d18094100db92d38daa923c95661512db203John McCall
9940c01d18094100db92d38daa923c95661512db203John McCall      // Short-circuit if we found a public path.
9950c01d18094100db92d38daa923c95661512db203John McCall      if (BestPath->Access == AS_public)
9960c01d18094100db92d38daa923c95661512db203John McCall        return BestPath;
997c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson    }
9980c01d18094100db92d38daa923c95661512db203John McCall
9990c01d18094100db92d38daa923c95661512db203John McCall  Next: ;
1000c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson  }
1001c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson
10020c01d18094100db92d38daa923c95661512db203John McCall  assert((!BestPath || BestPath->Access != AS_public) &&
10030c01d18094100db92d38daa923c95661512db203John McCall         "fell out of loop with public path");
10040c01d18094100db92d38daa923c95661512db203John McCall
10050c01d18094100db92d38daa923c95661512db203John McCall  // We didn't find a public path, but at least one path was subject
10060c01d18094100db92d38daa923c95661512db203John McCall  // to dependent friendship, so delay the check.
10070c01d18094100db92d38daa923c95661512db203John McCall  if (AnyDependent)
10086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
10090c01d18094100db92d38daa923c95661512db203John McCall
10106b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  return BestPath;
1011726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl}
1012726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
1013fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall/// Given that an entity has protected natural access, check whether
1014fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall/// access might be denied because of the protected member access
1015fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall/// restriction.
1016fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall///
1017fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall/// \return true if a note was emitted
1018fe24e05a87e48fa3318b65d1a92c542107639fd9John McCallstatic bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
1019fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall                                       AccessTarget &Target) {
1020fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  // Only applies to instance accesses.
1021b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  if (!Target.isInstanceMember())
1022fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    return false;
1023b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
1024fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  assert(Target.isMemberAccess());
1025fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
1026714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass();
1027fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
1028fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  for (EffectiveContext::record_iterator
1029fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1030fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    const CXXRecordDecl *ECRecord = *I;
1031b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
1032fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_accessible: break;
1033fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_inaccessible: continue;
1034fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_dependent: continue;
1035fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    }
1036fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
1037fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    // The effective context is a subclass of the declaring class.
1038b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    // Check whether the [class.protected] restriction is limiting
1039b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    // access.
1040fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
1041fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    // To get this exactly right, this might need to be checked more
1042fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    // holistically;  it's not necessarily the case that gaining
1043fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    // access here would grant us access overall.
1044fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
1045b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    NamedDecl *D = Target.getTargetDecl();
1046b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
1047b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    // If we don't have an instance context, [class.protected] says the
1048b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    // naming class has to equal the context class.
1049b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    if (!Target.hasInstanceContext()) {
1050b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      // If it does, the restriction doesn't apply.
1051b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      if (NamingClass == ECRecord) continue;
1052b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
1053b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      // TODO: it would be great to have a fixit here, since this is
1054b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      // such an obvious error.
1055b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      S.Diag(D->getLocation(), diag::note_access_protected_restricted_noobject)
1056b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        << S.Context.getTypeDeclType(ECRecord);
1057b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      return true;
1058b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    }
1059b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
1060fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
1061fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    assert(InstanceContext && "diagnosing dependent access");
1062fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
1063fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
1064fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_accessible: continue;
1065fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_dependent: continue;
1066fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    case AR_inaccessible:
1067b9abd87283ac6e929b7e12a577663bc99e61d020John McCall      break;
1068b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    }
1069b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
1070b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    // Okay, the restriction seems to be what's limiting us.
1071b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
1072b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    // Use a special diagnostic for constructors and destructors.
1073b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
1074b9abd87283ac6e929b7e12a577663bc99e61d020John McCall        (isa<FunctionTemplateDecl>(D) &&
1075b9abd87283ac6e929b7e12a577663bc99e61d020John McCall         isa<CXXConstructorDecl>(
1076b9abd87283ac6e929b7e12a577663bc99e61d020John McCall                cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1077651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return S.Diag(D->getLocation(),
1078651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    diag::note_access_protected_restricted_ctordtor)
1079651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines             << isa<CXXDestructorDecl>(D->getAsFunction());
1080fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall    }
1081b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
1082b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    // Otherwise, use the generic diagnostic.
1083651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return S.Diag(D->getLocation(),
1084651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                  diag::note_access_protected_restricted_object)
1085651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           << S.Context.getTypeDeclType(ECRecord);
1086fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  }
1087fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
1088fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall  return false;
1089fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall}
1090fe24e05a87e48fa3318b65d1a92c542107639fd9John McCall
1091714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall/// We are unable to access a given declaration due to its direct
1092714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall/// access control;  diagnose that.
1093714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCallstatic void diagnoseBadDirectAccess(Sema &S,
1094714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall                                    const EffectiveContext &EC,
1095714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall                                    AccessTarget &entity) {
1096714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  assert(entity.isMemberAccess());
1097714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  NamedDecl *D = entity.getTargetDecl();
1098714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
1099714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  if (D->getAccess() == AS_protected &&
1100714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      TryDiagnoseProtectedAccess(S, EC, entity))
1101714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    return;
1102714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
1103714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // Find an original declaration.
1104714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  while (D->isOutOfLine()) {
11056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    NamedDecl *PrevDecl = nullptr;
1106714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    if (VarDecl *VD = dyn_cast<VarDecl>(D))
1107714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      PrevDecl = VD->getPreviousDecl();
1108714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1109714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      PrevDecl = FD->getPreviousDecl();
1110714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
1111714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      PrevDecl = TND->getPreviousDecl();
1112714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
1113714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1114714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall        break;
1115714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      PrevDecl = TD->getPreviousDecl();
1116714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    }
1117714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    if (!PrevDecl) break;
1118714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    D = PrevDecl;
1119714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  }
1120714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
1121714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
1122714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  Decl *ImmediateChild;
1123714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  if (D->getDeclContext() == DeclaringClass)
1124714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    ImmediateChild = D;
1125714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  else {
1126714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    DeclContext *DC = D->getDeclContext();
1127714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    while (DC->getParent() != DeclaringClass)
1128714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      DC = DC->getParent();
1129714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    ImmediateChild = cast<Decl>(DC);
1130714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  }
1131714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
1132714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // Check whether there's an AccessSpecDecl preceding this in the
1133714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // chain of the DeclContext.
1134714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  bool isImplicit = true;
1135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *I : DeclaringClass->decls()) {
1136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (I == ImmediateChild) break;
1137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (isa<AccessSpecDecl>(I)) {
1138714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      isImplicit = false;
1139714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      break;
1140714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    }
1141714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  }
1142714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
1143714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  S.Diag(D->getLocation(), diag::note_access_natural)
1144714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    << (unsigned) (D->getAccess() == AS_protected)
1145714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    << isImplicit;
1146714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall}
1147714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
11486b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Diagnose the path which caused the given declaration or base class
11496b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// to become inaccessible.
11506b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstatic void DiagnoseAccessPath(Sema &S,
11516b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                               const EffectiveContext &EC,
1152714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall                               AccessTarget &entity) {
1153714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // Save the instance context to preserve invariants.
1154714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1155db73c684ba61fed4087af488e8610657ec638c17John McCall
1156714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // This basically repeats the main algorithm but keeps some more
1157714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // information.
1158db73c684ba61fed4087af488e8610657ec638c17John McCall
1159714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // The natural access so far.
1160714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  AccessSpecifier accessSoFar = AS_public;
1161aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall
1162714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // Check whether we have special rights to the declaring class.
1163714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  if (entity.isMemberAccess()) {
1164714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    NamedDecl *D = entity.getTargetDecl();
1165714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    accessSoFar = D->getAccess();
1166714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1167aa56a66abb61e9f42b48ae88e43328aba10c9148John McCall
1168714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    switch (HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1169714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    // If the declaration is accessible when named in its declaring
1170714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    // class, then we must be constrained by the path.
1171714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    case AR_accessible:
1172714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      accessSoFar = AS_public;
1173714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      entity.suppressInstanceContext();
1174714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      break;
1175726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
1176714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    case AR_inaccessible:
1177714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      if (accessSoFar == AS_private ||
1178714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall          declaringClass == entity.getEffectiveNamingClass())
1179714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall        return diagnoseBadDirectAccess(S, EC, entity);
1180714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      break;
1181726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
1182161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
1183714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      llvm_unreachable("cannot diagnose dependent access");
11846b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
11856b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
1186c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson
1187714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  CXXBasePaths paths;
1188714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  CXXBasePath &path = *FindBestPath(S, EC, entity, accessSoFar, paths);
1189714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  assert(path.Access != AS_public);
1190726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
1191714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  CXXBasePath::iterator i = path.end(), e = path.begin();
1192714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  CXXBasePath::iterator constrainingBase = i;
1193714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  while (i != e) {
1194714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    --i;
1195c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson
1196714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    assert(accessSoFar != AS_none && accessSoFar != AS_private);
11976b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1198714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    // Is the entity accessible when named in the deriving class, as
1199714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    // modified by the base specifier?
1200714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    const CXXRecordDecl *derivingClass = i->Class->getCanonicalDecl();
1201714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    const CXXBaseSpecifier *base = i->Base;
12026b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1203714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    // If the access to this base is worse than the access we have to
1204714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    // the declaration, remember it.
1205714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    AccessSpecifier baseAccess = base->getAccessSpecifier();
1206714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    if (baseAccess > accessSoFar) {
1207714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      constrainingBase = i;
1208714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      accessSoFar = baseAccess;
1209714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    }
1210714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
1211714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    switch (HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1212161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: break;
1213714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    case AR_accessible:
1214714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      accessSoFar = AS_public;
1215714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      entity.suppressInstanceContext();
12166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      constrainingBase = nullptr;
1217714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      break;
1218161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
1219714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      llvm_unreachable("cannot diagnose dependent access");
12206b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
12216b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1222714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    // If this was private inheritance, but we don't have access to
1223714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    // the deriving class, we're done.
1224714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    if (accessSoFar == AS_private) {
1225714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      assert(baseAccess == AS_private);
1226714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      assert(constrainingBase == i);
1227714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      break;
12286b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
1229c4f1e87138bfe5d3aaccff13c86b383a255bca42Anders Carlsson  }
1230726212f41bac77dc7f3352bc7047615fa0cd9e58Sebastian Redl
1231714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // If we don't have a constraining base, the access failure must be
1232714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // due to the original declaration.
1233714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  if (constrainingBase == path.end())
1234714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    return diagnoseBadDirectAccess(S, EC, entity);
1235714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
1236714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // We're constrained by inheritance, but we want to say
1237714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // "declared private here" if we're diagnosing a hierarchy
1238714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  // conversion and this is the final step.
1239714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  unsigned diagnostic;
1240714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  if (entity.isMemberAccess() ||
1241714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall      constrainingBase + 1 != path.end()) {
1242714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    diagnostic = diag::note_access_constrained_by_path;
1243714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  } else {
1244714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    diagnostic = diag::note_access_natural;
1245714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  }
1246714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
1247714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  const CXXBaseSpecifier *base = constrainingBase->Base;
1248714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
1249714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  S.Diag(base->getSourceRange().getBegin(), diagnostic)
1250714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    << base->getSourceRange()
1251714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    << (base->getAccessSpecifier() == AS_protected)
1252714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall    << (base->getAccessSpecifierAsWritten() == AS_none);
1253714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall
1254714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  if (entity.isMemberAccess())
1255c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    S.Diag(entity.getTargetDecl()->getLocation(),
1256c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines           diag::note_member_declared_at);
125729f006be830fbbcaa0c1cf7c7399bb5080dc7f32Anders Carlsson}
125892f883177b162928a8e632e4e3b93fafd2b26072John McCall
1259db73c684ba61fed4087af488e8610657ec638c17John McCallstatic void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
1260db73c684ba61fed4087af488e8610657ec638c17John McCall                              const EffectiveContext &EC,
1261161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              AccessTarget &Entity) {
1262db73c684ba61fed4087af488e8610657ec638c17John McCall  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
1263161755a09898c95d21bfff33707da9ca41cd53c5John McCall  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
12646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr);
12656b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
126658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  S.Diag(Loc, Entity.getDiag())
1267db73c684ba61fed4087af488e8610657ec638c17John McCall    << (Entity.getAccess() == AS_protected)
1268db73c684ba61fed4087af488e8610657ec638c17John McCall    << (D ? D->getDeclName() : DeclarationName())
126958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << S.Context.getTypeDeclType(NamingClass)
127058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << S.Context.getTypeDeclType(DeclaringClass);
1271db73c684ba61fed4087af488e8610657ec638c17John McCall  DiagnoseAccessPath(S, EC, Entity);
12726b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
127392f883177b162928a8e632e4e3b93fafd2b26072John McCall
1274b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet/// MSVC has a bug where if during an using declaration name lookup,
1275b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet/// the declaration found is unaccessible (private) and that declaration
1276b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet/// was bring into scope via another using declaration whose target
1277b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet/// declaration is accessible (public) then no error is generated.
1278b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet/// Example:
1279b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///   class A {
1280b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///   public:
1281b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///     int f();
1282b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///   };
1283b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///   class B : public A {
1284b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///   private:
1285b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///     using A::f;
1286b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///   };
1287b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///   class C : public B {
1288b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///   private:
1289b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///     using B::f;
1290b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///   };
1291b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet///
1292b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet/// Here, B::f is private so this should fail in Standard C++, but
1293b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet/// because B::f refers to A::f which is public MSVC accepts it.
1294b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichetstatic bool IsMicrosoftUsingDeclarationAccessBug(Sema& S,
1295b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet                                                 SourceLocation AccessLoc,
1296b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet                                                 AccessTarget &Entity) {
1297b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet  if (UsingShadowDecl *Shadow =
1298b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet                         dyn_cast<UsingShadowDecl>(Entity.getTargetDecl())) {
1299b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet    const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1300b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet    if (Entity.getTargetDecl()->getAccess() == AS_private &&
1301b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet        (OrigDecl->getAccess() == AS_public ||
1302b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet         OrigDecl->getAccess() == AS_protected)) {
1303d7c56e1114bfe7d461786903bb720d2c6efc05a1Richard Smith      S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1304b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet        << Shadow->getUsingDecl()->getQualifiedNameAsString()
1305b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet        << OrigDecl->getQualifiedNameAsString();
1306b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet      return true;
1307b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet    }
1308b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet  }
1309b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet  return false;
1310b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet}
1311b2ee8305f878259613b65d0f96a03f7f852977eaFrancois Pichet
1312db73c684ba61fed4087af488e8610657ec638c17John McCall/// Determines whether the accessed entity is accessible.  Public members
1313db73c684ba61fed4087af488e8610657ec638c17John McCall/// have been weeded out by this point.
1314161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult IsAccessible(Sema &S,
1315161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 const EffectiveContext &EC,
1316161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 AccessTarget &Entity) {
1317db73c684ba61fed4087af488e8610657ec638c17John McCall  // Determine the actual naming class.
1318714b509bb4f8be76e6616944551efe7a6e8358cdJohn McCall  const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
131992f883177b162928a8e632e4e3b93fafd2b26072John McCall
1320db73c684ba61fed4087af488e8610657ec638c17John McCall  AccessSpecifier UnprivilegedAccess = Entity.getAccess();
1321db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(UnprivilegedAccess != AS_public && "public access not weeded out");
132292f883177b162928a8e632e4e3b93fafd2b26072John McCall
1323db73c684ba61fed4087af488e8610657ec638c17John McCall  // Before we try to recalculate access paths, try to white-list
1324db73c684ba61fed4087af488e8610657ec638c17John McCall  // accesses which just trade in on the final step, i.e. accesses
1325db73c684ba61fed4087af488e8610657ec638c17John McCall  // which don't require [M4] or [B4]. These are by far the most
1326161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // common forms of privileged access.
1327db73c684ba61fed4087af488e8610657ec638c17John McCall  if (UnprivilegedAccess != AS_none) {
1328161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1329161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent:
1330db73c684ba61fed4087af488e8610657ec638c17John McCall      // This is actually an interesting policy decision.  We don't
1331db73c684ba61fed4087af488e8610657ec638c17John McCall      // *have* to delay immediately here: we can do the full access
1332db73c684ba61fed4087af488e8610657ec638c17John McCall      // calculation in the hope that friendship on some intermediate
1333db73c684ba61fed4087af488e8610657ec638c17John McCall      // class will make the declaration accessible non-dependently.
1334db73c684ba61fed4087af488e8610657ec638c17John McCall      // But that's not cheap, and odds are very good (note: assertion
1335db73c684ba61fed4087af488e8610657ec638c17John McCall      // made without data) that the friend declaration will determine
1336db73c684ba61fed4087af488e8610657ec638c17John McCall      // access.
1337161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return AR_dependent;
1338db73c684ba61fed4087af488e8610657ec638c17John McCall
1339161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible: return AR_accessible;
1340161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: break;
1341db73c684ba61fed4087af488e8610657ec638c17John McCall    }
1342db73c684ba61fed4087af488e8610657ec638c17John McCall  }
134392f883177b162928a8e632e4e3b93fafd2b26072John McCall
1344161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1345db73c684ba61fed4087af488e8610657ec638c17John McCall
1346db73c684ba61fed4087af488e8610657ec638c17John McCall  // We lower member accesses to base accesses by pretending that the
1347db73c684ba61fed4087af488e8610657ec638c17John McCall  // member is a base class of its declaring class.
1348db73c684ba61fed4087af488e8610657ec638c17John McCall  AccessSpecifier FinalAccess;
13496b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
13506b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (Entity.isMemberAccess()) {
1351db73c684ba61fed4087af488e8610657ec638c17John McCall    // Determine if the declaration is accessible from EC when named
1352db73c684ba61fed4087af488e8610657ec638c17John McCall    // in its declaring class.
13536b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    NamedDecl *Target = Entity.getTargetDecl();
1354161755a09898c95d21bfff33707da9ca41cd53c5John McCall    const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
13556b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1356db73c684ba61fed4087af488e8610657ec638c17John McCall    FinalAccess = Target->getAccess();
1357161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1358161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_accessible:
1359637619b915888ead5576d19508644e4eb9024078John McCall      // Target is accessible at EC when named in its declaring class.
1360637619b915888ead5576d19508644e4eb9024078John McCall      // We can now hill-climb and simply check whether the declaring
1361637619b915888ead5576d19508644e4eb9024078John McCall      // class is accessible as a base of the naming class.  This is
1362637619b915888ead5576d19508644e4eb9024078John McCall      // equivalent to checking the access of a notional public
1363637619b915888ead5576d19508644e4eb9024078John McCall      // member with no instance context.
1364161755a09898c95d21bfff33707da9ca41cd53c5John McCall      FinalAccess = AS_public;
1365637619b915888ead5576d19508644e4eb9024078John McCall      Entity.suppressInstanceContext();
1366161755a09898c95d21bfff33707da9ca41cd53c5John McCall      break;
1367161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_inaccessible: break;
1368161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case AR_dependent: return AR_dependent; // see above
13696b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    }
13702f514480c448708ec382a684cf5e035d3a827ec8John McCall
1371db73c684ba61fed4087af488e8610657ec638c17John McCall    if (DeclaringClass == NamingClass)
1372161755a09898c95d21bfff33707da9ca41cd53c5John McCall      return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
1373db73c684ba61fed4087af488e8610657ec638c17John McCall  } else {
1374db73c684ba61fed4087af488e8610657ec638c17John McCall    FinalAccess = AS_public;
13756b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  }
13762f514480c448708ec382a684cf5e035d3a827ec8John McCall
1377161755a09898c95d21bfff33707da9ca41cd53c5John McCall  assert(Entity.getDeclaringClass() != NamingClass);
13786b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
13796b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // Append the declaration's access if applicable.
13806b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXBasePaths Paths;
1381161755a09898c95d21bfff33707da9ca41cd53c5John McCall  CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
13820c01d18094100db92d38daa923c95661512db203John McCall  if (!Path)
1383161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_dependent;
138492f883177b162928a8e632e4e3b93fafd2b26072John McCall
1385db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(Path->Access <= UnprivilegedAccess &&
1386db73c684ba61fed4087af488e8610657ec638c17John McCall         "access along best path worse than direct?");
1387db73c684ba61fed4087af488e8610657ec638c17John McCall  if (Path->Access == AS_public)
1388161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_accessible;
1389161755a09898c95d21bfff33707da9ca41cd53c5John McCall  return AR_inaccessible;
13900c01d18094100db92d38daa923c95661512db203John McCall}
13910c01d18094100db92d38daa923c95661512db203John McCall
1392161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic void DelayDependentAccess(Sema &S,
1393161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 const EffectiveContext &EC,
1394161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 SourceLocation Loc,
1395161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 const AccessTarget &Entity) {
13960c01d18094100db92d38daa923c95661512db203John McCall  assert(EC.isDependent() && "delaying non-dependent access");
13977ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  DeclContext *DC = EC.getInnerContext();
13980c01d18094100db92d38daa923c95661512db203John McCall  assert(DC->isDependentContext() && "delaying non-dependent access");
13990c01d18094100db92d38daa923c95661512db203John McCall  DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access,
14000c01d18094100db92d38daa923c95661512db203John McCall                              Loc,
14010c01d18094100db92d38daa923c95661512db203John McCall                              Entity.isMemberAccess(),
14020c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getAccess(),
14030c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getTargetDecl(),
14040c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getNamingClass(),
1405161755a09898c95d21bfff33707da9ca41cd53c5John McCall                              Entity.getBaseObjectType(),
14060c01d18094100db92d38daa923c95661512db203John McCall                              Entity.getDiag());
14076b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
14086b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
14096b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Checks access to an entity from the given effective context.
1410161755a09898c95d21bfff33707da9ca41cd53c5John McCallstatic AccessResult CheckEffectiveAccess(Sema &S,
1411161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                         const EffectiveContext &EC,
1412161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                         SourceLocation Loc,
1413161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                         AccessTarget &Entity) {
1414db73c684ba61fed4087af488e8610657ec638c17John McCall  assert(Entity.getAccess() != AS_public && "called for public access!");
141592f883177b162928a8e632e4e3b93fafd2b26072John McCall
1416db73c684ba61fed4087af488e8610657ec638c17John McCall  switch (IsAccessible(S, EC, Entity)) {
1417161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_dependent:
1418161755a09898c95d21bfff33707da9ca41cd53c5John McCall    DelayDependentAccess(S, EC, Loc, Entity);
1419161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_dependent;
14200c01d18094100db92d38daa923c95661512db203John McCall
1421161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_inaccessible:
1422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (S.getLangOpts().MSVCCompat &&
1423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity))
1424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return AR_accessible;
1425db73c684ba61fed4087af488e8610657ec638c17John McCall    if (!Entity.isQuiet())
1426db73c684ba61fed4087af488e8610657ec638c17John McCall      DiagnoseBadAccess(S, Loc, EC, Entity);
1427161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_inaccessible;
142892f883177b162928a8e632e4e3b93fafd2b26072John McCall
1429161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_accessible:
1430161755a09898c95d21bfff33707da9ca41cd53c5John McCall    return AR_accessible;
1431db73c684ba61fed4087af488e8610657ec638c17John McCall  }
1432db73c684ba61fed4087af488e8610657ec638c17John McCall
1433161755a09898c95d21bfff33707da9ca41cd53c5John McCall  // silence unnecessary warning
1434161755a09898c95d21bfff33707da9ca41cd53c5John McCall  llvm_unreachable("invalid access result");
14356b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
143692f883177b162928a8e632e4e3b93fafd2b26072John McCall
14376b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallstatic Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
1438161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                      AccessTarget &Entity) {
14396b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  // If the access path is public, it's accessible everywhere.
14406b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (Entity.getAccess() == AS_public)
14416b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return Sema::AR_accessible;
144292f883177b162928a8e632e4e3b93fafd2b26072John McCall
1443eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // If we're currently parsing a declaration, we may need to delay
1444eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // access control checking, because our effective context might be
1445eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // different based on what the declaration comes out as.
1446eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  //
1447eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // For example, we might be parsing a declaration with a scope
1448eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // specifier, like this:
1449eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  //   A::private_type A::foo() { ... }
1450eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  //
1451eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  // Or we might be parsing something that will turn out to be a friend:
1452eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  //   void foo(A::private_type);
1453eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  //   void B::foo(A::private_type);
1454eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
1455eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall    S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
14566b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return Sema::AR_delayed;
145792f883177b162928a8e632e4e3b93fafd2b26072John McCall  }
145892f883177b162928a8e632e4e3b93fafd2b26072John McCall
1459161755a09898c95d21bfff33707da9ca41cd53c5John McCall  EffectiveContext EC(S.CurContext);
1460161755a09898c95d21bfff33707da9ca41cd53c5John McCall  switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
1461161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_accessible: return Sema::AR_accessible;
1462161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_inaccessible: return Sema::AR_inaccessible;
1463161755a09898c95d21bfff33707da9ca41cd53c5John McCall  case AR_dependent: return Sema::AR_dependent;
1464161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
1465161755a09898c95d21bfff33707da9ca41cd53c5John McCall  llvm_unreachable("falling off end");
146692f883177b162928a8e632e4e3b93fafd2b26072John McCall}
146792f883177b162928a8e632e4e3b93fafd2b26072John McCall
1468cad7e43c5aba88bf6affc155b02d8609485db41bRichard Smithvoid Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) {
14694bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  // Access control for names used in the declarations of functions
14704bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  // and function templates should normally be evaluated in the context
14714bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  // of the declaration, just in case it's a friend of something.
14724bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  // However, this does not apply to local extern declarations.
14734bfd680597862e437fcba739dce58531d0b15d6eJohn McCall
1474cad7e43c5aba88bf6affc155b02d8609485db41bRichard Smith  DeclContext *DC = D->getDeclContext();
1475651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  if (D->isLocalExternDecl()) {
1476651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DC = D->getLexicalDeclContext();
1477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  } else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1478651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DC = FN;
1479cad7e43c5aba88bf6affc155b02d8609485db41bRichard Smith  } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1480cad7e43c5aba88bf6affc155b02d8609485db41bRichard Smith    DC = cast<DeclContext>(TD->getTemplatedDecl());
14814bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  }
14824bfd680597862e437fcba739dce58531d0b15d6eJohn McCall
1483630eb01b2568d0958118eb1a0ded02bebecb2b0fChandler Carruth  EffectiveContext EC(DC);
14842f514480c448708ec382a684cf5e035d3a827ec8John McCall
1485161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Target(DD.getAccessData());
1486161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1487161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
14882f514480c448708ec382a684cf5e035d3a827ec8John McCall    DD.Triggered = true;
14892f514480c448708ec382a684cf5e035d3a827ec8John McCall}
14902f514480c448708ec382a684cf5e035d3a827ec8John McCall
14910c01d18094100db92d38daa923c95661512db203John McCallvoid Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD,
14920c01d18094100db92d38daa923c95661512db203John McCall                        const MultiLevelTemplateArgumentList &TemplateArgs) {
14930c01d18094100db92d38daa923c95661512db203John McCall  SourceLocation Loc = DD.getAccessLoc();
14940c01d18094100db92d38daa923c95661512db203John McCall  AccessSpecifier Access = DD.getAccess();
14950c01d18094100db92d38daa923c95661512db203John McCall
14960c01d18094100db92d38daa923c95661512db203John McCall  Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
14970c01d18094100db92d38daa923c95661512db203John McCall                                       TemplateArgs);
14980c01d18094100db92d38daa923c95661512db203John McCall  if (!NamingD) return;
14990c01d18094100db92d38daa923c95661512db203John McCall  Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
15000c01d18094100db92d38daa923c95661512db203John McCall                                       TemplateArgs);
15010c01d18094100db92d38daa923c95661512db203John McCall  if (!TargetD) return;
15020c01d18094100db92d38daa923c95661512db203John McCall
15030c01d18094100db92d38daa923c95661512db203John McCall  if (DD.isAccessToMember()) {
1504161755a09898c95d21bfff33707da9ca41cd53c5John McCall    CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
1505161755a09898c95d21bfff33707da9ca41cd53c5John McCall    NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1506161755a09898c95d21bfff33707da9ca41cd53c5John McCall    QualType BaseObjectType = DD.getAccessBaseObjectType();
1507161755a09898c95d21bfff33707da9ca41cd53c5John McCall    if (!BaseObjectType.isNull()) {
1508161755a09898c95d21bfff33707da9ca41cd53c5John McCall      BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1509161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 DeclarationName());
1510161755a09898c95d21bfff33707da9ca41cd53c5John McCall      if (BaseObjectType.isNull()) return;
1511161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
1512161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1513161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget Entity(Context,
1514161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        AccessTarget::Member,
1515161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        NamingClass,
1516161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        DeclAccessPair::make(TargetDecl, Access),
1517161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        BaseObjectType);
15180c01d18094100db92d38daa923c95661512db203John McCall    Entity.setDiag(DD.getDiagnostic());
15190c01d18094100db92d38daa923c95661512db203John McCall    CheckAccess(*this, Loc, Entity);
15200c01d18094100db92d38daa923c95661512db203John McCall  } else {
1521161755a09898c95d21bfff33707da9ca41cd53c5John McCall    AccessTarget Entity(Context,
1522161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        AccessTarget::Base,
1523161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        cast<CXXRecordDecl>(TargetD),
1524161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        cast<CXXRecordDecl>(NamingD),
1525161755a09898c95d21bfff33707da9ca41cd53c5John McCall                        Access);
15260c01d18094100db92d38daa923c95661512db203John McCall    Entity.setDiag(DD.getDiagnostic());
15270c01d18094100db92d38daa923c95661512db203John McCall    CheckAccess(*this, Loc, Entity);
15280c01d18094100db92d38daa923c95661512db203John McCall  }
15290c01d18094100db92d38daa923c95661512db203John McCall}
15300c01d18094100db92d38daa923c95661512db203John McCall
15316b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
15329aa472c45d2bd81b7b52c225e8acc560d716db97John McCall                                                     DeclAccessPair Found) {
15334e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().AccessControl ||
153458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall      !E->getNamingClass() ||
15359aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
15366b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
1537c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
1538161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1539161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      Found, QualType());
154058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(diag::err_access) << E->getSourceRange();
154158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
154258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, E->getNameLoc(), Entity);
1543c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall}
1544c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
1545c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall/// Perform access-control checking on a previously-unresolved member
1546c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall/// access which has now been resolved to a member.
15476b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
15489aa472c45d2bd81b7b52c225e8acc560d716db97John McCall                                                     DeclAccessPair Found) {
15494e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().AccessControl ||
15509aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
15516b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
1552c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
1553161755a09898c95d21bfff33707da9ca41cd53c5John McCall  QualType BaseType = E->getBaseType();
1554161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (E->isArrow())
1555161755a09898c95d21bfff33707da9ca41cd53c5John McCall    BaseType = BaseType->getAs<PointerType>()->getPointeeType();
1556161755a09898c95d21bfff33707da9ca41cd53c5John McCall
1557161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1558161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      Found, BaseType);
155958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(diag::err_access) << E->getSourceRange();
156058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
156158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, E->getMemberLoc(), Entity);
1562c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall}
1563c373d48502ca7683ab55385f5bd624d778eb288dJohn McCall
156412d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall/// Is the given special member function accessible for the purposes of
156512d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall/// deciding whether to define a special member function as deleted?
156612d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCallbool Sema::isSpecialMemberAccessibleForDeletion(CXXMethodDecl *decl,
156712d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall                                                AccessSpecifier access,
156812d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall                                                QualType objectType) {
156912d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  // Fast path.
157012d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  if (access == AS_public || !getLangOpts().AccessControl) return true;
157112d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall
157212d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  AccessTarget entity(Context, AccessTarget::Member, decl->getParent(),
157312d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall                      DeclAccessPair::make(decl, access), objectType);
157412d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall
157512d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  // Suppress diagnostics.
157612d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  entity.setDiag(PDiag());
157712d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall
157812d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  switch (CheckAccess(*this, SourceLocation(), entity)) {
157912d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  case AR_accessible: return true;
158012d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  case AR_inaccessible: return false;
158112d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  case AR_dependent: llvm_unreachable("dependent for =delete computation");
158212d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  case AR_delayed: llvm_unreachable("cannot delay =delete computation");
158312d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  }
158412d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall  llvm_unreachable("bad access result");
158512d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall}
158612d8d80fb0f8d9cddecb34da0f37b0dc9fcaf5e6John McCall
15876b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
158858e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                               CXXDestructorDecl *Dtor,
1589b9abd87283ac6e929b7e12a577663bc99e61d020John McCall                                               const PartialDiagnostic &PDiag,
1590b9abd87283ac6e929b7e12a577663bc99e61d020John McCall                                               QualType ObjectTy) {
15914e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().AccessControl)
15926b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
15934f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall
159458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  // There's never a path involved when checking implicit destructor access.
15954f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall  AccessSpecifier Access = Dtor->getAccess();
15964f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall  if (Access == AS_public)
15976b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
15984f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall
159958e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  CXXRecordDecl *NamingClass = Dtor->getParent();
1600b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  if (ObjectTy.isNull()) ObjectTy = Context.getTypeDeclType(NamingClass);
1601b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
1602161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1603161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      DeclAccessPair::make(Dtor, Access),
1604b9abd87283ac6e929b7e12a577663bc99e61d020John McCall                      ObjectTy);
160558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(PDiag); // TODO: avoid copy
160658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
160758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, Loc, Entity);
16084f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall}
16094f9506a27cb6b865bf38beea48eadfa9dc93f510John McCall
1610b13b737a2450167c82e148590e8019b839ce6b98John McCall/// Checks access to a constructor.
16116b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
161257d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                CXXConstructorDecl *Constructor,
161357d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                const InitializedEntity &Entity,
161457d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                AccessSpecifier Access,
161557d12fd4a2bc739c4a4d62a364b7f08cd483c59eJeffrey Yasskin                                                bool IsCopyBindingRefToTemp) {
1616b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  if (!getLangOpts().AccessControl || Access == AS_public)
16176b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
1618b13b737a2450167c82e148590e8019b839ce6b98John McCall
1619b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt  PartialDiagnostic PD(PDiag());
16209a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson  switch (Entity.getKind()) {
16219a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson  default:
1622b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt    PD = PDiag(IsCopyBindingRefToTemp
1623b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt                 ? diag::ext_rvalue_to_reference_access_ctor
1624b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt                 : diag::err_access_ctor);
1625b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt
16269a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson    break;
16279a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson
16283b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson  case InitializedEntity::EK_Base:
1629b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt    PD = PDiag(diag::err_access_base_ctor);
1630b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt    PD << Entity.isInheritedVirtualBase()
1631b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt       << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor);
16329a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson    break;
16333b8c53b619c1c3d77632734d227566071459b9f5Anders Carlsson
1634b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson  case InitializedEntity::EK_Member: {
1635b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson    const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
1636b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt    PD = PDiag(diag::err_access_field_ctor);
1637b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt    PD << Field->getType() << getSpecialMember(Constructor);
1638b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson    break;
1639b99c666a940e93bcfcaeddc01515c94472e28a20Anders Carlsson  }
164058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
16414773654f2700d6fbb20612fbb6763b35860fa74dDouglas Gregor  case InitializedEntity::EK_LambdaCapture: {
16422434dcfb022778b06cfd257d830d0249680b87cfBill Wendling    StringRef VarName = Entity.getCapturedVarName();
16434773654f2700d6fbb20612fbb6763b35860fa74dDouglas Gregor    PD = PDiag(diag::err_access_lambda_capture);
16442434dcfb022778b06cfd257d830d0249680b87cfBill Wendling    PD << VarName << Entity.getType() << getSpecialMember(Constructor);
16454773654f2700d6fbb20612fbb6763b35860fa74dDouglas Gregor    break;
16464773654f2700d6fbb20612fbb6763b35860fa74dDouglas Gregor  }
16474773654f2700d6fbb20612fbb6763b35860fa74dDouglas Gregor
1648711f34adb886cce8ba86c7b1b6513a1eaaf63bb5Anders Carlsson  }
1649711f34adb886cce8ba86c7b1b6513a1eaaf63bb5Anders Carlsson
1650b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  return CheckConstructorAccess(UseLoc, Constructor, Entity, Access, PD);
1651b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt}
1652b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt
1653b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt/// Checks access to a constructor.
1654b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean HuntSema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
1655b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt                                                CXXConstructorDecl *Constructor,
1656b9abd87283ac6e929b7e12a577663bc99e61d020John McCall                                                const InitializedEntity &Entity,
1657b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt                                                AccessSpecifier Access,
1658b9abd87283ac6e929b7e12a577663bc99e61d020John McCall                                                const PartialDiagnostic &PD) {
16594e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().AccessControl ||
1660b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt      Access == AS_public)
1661b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt    return AR_accessible;
1662b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt
1663b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt  CXXRecordDecl *NamingClass = Constructor->getParent();
1664b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
1665b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  // Initializing a base sub-object is an instance method call on an
1666b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  // object of the derived class.  Otherwise, we have an instance method
1667b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  // call on an object of the constructed type.
1668b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  CXXRecordDecl *ObjectClass;
1669b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  if (Entity.getKind() == InitializedEntity::EK_Base) {
1670b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1671b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  } else {
1672b9abd87283ac6e929b7e12a577663bc99e61d020John McCall    ObjectClass = NamingClass;
1673b9abd87283ac6e929b7e12a577663bc99e61d020John McCall  }
1674b9abd87283ac6e929b7e12a577663bc99e61d020John McCall
1675b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt  AccessTarget AccessEntity(Context, AccessTarget::Member, NamingClass,
1676b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt                            DeclAccessPair::make(Constructor, Access),
1677b9abd87283ac6e929b7e12a577663bc99e61d020John McCall                            Context.getTypeDeclType(ObjectClass));
1678b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt  AccessEntity.setDiag(PD);
1679b320e0c322fb71d6235ebca9ec22940a97bdcdc7Sean Hunt
16809a68a67c6ae4982001815cc04f69b8781058263aAnders Carlsson  return CheckAccess(*this, UseLoc, AccessEntity);
1681b9abd87283ac6e929b7e12a577663bc99e61d020John McCall}
1682b13b737a2450167c82e148590e8019b839ce6b98John McCall
168390c8c57bcd84083df85f76aac2aa62acb85eb077John McCall/// Checks access to an overloaded operator new or delete.
168490c8c57bcd84083df85f76aac2aa62acb85eb077John McCallSema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
168590c8c57bcd84083df85f76aac2aa62acb85eb077John McCall                                               SourceRange PlacementRange,
168690c8c57bcd84083df85f76aac2aa62acb85eb077John McCall                                               CXXRecordDecl *NamingClass,
1687cb45a0f42964ab5fa1474b25abcc1ae3a8bd0ab8Sean Hunt                                               DeclAccessPair Found,
1688cb45a0f42964ab5fa1474b25abcc1ae3a8bd0ab8Sean Hunt                                               bool Diagnose) {
16894e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().AccessControl ||
169090c8c57bcd84083df85f76aac2aa62acb85eb077John McCall      !NamingClass ||
16919aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
169290c8c57bcd84083df85f76aac2aa62acb85eb077John McCall    return AR_accessible;
169390c8c57bcd84083df85f76aac2aa62acb85eb077John McCall
1694161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1695161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      QualType());
1696cb45a0f42964ab5fa1474b25abcc1ae3a8bd0ab8Sean Hunt  if (Diagnose)
1697cb45a0f42964ab5fa1474b25abcc1ae3a8bd0ab8Sean Hunt    Entity.setDiag(diag::err_access)
1698cb45a0f42964ab5fa1474b25abcc1ae3a8bd0ab8Sean Hunt      << PlacementRange;
169990c8c57bcd84083df85f76aac2aa62acb85eb077John McCall
170090c8c57bcd84083df85f76aac2aa62acb85eb077John McCall  return CheckAccess(*this, OpLoc, Entity);
170190c8c57bcd84083df85f76aac2aa62acb85eb077John McCall}
170290c8c57bcd84083df85f76aac2aa62acb85eb077John McCall
17034fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev/// \brief Checks access to a member.
17044fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey BataevSema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc,
17054fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev                                           CXXRecordDecl *NamingClass,
170691d3f338e446e654392184e68f940c77b5c98f39Eli Friedman                                           DeclAccessPair Found) {
17074fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev  if (!getLangOpts().AccessControl ||
17084fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev      !NamingClass ||
170991d3f338e446e654392184e68f940c77b5c98f39Eli Friedman      Found.getAccess() == AS_public)
17104fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev    return AR_accessible;
17114fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev
17124fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
171391d3f338e446e654392184e68f940c77b5c98f39Eli Friedman                      Found, QualType());
17144fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev
17154fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev  return CheckAccess(*this, UseLoc, Entity);
17164fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev}
17174fa7eab771ab8212e1058bd1a91061ff120c8fbbAlexey Bataev
1718b13b737a2450167c82e148590e8019b839ce6b98John McCall/// Checks access to an overloaded member operator, including
1719b13b737a2450167c82e148590e8019b839ce6b98John McCall/// conversion operators.
17206b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
17216b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                                   Expr *ObjectExpr,
172258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                                   Expr *ArgExpr,
17239aa472c45d2bd81b7b52c225e8acc560d716db97John McCall                                                   DeclAccessPair Found) {
17244e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().AccessControl ||
17259aa472c45d2bd81b7b52c225e8acc560d716db97John McCall      Found.getAccess() == AS_public)
17266b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
17275357b615364c17ea024c757354c58ae2a520d216John McCall
1728ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall  const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
17295357b615364c17ea024c757354c58ae2a520d216John McCall  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
17305357b615364c17ea024c757354c58ae2a520d216John McCall
1731161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1732161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      ObjectExpr->getType());
173358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  Entity.setDiag(diag::err_access)
173458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << ObjectExpr->getSourceRange()
173558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    << (ArgExpr ? ArgExpr->getSourceRange() : SourceRange());
173658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
173758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, OpLoc, Entity);
17386b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall}
17395357b615364c17ea024c757354c58ae2a520d216John McCall
17401f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall/// Checks access to the target of a friend declaration.
17411f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCallSema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
1742651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  assert(isa<CXXMethodDecl>(target->getAsFunction()));
17431f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall
17441f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  // Friendship lookup is a redeclaration lookup, so there's never an
17451f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  // inheritance path modifying access.
17461f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  AccessSpecifier access = target->getAccess();
17471f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall
17481f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  if (!getLangOpts().AccessControl || access == AS_public)
17491f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall    return AR_accessible;
17501f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall
1751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
17521f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall
17531f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  AccessTarget entity(Context, AccessTarget::Member,
17541f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall                      cast<CXXRecordDecl>(target->getDeclContext()),
17551f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall                      DeclAccessPair::make(target, access),
17561f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall                      /*no instance context*/ QualType());
17571f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  entity.setDiag(diag::err_access_friend_function)
17580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      << (method->getQualifier() ? method->getQualifierLoc().getSourceRange()
17590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines                                 : method->getNameInfo().getSourceRange());
17601f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall
17611f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  // We need to bypass delayed-diagnostics because we might be called
17621f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  // while the ParsingDeclarator is active.
17631f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  EffectiveContext EC(CurContext);
17641f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
17651f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  case AR_accessible: return Sema::AR_accessible;
17661f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  case AR_inaccessible: return Sema::AR_inaccessible;
17671f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  case AR_dependent: return Sema::AR_dependent;
17681f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  }
17691f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  llvm_unreachable("falling off end");
17701f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall}
17711f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall
17726bb8017bb9e828d118e15e59d71c66bba323c364John McCallSema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
17736bb8017bb9e828d118e15e59d71c66bba323c364John McCall                                                    DeclAccessPair Found) {
17744e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().AccessControl ||
1775e2f5ba9d80cfadbb3e1dafb9f375eb526f669b85John McCall      Found.getAccess() == AS_none ||
17766bb8017bb9e828d118e15e59d71c66bba323c364John McCall      Found.getAccess() == AS_public)
17776bb8017bb9e828d118e15e59d71c66bba323c364John McCall    return AR_accessible;
17786bb8017bb9e828d118e15e59d71c66bba323c364John McCall
17799c72c6088d591ace8503b842d39448c2040f3033John McCall  OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
1780e9ee23edd17c4bb7f271e67f8790792b4de677fcJohn McCall  CXXRecordDecl *NamingClass = Ovl->getNamingClass();
17816bb8017bb9e828d118e15e59d71c66bba323c364John McCall
1782161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1783b9abd87283ac6e929b7e12a577663bc99e61d020John McCall                      /*no instance context*/ QualType());
17846bb8017bb9e828d118e15e59d71c66bba323c364John McCall  Entity.setDiag(diag::err_access)
17856bb8017bb9e828d118e15e59d71c66bba323c364John McCall    << Ovl->getSourceRange();
17866bb8017bb9e828d118e15e59d71c66bba323c364John McCall
17876bb8017bb9e828d118e15e59d71c66bba323c364John McCall  return CheckAccess(*this, Ovl->getNameLoc(), Entity);
17886bb8017bb9e828d118e15e59d71c66bba323c364John McCall}
17896bb8017bb9e828d118e15e59d71c66bba323c364John McCall
17906b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// Checks access for a hierarchy conversion.
17916b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///
17926b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \param ForceCheck true if this check should be performed even if access
17936b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///     control is disabled;  some things rely on this for semantics
17946b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall/// \param ForceUnprivileged true if this check should proceed as if the
17956b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall///     context had no special privileges
17966b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallSema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
17976b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              QualType Base,
17986b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              QualType Derived,
17996b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              const CXXBasePath &Path,
180058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                              unsigned DiagID,
18016b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall                                              bool ForceCheck,
180258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall                                              bool ForceUnprivileged) {
18034e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!ForceCheck && !getLangOpts().AccessControl)
18046b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
18056b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
18066b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  if (Path.Access == AS_public)
18076b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    return AR_accessible;
18086b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
18096b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  CXXRecordDecl *BaseD, *DerivedD;
18106b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  BaseD = cast<CXXRecordDecl>(Base->getAs<RecordType>()->getDecl());
18116b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  DerivedD = cast<CXXRecordDecl>(Derived->getAs<RecordType>()->getDecl());
181258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall
1813161755a09898c95d21bfff33707da9ca41cd53c5John McCall  AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
1814161755a09898c95d21bfff33707da9ca41cd53c5John McCall                      Path.Access);
181558e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  if (DiagID)
181658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    Entity.setDiag(DiagID) << Derived << Base;
18176b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
1818161755a09898c95d21bfff33707da9ca41cd53c5John McCall  if (ForceUnprivileged) {
1819161755a09898c95d21bfff33707da9ca41cd53c5John McCall    switch (CheckEffectiveAccess(*this, EffectiveContext(),
1820161755a09898c95d21bfff33707da9ca41cd53c5John McCall                                 AccessLoc, Entity)) {
1821161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case ::AR_accessible: return Sema::AR_accessible;
1822161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case ::AR_inaccessible: return Sema::AR_inaccessible;
1823161755a09898c95d21bfff33707da9ca41cd53c5John McCall    case ::AR_dependent: return Sema::AR_dependent;
1824161755a09898c95d21bfff33707da9ca41cd53c5John McCall    }
1825161755a09898c95d21bfff33707da9ca41cd53c5John McCall    llvm_unreachable("unexpected result from CheckEffectiveAccess");
1826161755a09898c95d21bfff33707da9ca41cd53c5John McCall  }
182758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  return CheckAccess(*this, AccessLoc, Entity);
18285357b615364c17ea024c757354c58ae2a520d216John McCall}
18295357b615364c17ea024c757354c58ae2a520d216John McCall
183092f883177b162928a8e632e4e3b93fafd2b26072John McCall/// Checks access to all the declarations in the given result set.
18316b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCallvoid Sema::CheckLookupAccess(const LookupResult &R) {
18324e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  assert(getLangOpts().AccessControl
18336b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall         && "performing access check without access control");
18346b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  assert(R.getNamingClass() && "performing access check without naming class");
18356b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall
183658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
183758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    if (I.getAccess() != AS_public) {
1838161755a09898c95d21bfff33707da9ca41cd53c5John McCall      AccessTarget Entity(Context, AccessedEntity::Member,
1839161755a09898c95d21bfff33707da9ca41cd53c5John McCall                          R.getNamingClass(), I.getPair(),
184024dd9ad9001d1aa16223de135d7e4ed34e94b207Erik Verbruggen                          R.getBaseObjectType());
184158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall      Entity.setDiag(diag::err_access);
184258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall      CheckAccess(*this, R.getNameLoc(), Entity);
184358e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall    }
184458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall  }
184592f883177b162928a8e632e4e3b93fafd2b26072John McCall}
1846926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
1847d12059673dcef32bc2b6bae5321654d33863afe6Erik Verbruggen/// Checks access to Decl from the given class. The check will take access
1848d12059673dcef32bc2b6bae5321654d33863afe6Erik Verbruggen/// specifiers into account, but no member access expressions and such.
1849d12059673dcef32bc2b6bae5321654d33863afe6Erik Verbruggen///
1850d12059673dcef32bc2b6bae5321654d33863afe6Erik Verbruggen/// \param Decl the declaration to check if it can be accessed
18511ddbd89bb397988dd1a4e96d8d8c2c7705a2af75Dmitri Gribenko/// \param Ctx the class/context from which to start the search
1852d12059673dcef32bc2b6bae5321654d33863afe6Erik Verbruggen/// \return true if the Decl is accessible from the Class, false otherwise.
185317015eff2b3166e445377b15913474b472775e7cDouglas Gregorbool Sema::IsSimplyAccessible(NamedDecl *Decl, DeclContext *Ctx) {
185417015eff2b3166e445377b15913474b472775e7cDouglas Gregor  if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx)) {
1855a885dce496f2a9e30650f74607efe11856a76a34Douglas Gregor    if (!Decl->isCXXClassMember())
185617015eff2b3166e445377b15913474b472775e7cDouglas Gregor      return true;
1857d12059673dcef32bc2b6bae5321654d33863afe6Erik Verbruggen
185817015eff2b3166e445377b15913474b472775e7cDouglas Gregor    QualType qType = Class->getTypeForDecl()->getCanonicalTypeInternal();
185917015eff2b3166e445377b15913474b472775e7cDouglas Gregor    AccessTarget Entity(Context, AccessedEntity::Member, Class,
186017015eff2b3166e445377b15913474b472775e7cDouglas Gregor                        DeclAccessPair::make(Decl, Decl->getAccess()),
186117015eff2b3166e445377b15913474b472775e7cDouglas Gregor                        qType);
186217015eff2b3166e445377b15913474b472775e7cDouglas Gregor    if (Entity.getAccess() == AS_public)
186317015eff2b3166e445377b15913474b472775e7cDouglas Gregor      return true;
1864d12059673dcef32bc2b6bae5321654d33863afe6Erik Verbruggen
186517015eff2b3166e445377b15913474b472775e7cDouglas Gregor    EffectiveContext EC(CurContext);
186617015eff2b3166e445377b15913474b472775e7cDouglas Gregor    return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
186717015eff2b3166e445377b15913474b472775e7cDouglas Gregor  }
186817015eff2b3166e445377b15913474b472775e7cDouglas Gregor
1869f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor  if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Decl)) {
1870f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    // @public and @package ivars are always accessible.
1871f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public ||
1872f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor        Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package)
1873f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor      return true;
18745068b6f6bd166c50d045bf33901759a2417fdee4Serge Pavlov
1875f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    // If we are inside a class or category implementation, determine the
1876f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    // interface we're in.
18776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1878f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    if (ObjCMethodDecl *MD = getCurMethodDecl())
1879f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor      ClassOfMethodDecl =  MD->getClassInterface();
1880f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    else if (FunctionDecl *FD = getCurFunctionDecl()) {
1881f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor      if (ObjCImplDecl *Impl
1882f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor            = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1883f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor        if (ObjCImplementationDecl *IMPD
1884f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor              = dyn_cast<ObjCImplementationDecl>(Impl))
1885f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor          ClassOfMethodDecl = IMPD->getClassInterface();
1886f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor        else if (ObjCCategoryImplDecl* CatImplClass
1887f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor                   = dyn_cast<ObjCCategoryImplDecl>(Impl))
1888f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor          ClassOfMethodDecl = CatImplClass->getClassInterface();
1889f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor      }
1890f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    }
1891f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor
1892f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    // If we're not in an interface, this ivar is inaccessible.
1893f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    if (!ClassOfMethodDecl)
1894f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor      return false;
1895f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor
1896f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    // If we're inside the same interface that owns the ivar, we're fine.
189760ef308e51c71b760d7f598c1b763ceb7b768148Douglas Gregor    if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))
1898f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor      return true;
1899f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor
1900f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    // If the ivar is private, it's inaccessible.
1901f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private)
1902f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor      return false;
1903f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor
1904f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor    return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);
1905f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor  }
1906f3c02869a7a50ebdc963d0456fd075368b5b5a3fDouglas Gregor
190717015eff2b3166e445377b15913474b472775e7cDouglas Gregor  return true;
1908d12059673dcef32bc2b6bae5321654d33863afe6Erik Verbruggen}
1909