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