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