clang 17.0.0git
SemaAccess.cpp
Go to the documentation of this file.
1//===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file provides Sema routines for C++ access control semantics.
10//
11//===----------------------------------------------------------------------===//
12
17#include "clang/AST/DeclCXX.h"
19#include "clang/AST/DeclObjC.h"
21#include "clang/AST/ExprCXX.h"
24#include "clang/Sema/Lookup.h"
25
26using namespace clang;
27using namespace sema;
28
29/// A copy of Sema's enum without AR_delayed.
34};
35
36/// SetMemberAccessSpecifier - Set the access specifier of a member.
37/// Returns true on error (when the previous member decl access specifier
38/// is different from the new member decl access specifier).
40 NamedDecl *PrevMemberDecl,
41 AccessSpecifier LexicalAS) {
42 if (!PrevMemberDecl) {
43 // Use the lexical access specifier.
44 MemberDecl->setAccess(LexicalAS);
45 return false;
46 }
47
48 // C++ [class.access.spec]p3: When a member is redeclared its access
49 // specifier must be same as its initial declaration.
50 if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
51 Diag(MemberDecl->getLocation(),
52 diag::err_class_redeclared_with_different_access)
53 << MemberDecl << LexicalAS;
54 Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
55 << PrevMemberDecl << PrevMemberDecl->getAccess();
56
57 MemberDecl->setAccess(LexicalAS);
58 return true;
59 }
60
61 MemberDecl->setAccess(PrevMemberDecl->getAccess());
62 return false;
63}
64
66 DeclContext *DC = D->getDeclContext();
67
68 // This can only happen at top: enum decls only "publish" their
69 // immediate members.
70 if (isa<EnumDecl>(DC))
71 DC = cast<EnumDecl>(DC)->getDeclContext();
72
73 CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
74 while (DeclaringClass->isAnonymousStructOrUnion())
75 DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
76 return DeclaringClass;
77}
78
79namespace {
80struct EffectiveContext {
81 EffectiveContext() : Inner(nullptr), Dependent(false) {}
82
83 explicit EffectiveContext(DeclContext *DC)
84 : Inner(DC),
85 Dependent(DC->isDependentContext()) {
86
87 // An implicit deduction guide is semantically in the context enclosing the
88 // class template, but for access purposes behaves like the constructor
89 // from which it was produced.
90 if (auto *DGD = dyn_cast<CXXDeductionGuideDecl>(DC)) {
91 if (DGD->isImplicit()) {
92 DC = DGD->getCorrespondingConstructor();
93 if (!DC) {
94 // The copy deduction candidate doesn't have a corresponding
95 // constructor.
96 DC = cast<DeclContext>(DGD->getDeducedTemplate()->getTemplatedDecl());
97 }
98 }
99 }
100
101 // C++11 [class.access.nest]p1:
102 // A nested class is a member and as such has the same access
103 // rights as any other member.
104 // C++11 [class.access]p2:
105 // A member of a class can also access all the names to which
106 // the class has access. A local class of a member function
107 // may access the same names that the member function itself
108 // may access.
109 // This almost implies that the privileges of nesting are transitive.
110 // Technically it says nothing about the local classes of non-member
111 // functions (which can gain privileges through friendship), but we
112 // take that as an oversight.
113 while (true) {
114 // We want to add canonical declarations to the EC lists for
115 // simplicity of checking, but we need to walk up through the
116 // actual current DC chain. Otherwise, something like a local
117 // extern or friend which happens to be the canonical
118 // declaration will really mess us up.
119
120 if (isa<CXXRecordDecl>(DC)) {
121 CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
122 Records.push_back(Record->getCanonicalDecl());
123 DC = Record->getDeclContext();
124 } else if (isa<FunctionDecl>(DC)) {
125 FunctionDecl *Function = cast<FunctionDecl>(DC);
126 Functions.push_back(Function->getCanonicalDecl());
127 if (Function->getFriendObjectKind())
128 DC = Function->getLexicalDeclContext();
129 else
130 DC = Function->getDeclContext();
131 } else if (DC->isFileContext()) {
132 break;
133 } else {
134 DC = DC->getParent();
135 }
136 }
137 }
138
139 bool isDependent() const { return Dependent; }
140
141 bool includesClass(const CXXRecordDecl *R) const {
142 R = R->getCanonicalDecl();
143 return llvm::is_contained(Records, R);
144 }
145
146 /// Retrieves the innermost "useful" context. Can be null if we're
147 /// doing access-control without privileges.
148 DeclContext *getInnerContext() const {
149 return Inner;
150 }
151
153
154 DeclContext *Inner;
157 bool Dependent;
158};
159
160/// Like sema::AccessedEntity, but kindly lets us scribble all over
161/// it.
162struct AccessTarget : public AccessedEntity {
163 AccessTarget(const AccessedEntity &Entity)
164 : AccessedEntity(Entity) {
165 initialize();
166 }
167
168 AccessTarget(ASTContext &Context,
169 MemberNonce _,
170 CXXRecordDecl *NamingClass,
171 DeclAccessPair FoundDecl,
172 QualType BaseObjectType)
173 : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,
174 FoundDecl, BaseObjectType) {
175 initialize();
176 }
177
178 AccessTarget(ASTContext &Context,
179 BaseNonce _,
180 CXXRecordDecl *BaseClass,
181 CXXRecordDecl *DerivedClass,
182 AccessSpecifier Access)
183 : AccessedEntity(Context.getDiagAllocator(), Base, BaseClass, DerivedClass,
184 Access) {
185 initialize();
186 }
187
188 bool isInstanceMember() const {
189 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
190 }
191
192 bool hasInstanceContext() const {
193 return HasInstanceContext;
194 }
195
196 class SavedInstanceContext {
197 public:
198 SavedInstanceContext(SavedInstanceContext &&S)
199 : Target(S.Target), Has(S.Has) {
200 S.Target = nullptr;
201 }
202 ~SavedInstanceContext() {
203 if (Target)
204 Target->HasInstanceContext = Has;
205 }
206
207 private:
208 friend struct AccessTarget;
209 explicit SavedInstanceContext(AccessTarget &Target)
210 : Target(&Target), Has(Target.HasInstanceContext) {}
211 AccessTarget *Target;
212 bool Has;
213 };
214
215 SavedInstanceContext saveInstanceContext() {
216 return SavedInstanceContext(*this);
217 }
218
219 void suppressInstanceContext() {
220 HasInstanceContext = false;
221 }
222
223 const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
224 assert(HasInstanceContext);
225 if (CalculatedInstanceContext)
226 return InstanceContext;
227
228 CalculatedInstanceContext = true;
229 DeclContext *IC = S.computeDeclContext(getBaseObjectType());
230 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
231 : nullptr);
232 return InstanceContext;
233 }
234
235 const CXXRecordDecl *getDeclaringClass() const {
236 return DeclaringClass;
237 }
238
239 /// The "effective" naming class is the canonical non-anonymous
240 /// class containing the actual naming class.
241 const CXXRecordDecl *getEffectiveNamingClass() const {
242 const CXXRecordDecl *namingClass = getNamingClass();
243 while (namingClass->isAnonymousStructOrUnion())
244 namingClass = cast<CXXRecordDecl>(namingClass->getParent());
245 return namingClass->getCanonicalDecl();
246 }
247
248private:
249 void initialize() {
250 HasInstanceContext = (isMemberAccess() &&
251 !getBaseObjectType().isNull() &&
252 getTargetDecl()->isCXXInstanceMember());
253 CalculatedInstanceContext = false;
254 InstanceContext = nullptr;
255
256 if (isMemberAccess())
257 DeclaringClass = FindDeclaringClass(getTargetDecl());
258 else
259 DeclaringClass = getBaseClass();
260 DeclaringClass = DeclaringClass->getCanonicalDecl();
261 }
262
263 bool HasInstanceContext : 1;
264 mutable bool CalculatedInstanceContext : 1;
265 mutable const CXXRecordDecl *InstanceContext;
266 const CXXRecordDecl *DeclaringClass;
267};
268
269}
270
271/// Checks whether one class might instantiate to the other.
272static bool MightInstantiateTo(const CXXRecordDecl *From,
273 const CXXRecordDecl *To) {
274 // Declaration names are always preserved by instantiation.
275 if (From->getDeclName() != To->getDeclName())
276 return false;
277
278 const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
279 const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
280 if (FromDC == ToDC) return true;
281 if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
282
283 // Be conservative.
284 return true;
285}
286
287/// Checks whether one class is derived from another, inclusively.
288/// Properly indicates when it couldn't be determined due to
289/// dependence.
290///
291/// This should probably be donated to AST or at least Sema.
293 const CXXRecordDecl *Target) {
294 assert(Derived->getCanonicalDecl() == Derived);
295 assert(Target->getCanonicalDecl() == Target);
296
297 if (Derived == Target) return AR_accessible;
298
299 bool CheckDependent = Derived->isDependentContext();
300 if (CheckDependent && MightInstantiateTo(Derived, Target))
301 return AR_dependent;
302
303 AccessResult OnFailure = AR_inaccessible;
304 SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
305
306 while (true) {
307 if (Derived->isDependentContext() && !Derived->hasDefinition() &&
308 !Derived->isLambda())
309 return AR_dependent;
310
311 for (const auto &I : Derived->bases()) {
312 const CXXRecordDecl *RD;
313
314 QualType T = I.getType();
315 if (const RecordType *RT = T->getAs<RecordType>()) {
316 RD = cast<CXXRecordDecl>(RT->getDecl());
317 } else if (const InjectedClassNameType *IT
319 RD = IT->getDecl();
320 } else {
321 assert(T->isDependentType() && "non-dependent base wasn't a record?");
322 OnFailure = AR_dependent;
323 continue;
324 }
325
326 RD = RD->getCanonicalDecl();
327 if (RD == Target) return AR_accessible;
328 if (CheckDependent && MightInstantiateTo(RD, Target))
329 OnFailure = AR_dependent;
330
331 Queue.push_back(RD);
332 }
333
334 if (Queue.empty()) break;
335
336 Derived = Queue.pop_back_val();
337 }
338
339 return OnFailure;
340}
341
342
343static bool MightInstantiateTo(Sema &S, DeclContext *Context,
344 DeclContext *Friend) {
345 if (Friend == Context)
346 return true;
347
348 assert(!Friend->isDependentContext() &&
349 "can't handle friends with dependent contexts here");
350
351 if (!Context->isDependentContext())
352 return false;
353
354 if (Friend->isFileContext())
355 return false;
356
357 // TODO: this is very conservative
358 return true;
359}
360
361// Asks whether the type in 'context' can ever instantiate to the type
362// in 'friend'.
363static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) {
364 if (Friend == Context)
365 return true;
366
367 if (!Friend->isDependentType() && !Context->isDependentType())
368 return false;
369
370 // TODO: this is very conservative.
371 return true;
372}
373
375 FunctionDecl *Context,
376 FunctionDecl *Friend) {
377 if (Context->getDeclName() != Friend->getDeclName())
378 return false;
379
380 if (!MightInstantiateTo(S,
381 Context->getDeclContext(),
382 Friend->getDeclContext()))
383 return false;
384
386 = S.Context.getCanonicalType(Friend->getType())
389 = S.Context.getCanonicalType(Context->getType())
390 ->getAs<FunctionProtoType>();
391
392 // There isn't any way that I know of to add qualifiers
393 // during instantiation.
394 if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
395 return false;
396
397 if (FriendTy->getNumParams() != ContextTy->getNumParams())
398 return false;
399
400 if (!MightInstantiateTo(S, ContextTy->getReturnType(),
401 FriendTy->getReturnType()))
402 return false;
403
404 for (unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
405 if (!MightInstantiateTo(S, ContextTy->getParamType(I),
406 FriendTy->getParamType(I)))
407 return false;
408
409 return true;
410}
411
413 FunctionTemplateDecl *Context,
414 FunctionTemplateDecl *Friend) {
415 return MightInstantiateTo(S,
416 Context->getTemplatedDecl(),
417 Friend->getTemplatedDecl());
418}
419
421 const EffectiveContext &EC,
422 const CXXRecordDecl *Friend) {
423 if (EC.includesClass(Friend))
424 return AR_accessible;
425
426 if (EC.isDependent()) {
427 for (const CXXRecordDecl *Context : EC.Records) {
428 if (MightInstantiateTo(Context, Friend))
429 return AR_dependent;
430 }
431 }
432
433 return AR_inaccessible;
434}
435
437 const EffectiveContext &EC,
438 CanQualType Friend) {
439 if (const RecordType *RT = Friend->getAs<RecordType>())
440 return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
441
442 // TODO: we can do better than this
443 if (Friend->isDependentType())
444 return AR_dependent;
445
446 return AR_inaccessible;
447}
448
449/// Determines whether the given friend class template matches
450/// anything in the effective context.
452 const EffectiveContext &EC,
453 ClassTemplateDecl *Friend) {
454 AccessResult OnFailure = AR_inaccessible;
455
456 // Check whether the friend is the template of a class in the
457 // context chain.
459 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
460 CXXRecordDecl *Record = *I;
461
462 // Figure out whether the current class has a template:
464
465 // A specialization of the template...
466 if (isa<ClassTemplateSpecializationDecl>(Record)) {
467 CTD = cast<ClassTemplateSpecializationDecl>(Record)
468 ->getSpecializedTemplate();
469
470 // ... or the template pattern itself.
471 } else {
472 CTD = Record->getDescribedClassTemplate();
473 if (!CTD) continue;
474 }
475
476 // It's a match.
477 if (Friend == CTD->getCanonicalDecl())
478 return AR_accessible;
479
480 // If the context isn't dependent, it can't be a dependent match.
481 if (!EC.isDependent())
482 continue;
483
484 // If the template names don't match, it can't be a dependent
485 // match.
486 if (CTD->getDeclName() != Friend->getDeclName())
487 continue;
488
489 // If the class's context can't instantiate to the friend's
490 // context, it can't be a dependent match.
491 if (!MightInstantiateTo(S, CTD->getDeclContext(),
492 Friend->getDeclContext()))
493 continue;
494
495 // Otherwise, it's a dependent match.
496 OnFailure = AR_dependent;
497 }
498
499 return OnFailure;
500}
501
502/// Determines whether the given friend function matches anything in
503/// the effective context.
505 const EffectiveContext &EC,
506 FunctionDecl *Friend) {
507 AccessResult OnFailure = AR_inaccessible;
508
510 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
511 if (Friend == *I)
512 return AR_accessible;
513
514 if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
515 OnFailure = AR_dependent;
516 }
517
518 return OnFailure;
519}
520
521/// Determines whether the given friend function template matches
522/// anything in the effective context.
524 const EffectiveContext &EC,
525 FunctionTemplateDecl *Friend) {
526 if (EC.Functions.empty()) return AR_inaccessible;
527
528 AccessResult OnFailure = AR_inaccessible;
529
531 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
532
533 FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
534 if (!FTD)
535 FTD = (*I)->getDescribedFunctionTemplate();
536 if (!FTD)
537 continue;
538
539 FTD = FTD->getCanonicalDecl();
540
541 if (Friend == FTD)
542 return AR_accessible;
543
544 if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
545 OnFailure = AR_dependent;
546 }
547
548 return OnFailure;
549}
550
551/// Determines whether the given friend declaration matches anything
552/// in the effective context.
554 const EffectiveContext &EC,
555 FriendDecl *FriendD) {
556 // Whitelist accesses if there's an invalid or unsupported friend
557 // declaration.
558 if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend())
559 return AR_accessible;
560
561 if (TypeSourceInfo *T = FriendD->getFriendType())
562 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
563
564 NamedDecl *Friend
565 = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
566
567 // FIXME: declarations with dependent or templated scope.
568
569 if (isa<ClassTemplateDecl>(Friend))
570 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
571
572 if (isa<FunctionTemplateDecl>(Friend))
573 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
574
575 if (isa<CXXRecordDecl>(Friend))
576 return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
577
578 assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
579 return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
580}
581
583 const EffectiveContext &EC,
584 const CXXRecordDecl *Class) {
585 AccessResult OnFailure = AR_inaccessible;
586
587 // Okay, check friends.
588 for (auto *Friend : Class->friends()) {
589 switch (MatchesFriend(S, EC, Friend)) {
590 case AR_accessible:
591 return AR_accessible;
592
593 case AR_inaccessible:
594 continue;
595
596 case AR_dependent:
597 OnFailure = AR_dependent;
598 break;
599 }
600 }
601
602 // That's it, give up.
603 return OnFailure;
604}
605
606namespace {
607
608/// A helper class for checking for a friend which will grant access
609/// to a protected instance member.
610struct ProtectedFriendContext {
611 Sema &S;
612 const EffectiveContext &EC;
613 const CXXRecordDecl *NamingClass;
614 bool CheckDependent;
615 bool EverDependent;
616
617 /// The path down to the current base class.
619
620 ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
621 const CXXRecordDecl *InstanceContext,
622 const CXXRecordDecl *NamingClass)
623 : S(S), EC(EC), NamingClass(NamingClass),
624 CheckDependent(InstanceContext->isDependentContext() ||
625 NamingClass->isDependentContext()),
626 EverDependent(false) {}
627
628 /// Check classes in the current path for friendship, starting at
629 /// the given index.
630 bool checkFriendshipAlongPath(unsigned I) {
631 assert(I < CurPath.size());
632 for (unsigned E = CurPath.size(); I != E; ++I) {
633 switch (GetFriendKind(S, EC, CurPath[I])) {
634 case AR_accessible: return true;
635 case AR_inaccessible: continue;
636 case AR_dependent: EverDependent = true; continue;
637 }
638 }
639 return false;
640 }
641
642 /// Perform a search starting at the given class.
643 ///
644 /// PrivateDepth is the index of the last (least derived) class
645 /// along the current path such that a notional public member of
646 /// the final class in the path would have access in that class.
647 bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
648 // If we ever reach the naming class, check the current path for
649 // friendship. We can also stop recursing because we obviously
650 // won't find the naming class there again.
651 if (Cur == NamingClass)
652 return checkFriendshipAlongPath(PrivateDepth);
653
654 if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
655 EverDependent = true;
656
657 // Recurse into the base classes.
658 for (const auto &I : Cur->bases()) {
659 // If this is private inheritance, then a public member of the
660 // base will not have any access in classes derived from Cur.
661 unsigned BasePrivateDepth = PrivateDepth;
662 if (I.getAccessSpecifier() == AS_private)
663 BasePrivateDepth = CurPath.size() - 1;
664
665 const CXXRecordDecl *RD;
666
667 QualType T = I.getType();
668 if (const RecordType *RT = T->getAs<RecordType>()) {
669 RD = cast<CXXRecordDecl>(RT->getDecl());
670 } else if (const InjectedClassNameType *IT
672 RD = IT->getDecl();
673 } else {
674 assert(T->isDependentType() && "non-dependent base wasn't a record?");
675 EverDependent = true;
676 continue;
677 }
678
679 // Recurse. We don't need to clean up if this returns true.
680 CurPath.push_back(RD);
681 if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
682 return true;
683 CurPath.pop_back();
684 }
685
686 return false;
687 }
688
689 bool findFriendship(const CXXRecordDecl *Cur) {
690 assert(CurPath.empty());
691 CurPath.push_back(Cur);
692 return findFriendship(Cur, 0);
693 }
694};
695}
696
697/// Search for a class P that EC is a friend of, under the constraint
698/// InstanceContext <= P
699/// if InstanceContext exists, or else
700/// NamingClass <= P
701/// and with the additional restriction that a protected member of
702/// NamingClass would have some natural access in P, which implicitly
703/// imposes the constraint that P <= NamingClass.
704///
705/// This isn't quite the condition laid out in the standard.
706/// Instead of saying that a notional protected member of NamingClass
707/// would have to have some natural access in P, it says the actual
708/// target has to have some natural access in P, which opens up the
709/// possibility that the target (which is not necessarily a member
710/// of NamingClass) might be more accessible along some path not
711/// passing through it. That's really a bad idea, though, because it
712/// introduces two problems:
713/// - Most importantly, it breaks encapsulation because you can
714/// access a forbidden base class's members by directly subclassing
715/// it elsewhere.
716/// - It also makes access substantially harder to compute because it
717/// breaks the hill-climbing algorithm: knowing that the target is
718/// accessible in some base class would no longer let you change
719/// the question solely to whether the base class is accessible,
720/// because the original target might have been more accessible
721/// because of crazy subclassing.
722/// So we don't implement that.
723static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
724 const CXXRecordDecl *InstanceContext,
725 const CXXRecordDecl *NamingClass) {
726 assert(InstanceContext == nullptr ||
727 InstanceContext->getCanonicalDecl() == InstanceContext);
728 assert(NamingClass->getCanonicalDecl() == NamingClass);
729
730 // If we don't have an instance context, our constraints give us
731 // that NamingClass <= P <= NamingClass, i.e. P == NamingClass.
732 // This is just the usual friendship check.
733 if (!InstanceContext) return GetFriendKind(S, EC, NamingClass);
734
735 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
736 if (PRC.findFriendship(InstanceContext)) return AR_accessible;
737 if (PRC.EverDependent) return AR_dependent;
738 return AR_inaccessible;
739}
740
742 const EffectiveContext &EC,
743 const CXXRecordDecl *NamingClass,
744 AccessSpecifier Access,
745 const AccessTarget &Target) {
746 assert(NamingClass->getCanonicalDecl() == NamingClass &&
747 "declaration should be canonicalized before being passed here");
748
749 if (Access == AS_public) return AR_accessible;
750 assert(Access == AS_private || Access == AS_protected);
751
752 AccessResult OnFailure = AR_inaccessible;
753
754 for (EffectiveContext::record_iterator
755 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
756 // All the declarations in EC have been canonicalized, so pointer
757 // equality from this point on will work fine.
758 const CXXRecordDecl *ECRecord = *I;
759
760 // [B2] and [M2]
761 if (Access == AS_private) {
762 if (ECRecord == NamingClass)
763 return AR_accessible;
764
765 if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
766 OnFailure = AR_dependent;
767
768 // [B3] and [M3]
769 } else {
770 assert(Access == AS_protected);
771 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
772 case AR_accessible: break;
773 case AR_inaccessible: continue;
774 case AR_dependent: OnFailure = AR_dependent; continue;
775 }
776
777 // C++ [class.protected]p1:
778 // An additional access check beyond those described earlier in
779 // [class.access] is applied when a non-static data member or
780 // non-static member function is a protected member of its naming
781 // class. As described earlier, access to a protected member is
782 // granted because the reference occurs in a friend or member of
783 // some class C. If the access is to form a pointer to member,
784 // the nested-name-specifier shall name C or a class derived from
785 // C. All other accesses involve a (possibly implicit) object
786 // expression. In this case, the class of the object expression
787 // shall be C or a class derived from C.
788 //
789 // We interpret this as a restriction on [M3].
790
791 // In this part of the code, 'C' is just our context class ECRecord.
792
793 // These rules are different if we don't have an instance context.
794 if (!Target.hasInstanceContext()) {
795 // If it's not an instance member, these restrictions don't apply.
796 if (!Target.isInstanceMember()) return AR_accessible;
797
798 // If it's an instance member, use the pointer-to-member rule
799 // that the naming class has to be derived from the effective
800 // context.
801
802 // Emulate a MSVC bug where the creation of pointer-to-member
803 // to protected member of base class is allowed but only from
804 // static member functions.
805 if (S.getLangOpts().MSVCCompat && !EC.Functions.empty())
806 if (CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
807 if (MD->isStatic()) return AR_accessible;
808
809 // Despite the standard's confident wording, there is a case
810 // where you can have an instance member that's neither in a
811 // pointer-to-member expression nor in a member access: when
812 // it names a field in an unevaluated context that can't be an
813 // implicit member. Pending clarification, we just apply the
814 // same naming-class restriction here.
815 // FIXME: we're probably not correctly adding the
816 // protected-member restriction when we retroactively convert
817 // an expression to being evaluated.
818
819 // We know that ECRecord derives from NamingClass. The
820 // restriction says to check whether NamingClass derives from
821 // ECRecord, but that's not really necessary: two distinct
822 // classes can't be recursively derived from each other. So
823 // along this path, we just need to check whether the classes
824 // are equal.
825 if (NamingClass == ECRecord) return AR_accessible;
826
827 // Otherwise, this context class tells us nothing; on to the next.
828 continue;
829 }
830
831 assert(Target.isInstanceMember());
832
833 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
834 if (!InstanceContext) {
835 OnFailure = AR_dependent;
836 continue;
837 }
838
839 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
840 case AR_accessible: return AR_accessible;
841 case AR_inaccessible: continue;
842 case AR_dependent: OnFailure = AR_dependent; continue;
843 }
844 }
845 }
846
847 // [M3] and [B3] say that, if the target is protected in N, we grant
848 // access if the access occurs in a friend or member of some class P
849 // that's a subclass of N and where the target has some natural
850 // access in P. The 'member' aspect is easy to handle because P
851 // would necessarily be one of the effective-context records, and we
852 // address that above. The 'friend' aspect is completely ridiculous
853 // to implement because there are no restrictions at all on P
854 // *unless* the [class.protected] restriction applies. If it does,
855 // however, we should ignore whether the naming class is a friend,
856 // and instead rely on whether any potential P is a friend.
857 if (Access == AS_protected && Target.isInstanceMember()) {
858 // Compute the instance context if possible.
859 const CXXRecordDecl *InstanceContext = nullptr;
860 if (Target.hasInstanceContext()) {
861 InstanceContext = Target.resolveInstanceContext(S);
862 if (!InstanceContext) return AR_dependent;
863 }
864
865 switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
866 case AR_accessible: return AR_accessible;
867 case AR_inaccessible: return OnFailure;
868 case AR_dependent: return AR_dependent;
869 }
870 llvm_unreachable("impossible friendship kind");
871 }
872
873 switch (GetFriendKind(S, EC, NamingClass)) {
874 case AR_accessible: return AR_accessible;
875 case AR_inaccessible: return OnFailure;
876 case AR_dependent: return AR_dependent;
877 }
878
879 // Silence bogus warnings
880 llvm_unreachable("impossible friendship kind");
881}
882
883/// Finds the best path from the naming class to the declaring class,
884/// taking friend declarations into account.
885///
886/// C++0x [class.access.base]p5:
887/// A member m is accessible at the point R when named in class N if
888/// [M1] m as a member of N is public, or
889/// [M2] m as a member of N is private, and R occurs in a member or
890/// friend of class N, or
891/// [M3] m as a member of N is protected, and R occurs in a member or
892/// friend of class N, or in a member or friend of a class P
893/// derived from N, where m as a member of P is public, private,
894/// or protected, or
895/// [M4] there exists a base class B of N that is accessible at R, and
896/// m is accessible at R when named in class B.
897///
898/// C++0x [class.access.base]p4:
899/// A base class B of N is accessible at R, if
900/// [B1] an invented public member of B would be a public member of N, or
901/// [B2] R occurs in a member or friend of class N, and an invented public
902/// member of B would be a private or protected member of N, or
903/// [B3] R occurs in a member or friend of a class P derived from N, and an
904/// invented public member of B would be a private or protected member
905/// of P, or
906/// [B4] there exists a class S such that B is a base class of S accessible
907/// at R and S is a base class of N accessible at R.
908///
909/// Along a single inheritance path we can restate both of these
910/// iteratively:
911///
912/// First, we note that M1-4 are equivalent to B1-4 if the member is
913/// treated as a notional base of its declaring class with inheritance
914/// access equivalent to the member's access. Therefore we need only
915/// ask whether a class B is accessible from a class N in context R.
916///
917/// Let B_1 .. B_n be the inheritance path in question (i.e. where
918/// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
919/// B_i). For i in 1..n, we will calculate ACAB(i), the access to the
920/// closest accessible base in the path:
921/// Access(a, b) = (* access on the base specifier from a to b *)
922/// Merge(a, forbidden) = forbidden
923/// Merge(a, private) = forbidden
924/// Merge(a, b) = min(a,b)
925/// Accessible(c, forbidden) = false
926/// Accessible(c, private) = (R is c) || IsFriend(c, R)
927/// Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
928/// Accessible(c, public) = true
929/// ACAB(n) = public
930/// ACAB(i) =
931/// let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
932/// if Accessible(B_i, AccessToBase) then public else AccessToBase
933///
934/// B is an accessible base of N at R iff ACAB(1) = public.
935///
936/// \param FinalAccess the access of the "final step", or AS_public if
937/// there is no final step.
938/// \return null if friendship is dependent
940 const EffectiveContext &EC,
941 AccessTarget &Target,
942 AccessSpecifier FinalAccess,
943 CXXBasePaths &Paths) {
944 // Derive the paths to the desired base.
945 const CXXRecordDecl *Derived = Target.getNamingClass();
946 const CXXRecordDecl *Base = Target.getDeclaringClass();
947
948 // FIXME: fail correctly when there are dependent paths.
949 bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
950 Paths);
951 assert(isDerived && "derived class not actually derived from base");
952 (void) isDerived;
953
954 CXXBasePath *BestPath = nullptr;
955
956 assert(FinalAccess != AS_none && "forbidden access after declaring class");
957
958 bool AnyDependent = false;
959
960 // Derive the friend-modified access along each path.
961 for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
962 PI != PE; ++PI) {
963 AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
964
965 // Walk through the path backwards.
966 AccessSpecifier PathAccess = FinalAccess;
967 CXXBasePath::iterator I = PI->end(), E = PI->begin();
968 while (I != E) {
969 --I;
970
971 assert(PathAccess != AS_none);
972
973 // If the declaration is a private member of a base class, there
974 // is no level of friendship in derived classes that can make it
975 // accessible.
976 if (PathAccess == AS_private) {
977 PathAccess = AS_none;
978 break;
979 }
980
981 const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
982
983 AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
984 PathAccess = std::max(PathAccess, BaseAccess);
985
986 switch (HasAccess(S, EC, NC, PathAccess, Target)) {
987 case AR_inaccessible: break;
988 case AR_accessible:
989 PathAccess = AS_public;
990
991 // Future tests are not against members and so do not have
992 // instance context.
993 Target.suppressInstanceContext();
994 break;
995 case AR_dependent:
996 AnyDependent = true;
997 goto Next;
998 }
999 }
1000
1001 // Note that we modify the path's Access field to the
1002 // friend-modified access.
1003 if (BestPath == nullptr || PathAccess < BestPath->Access) {
1004 BestPath = &*PI;
1005 BestPath->Access = PathAccess;
1006
1007 // Short-circuit if we found a public path.
1008 if (BestPath->Access == AS_public)
1009 return BestPath;
1010 }
1011
1012 Next: ;
1013 }
1014
1015 assert((!BestPath || BestPath->Access != AS_public) &&
1016 "fell out of loop with public path");
1017
1018 // We didn't find a public path, but at least one path was subject
1019 // to dependent friendship, so delay the check.
1020 if (AnyDependent)
1021 return nullptr;
1022
1023 return BestPath;
1024}
1025
1026/// Given that an entity has protected natural access, check whether
1027/// access might be denied because of the protected member access
1028/// restriction.
1029///
1030/// \return true if a note was emitted
1031static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
1032 AccessTarget &Target) {
1033 // Only applies to instance accesses.
1034 if (!Target.isInstanceMember())
1035 return false;
1036
1037 assert(Target.isMemberAccess());
1038
1039 const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass();
1040
1041 for (EffectiveContext::record_iterator
1042 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1043 const CXXRecordDecl *ECRecord = *I;
1044 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
1045 case AR_accessible: break;
1046 case AR_inaccessible: continue;
1047 case AR_dependent: continue;
1048 }
1049
1050 // The effective context is a subclass of the declaring class.
1051 // Check whether the [class.protected] restriction is limiting
1052 // access.
1053
1054 // To get this exactly right, this might need to be checked more
1055 // holistically; it's not necessarily the case that gaining
1056 // access here would grant us access overall.
1057
1058 NamedDecl *D = Target.getTargetDecl();
1059
1060 // If we don't have an instance context, [class.protected] says the
1061 // naming class has to equal the context class.
1062 if (!Target.hasInstanceContext()) {
1063 // If it does, the restriction doesn't apply.
1064 if (NamingClass == ECRecord) continue;
1065
1066 // TODO: it would be great to have a fixit here, since this is
1067 // such an obvious error.
1068 S.Diag(D->getLocation(), diag::note_access_protected_restricted_noobject)
1069 << S.Context.getTypeDeclType(ECRecord);
1070 return true;
1071 }
1072
1073 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
1074 assert(InstanceContext && "diagnosing dependent access");
1075
1076 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
1077 case AR_accessible: continue;
1078 case AR_dependent: continue;
1079 case AR_inaccessible:
1080 break;
1081 }
1082
1083 // Okay, the restriction seems to be what's limiting us.
1084
1085 // Use a special diagnostic for constructors and destructors.
1086 if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
1087 (isa<FunctionTemplateDecl>(D) &&
1088 isa<CXXConstructorDecl>(
1089 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1090 return S.Diag(D->getLocation(),
1091 diag::note_access_protected_restricted_ctordtor)
1092 << isa<CXXDestructorDecl>(D->getAsFunction());
1093 }
1094
1095 // Otherwise, use the generic diagnostic.
1096 return S.Diag(D->getLocation(),
1097 diag::note_access_protected_restricted_object)
1098 << S.Context.getTypeDeclType(ECRecord);
1099 }
1100
1101 return false;
1102}
1103
1104/// We are unable to access a given declaration due to its direct
1105/// access control; diagnose that.
1107 const EffectiveContext &EC,
1108 AccessTarget &entity) {
1109 assert(entity.isMemberAccess());
1110 NamedDecl *D = entity.getTargetDecl();
1111
1112 if (D->getAccess() == AS_protected &&
1113 TryDiagnoseProtectedAccess(S, EC, entity))
1114 return;
1115
1116 // Find an original declaration.
1117 while (D->isOutOfLine()) {
1118 NamedDecl *PrevDecl = nullptr;
1119 if (VarDecl *VD = dyn_cast<VarDecl>(D))
1120 PrevDecl = VD->getPreviousDecl();
1121 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1122 PrevDecl = FD->getPreviousDecl();
1123 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
1124 PrevDecl = TND->getPreviousDecl();
1125 else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
1126 if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1127 break;
1128 PrevDecl = TD->getPreviousDecl();
1129 }
1130 if (!PrevDecl) break;
1131 D = PrevDecl;
1132 }
1133
1134 CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
1135 Decl *ImmediateChild;
1136 if (D->getDeclContext() == DeclaringClass)
1137 ImmediateChild = D;
1138 else {
1139 DeclContext *DC = D->getDeclContext();
1140 while (DC->getParent() != DeclaringClass)
1141 DC = DC->getParent();
1142 ImmediateChild = cast<Decl>(DC);
1143 }
1144
1145 // Check whether there's an AccessSpecDecl preceding this in the
1146 // chain of the DeclContext.
1147 bool isImplicit = true;
1148 for (const auto *I : DeclaringClass->decls()) {
1149 if (I == ImmediateChild) break;
1150 if (isa<AccessSpecDecl>(I)) {
1151 isImplicit = false;
1152 break;
1153 }
1154 }
1155
1156 S.Diag(D->getLocation(), diag::note_access_natural)
1157 << (unsigned) (D->getAccess() == AS_protected)
1158 << isImplicit;
1159}
1160
1161/// Diagnose the path which caused the given declaration or base class
1162/// to become inaccessible.
1164 const EffectiveContext &EC,
1165 AccessTarget &entity) {
1166 // Save the instance context to preserve invariants.
1167 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1168
1169 // This basically repeats the main algorithm but keeps some more
1170 // information.
1171
1172 // The natural access so far.
1173 AccessSpecifier accessSoFar = AS_public;
1174
1175 // Check whether we have special rights to the declaring class.
1176 if (entity.isMemberAccess()) {
1177 NamedDecl *D = entity.getTargetDecl();
1178 accessSoFar = D->getAccess();
1179 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1180
1181 switch (HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1182 // If the declaration is accessible when named in its declaring
1183 // class, then we must be constrained by the path.
1184 case AR_accessible:
1185 accessSoFar = AS_public;
1186 entity.suppressInstanceContext();
1187 break;
1188
1189 case AR_inaccessible:
1190 if (accessSoFar == AS_private ||
1191 declaringClass == entity.getEffectiveNamingClass())
1192 return diagnoseBadDirectAccess(S, EC, entity);
1193 break;
1194
1195 case AR_dependent:
1196 llvm_unreachable("cannot diagnose dependent access");
1197 }
1198 }
1199
1200 CXXBasePaths paths;
1201 CXXBasePath &path = *FindBestPath(S, EC, entity, accessSoFar, paths);
1202 assert(path.Access != AS_public);
1203
1204 CXXBasePath::iterator i = path.end(), e = path.begin();
1205 CXXBasePath::iterator constrainingBase = i;
1206 while (i != e) {
1207 --i;
1208
1209 assert(accessSoFar != AS_none && accessSoFar != AS_private);
1210
1211 // Is the entity accessible when named in the deriving class, as
1212 // modified by the base specifier?
1213 const CXXRecordDecl *derivingClass = i->Class->getCanonicalDecl();
1214 const CXXBaseSpecifier *base = i->Base;
1215
1216 // If the access to this base is worse than the access we have to
1217 // the declaration, remember it.
1218 AccessSpecifier baseAccess = base->getAccessSpecifier();
1219 if (baseAccess > accessSoFar) {
1220 constrainingBase = i;
1221 accessSoFar = baseAccess;
1222 }
1223
1224 switch (HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1225 case AR_inaccessible: break;
1226 case AR_accessible:
1227 accessSoFar = AS_public;
1228 entity.suppressInstanceContext();
1229 constrainingBase = nullptr;
1230 break;
1231 case AR_dependent:
1232 llvm_unreachable("cannot diagnose dependent access");
1233 }
1234
1235 // If this was private inheritance, but we don't have access to
1236 // the deriving class, we're done.
1237 if (accessSoFar == AS_private) {
1238 assert(baseAccess == AS_private);
1239 assert(constrainingBase == i);
1240 break;
1241 }
1242 }
1243
1244 // If we don't have a constraining base, the access failure must be
1245 // due to the original declaration.
1246 if (constrainingBase == path.end())
1247 return diagnoseBadDirectAccess(S, EC, entity);
1248
1249 // We're constrained by inheritance, but we want to say
1250 // "declared private here" if we're diagnosing a hierarchy
1251 // conversion and this is the final step.
1252 unsigned diagnostic;
1253 if (entity.isMemberAccess() ||
1254 constrainingBase + 1 != path.end()) {
1255 diagnostic = diag::note_access_constrained_by_path;
1256 } else {
1257 diagnostic = diag::note_access_natural;
1258 }
1259
1260 const CXXBaseSpecifier *base = constrainingBase->Base;
1261
1262 S.Diag(base->getSourceRange().getBegin(), diagnostic)
1263 << base->getSourceRange()
1264 << (base->getAccessSpecifier() == AS_protected)
1265 << (base->getAccessSpecifierAsWritten() == AS_none);
1266
1267 if (entity.isMemberAccess())
1268 S.Diag(entity.getTargetDecl()->getLocation(),
1269 diag::note_member_declared_at);
1270}
1271
1273 const EffectiveContext &EC,
1274 AccessTarget &Entity) {
1275 const CXXRecordDecl *NamingClass = Entity.getNamingClass();
1276 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1277 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr);
1278
1279 S.Diag(Loc, Entity.getDiag())
1280 << (Entity.getAccess() == AS_protected)
1281 << (D ? D->getDeclName() : DeclarationName())
1282 << S.Context.getTypeDeclType(NamingClass)
1283 << S.Context.getTypeDeclType(DeclaringClass);
1284 DiagnoseAccessPath(S, EC, Entity);
1285}
1286
1287/// MSVC has a bug where if during an using declaration name lookup,
1288/// the declaration found is unaccessible (private) and that declaration
1289/// was bring into scope via another using declaration whose target
1290/// declaration is accessible (public) then no error is generated.
1291/// Example:
1292/// class A {
1293/// public:
1294/// int f();
1295/// };
1296/// class B : public A {
1297/// private:
1298/// using A::f;
1299/// };
1300/// class C : public B {
1301/// private:
1302/// using B::f;
1303/// };
1304///
1305/// Here, B::f is private so this should fail in Standard C++, but
1306/// because B::f refers to A::f which is public MSVC accepts it.
1308 SourceLocation AccessLoc,
1309 AccessTarget &Entity) {
1310 if (UsingShadowDecl *Shadow =
1311 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1312 if (UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1313 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1314 if (Entity.getTargetDecl()->getAccess() == AS_private &&
1315 (OrigDecl->getAccess() == AS_public ||
1316 OrigDecl->getAccess() == AS_protected)) {
1317 S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1318 << UD->getQualifiedNameAsString()
1319 << OrigDecl->getQualifiedNameAsString();
1320 return true;
1321 }
1322 }
1323 return false;
1324}
1325
1326/// Determines whether the accessed entity is accessible. Public members
1327/// have been weeded out by this point.
1329 const EffectiveContext &EC,
1330 AccessTarget &Entity) {
1331 // Determine the actual naming class.
1332 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1333
1334 AccessSpecifier UnprivilegedAccess = Entity.getAccess();
1335 assert(UnprivilegedAccess != AS_public && "public access not weeded out");
1336
1337 // Before we try to recalculate access paths, try to white-list
1338 // accesses which just trade in on the final step, i.e. accesses
1339 // which don't require [M4] or [B4]. These are by far the most
1340 // common forms of privileged access.
1341 if (UnprivilegedAccess != AS_none) {
1342 switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1343 case AR_dependent:
1344 // This is actually an interesting policy decision. We don't
1345 // *have* to delay immediately here: we can do the full access
1346 // calculation in the hope that friendship on some intermediate
1347 // class will make the declaration accessible non-dependently.
1348 // But that's not cheap, and odds are very good (note: assertion
1349 // made without data) that the friend declaration will determine
1350 // access.
1351 return AR_dependent;
1352
1353 case AR_accessible: return AR_accessible;
1354 case AR_inaccessible: break;
1355 }
1356 }
1357
1358 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1359
1360 // We lower member accesses to base accesses by pretending that the
1361 // member is a base class of its declaring class.
1362 AccessSpecifier FinalAccess;
1363
1364 if (Entity.isMemberAccess()) {
1365 // Determine if the declaration is accessible from EC when named
1366 // in its declaring class.
1367 NamedDecl *Target = Entity.getTargetDecl();
1368 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1369
1370 FinalAccess = Target->getAccess();
1371 switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1372 case AR_accessible:
1373 // Target is accessible at EC when named in its declaring class.
1374 // We can now hill-climb and simply check whether the declaring
1375 // class is accessible as a base of the naming class. This is
1376 // equivalent to checking the access of a notional public
1377 // member with no instance context.
1378 FinalAccess = AS_public;
1379 Entity.suppressInstanceContext();
1380 break;
1381 case AR_inaccessible: break;
1382 case AR_dependent: return AR_dependent; // see above
1383 }
1384
1385 if (DeclaringClass == NamingClass)
1386 return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
1387 } else {
1388 FinalAccess = AS_public;
1389 }
1390
1391 assert(Entity.getDeclaringClass() != NamingClass);
1392
1393 // Append the declaration's access if applicable.
1394 CXXBasePaths Paths;
1395 CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
1396 if (!Path)
1397 return AR_dependent;
1398
1399 assert(Path->Access <= UnprivilegedAccess &&
1400 "access along best path worse than direct?");
1401 if (Path->Access == AS_public)
1402 return AR_accessible;
1403 return AR_inaccessible;
1404}
1405
1407 const EffectiveContext &EC,
1408 SourceLocation Loc,
1409 const AccessTarget &Entity) {
1410 assert(EC.isDependent() && "delaying non-dependent access");
1411 DeclContext *DC = EC.getInnerContext();
1412 assert(DC->isDependentContext() && "delaying non-dependent access");
1414 Loc,
1415 Entity.isMemberAccess(),
1416 Entity.getAccess(),
1417 Entity.getTargetDecl(),
1418 Entity.getNamingClass(),
1419 Entity.getBaseObjectType(),
1420 Entity.getDiag());
1421}
1422
1423/// Checks access to an entity from the given effective context.
1425 const EffectiveContext &EC,
1426 SourceLocation Loc,
1427 AccessTarget &Entity) {
1428 assert(Entity.getAccess() != AS_public && "called for public access!");
1429
1430 switch (IsAccessible(S, EC, Entity)) {
1431 case AR_dependent:
1432 DelayDependentAccess(S, EC, Loc, Entity);
1433 return AR_dependent;
1434
1435 case AR_inaccessible:
1436 if (S.getLangOpts().MSVCCompat &&
1438 return AR_accessible;
1439 if (!Entity.isQuiet())
1440 DiagnoseBadAccess(S, Loc, EC, Entity);
1441 return AR_inaccessible;
1442
1443 case AR_accessible:
1444 return AR_accessible;
1445 }
1446
1447 // silence unnecessary warning
1448 llvm_unreachable("invalid access result");
1449}
1450
1452 AccessTarget &Entity) {
1453 // If the access path is public, it's accessible everywhere.
1454 if (Entity.getAccess() == AS_public)
1455 return Sema::AR_accessible;
1456
1457 // If we're currently parsing a declaration, we may need to delay
1458 // access control checking, because our effective context might be
1459 // different based on what the declaration comes out as.
1460 //
1461 // For example, we might be parsing a declaration with a scope
1462 // specifier, like this:
1463 // A::private_type A::foo() { ... }
1464 //
1465 // Or we might be parsing something that will turn out to be a friend:
1466 // void foo(A::private_type);
1467 // void B::foo(A::private_type);
1470 return Sema::AR_delayed;
1471 }
1472
1473 EffectiveContext EC(S.CurContext);
1474 switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
1477 case AR_dependent: return Sema::AR_dependent;
1478 }
1479 llvm_unreachable("invalid access result");
1480}
1481
1483 // Access control for names used in the declarations of functions
1484 // and function templates should normally be evaluated in the context
1485 // of the declaration, just in case it's a friend of something.
1486 // However, this does not apply to local extern declarations.
1487
1488 DeclContext *DC = D->getDeclContext();
1489 if (D->isLocalExternDecl()) {
1490 DC = D->getLexicalDeclContext();
1491 } else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1492 DC = FN;
1493 } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1494 if (isa<DeclContext>(TD->getTemplatedDecl()))
1495 DC = cast<DeclContext>(TD->getTemplatedDecl());
1496 } else if (auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
1497 DC = RD;
1498 }
1499
1500 EffectiveContext EC(DC);
1501
1502 AccessTarget Target(DD.getAccessData());
1503
1504 if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
1505 DD.Triggered = true;
1506}
1507
1509 const MultiLevelTemplateArgumentList &TemplateArgs) {
1510 SourceLocation Loc = DD.getAccessLoc();
1511 AccessSpecifier Access = DD.getAccess();
1512
1513 Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
1514 TemplateArgs);
1515 if (!NamingD) return;
1516 Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
1517 TemplateArgs);
1518 if (!TargetD) return;
1519
1520 if (DD.isAccessToMember()) {
1521 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
1522 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1523 QualType BaseObjectType = DD.getAccessBaseObjectType();
1524 if (!BaseObjectType.isNull()) {
1525 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1526 DeclarationName());
1527 if (BaseObjectType.isNull()) return;
1528 }
1529
1530 AccessTarget Entity(Context,
1531 AccessTarget::Member,
1532 NamingClass,
1533 DeclAccessPair::make(TargetDecl, Access),
1534 BaseObjectType);
1535 Entity.setDiag(DD.getDiagnostic());
1536 CheckAccess(*this, Loc, Entity);
1537 } else {
1538 AccessTarget Entity(Context,
1539 AccessTarget::Base,
1540 cast<CXXRecordDecl>(TargetD),
1541 cast<CXXRecordDecl>(NamingD),
1542 Access);
1543 Entity.setDiag(DD.getDiagnostic());
1544 CheckAccess(*this, Loc, Entity);
1545 }
1546}
1547
1549 DeclAccessPair Found) {
1550 if (!getLangOpts().AccessControl ||
1551 !E->getNamingClass() ||
1552 Found.getAccess() == AS_public)
1553 return AR_accessible;
1554
1555 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1556 Found, QualType());
1557 Entity.setDiag(diag::err_access) << E->getSourceRange();
1558
1559 return CheckAccess(*this, E->getNameLoc(), Entity);
1560}
1561
1562/// Perform access-control checking on a previously-unresolved member
1563/// access which has now been resolved to a member.
1565 DeclAccessPair Found) {
1566 if (!getLangOpts().AccessControl ||
1567 Found.getAccess() == AS_public)
1568 return AR_accessible;
1569
1570 QualType BaseType = E->getBaseType();
1571 if (E->isArrow())
1572 BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1573
1574 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1575 Found, BaseType);
1576 Entity.setDiag(diag::err_access) << E->getSourceRange();
1577
1578 return CheckAccess(*this, E->getMemberLoc(), Entity);
1579}
1580
1581/// Is the given member accessible for the purposes of deciding whether to
1582/// define a special member function as deleted?
1584 DeclAccessPair Found,
1585 QualType ObjectType,
1586 SourceLocation Loc,
1587 const PartialDiagnostic &Diag) {
1588 // Fast path.
1589 if (Found.getAccess() == AS_public || !getLangOpts().AccessControl)
1590 return true;
1591
1592 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1593 ObjectType);
1594
1595 // Suppress diagnostics.
1596 Entity.setDiag(Diag);
1597
1598 switch (CheckAccess(*this, Loc, Entity)) {
1599 case AR_accessible: return true;
1600 case AR_inaccessible: return false;
1601 case AR_dependent: llvm_unreachable("dependent for =delete computation");
1602 case AR_delayed: llvm_unreachable("cannot delay =delete computation");
1603 }
1604 llvm_unreachable("bad access result");
1605}
1606
1608 CXXDestructorDecl *Dtor,
1609 const PartialDiagnostic &PDiag,
1610 QualType ObjectTy) {
1611 if (!getLangOpts().AccessControl)
1612 return AR_accessible;
1613
1614 // There's never a path involved when checking implicit destructor access.
1615 AccessSpecifier Access = Dtor->getAccess();
1616 if (Access == AS_public)
1617 return AR_accessible;
1618
1619 CXXRecordDecl *NamingClass = Dtor->getParent();
1620 if (ObjectTy.isNull()) ObjectTy = Context.getTypeDeclType(NamingClass);
1621
1622 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1623 DeclAccessPair::make(Dtor, Access),
1624 ObjectTy);
1625 Entity.setDiag(PDiag); // TODO: avoid copy
1626
1627 return CheckAccess(*this, Loc, Entity);
1628}
1629
1630/// Checks access to a constructor.
1632 CXXConstructorDecl *Constructor,
1633 DeclAccessPair Found,
1634 const InitializedEntity &Entity,
1635 bool IsCopyBindingRefToTemp) {
1636 if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1637 return AR_accessible;
1638
1640 switch (Entity.getKind()) {
1641 default:
1642 PD = PDiag(IsCopyBindingRefToTemp
1643 ? diag::ext_rvalue_to_reference_access_ctor
1644 : diag::err_access_ctor);
1645
1646 break;
1647
1649 PD = PDiag(diag::err_access_base_ctor);
1650 PD << Entity.isInheritedVirtualBase()
1651 << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor);
1652 break;
1653
1655 const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
1656 PD = PDiag(diag::err_access_field_ctor);
1657 PD << Field->getType() << getSpecialMember(Constructor);
1658 break;
1659 }
1660
1662 StringRef VarName = Entity.getCapturedVarName();
1663 PD = PDiag(diag::err_access_lambda_capture);
1664 PD << VarName << Entity.getType() << getSpecialMember(Constructor);
1665 break;
1666 }
1667
1668 }
1669
1670 return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD);
1671}
1672
1673/// Checks access to a constructor.
1675 CXXConstructorDecl *Constructor,
1676 DeclAccessPair Found,
1677 const InitializedEntity &Entity,
1678 const PartialDiagnostic &PD) {
1679 if (!getLangOpts().AccessControl ||
1680 Found.getAccess() == AS_public)
1681 return AR_accessible;
1682
1683 CXXRecordDecl *NamingClass = Constructor->getParent();
1684
1685 // Initializing a base sub-object is an instance method call on an
1686 // object of the derived class. Otherwise, we have an instance method
1687 // call on an object of the constructed type.
1688 //
1689 // FIXME: If we have a parent, we're initializing the base class subobject
1690 // in aggregate initialization. It's not clear whether the object class
1691 // should be the base class or the derived class in that case.
1692 CXXRecordDecl *ObjectClass;
1693 if ((Entity.getKind() == InitializedEntity::EK_Base ||
1695 !Entity.getParent()) {
1696 ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1697 } else if (auto *Shadow =
1698 dyn_cast<ConstructorUsingShadowDecl>(Found.getDecl())) {
1699 // If we're using an inheriting constructor to construct an object,
1700 // the object class is the derived class, not the base class.
1701 ObjectClass = Shadow->getParent();
1702 } else {
1703 ObjectClass = NamingClass;
1704 }
1705
1706 AccessTarget AccessEntity(
1707 Context, AccessTarget::Member, NamingClass,
1708 DeclAccessPair::make(Constructor, Found.getAccess()),
1709 Context.getTypeDeclType(ObjectClass));
1710 AccessEntity.setDiag(PD);
1711
1712 return CheckAccess(*this, UseLoc, AccessEntity);
1713}
1714
1715/// Checks access to an overloaded operator new or delete.
1717 SourceRange PlacementRange,
1718 CXXRecordDecl *NamingClass,
1719 DeclAccessPair Found,
1720 bool Diagnose) {
1721 if (!getLangOpts().AccessControl ||
1722 !NamingClass ||
1723 Found.getAccess() == AS_public)
1724 return AR_accessible;
1725
1726 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1727 QualType());
1728 if (Diagnose)
1729 Entity.setDiag(diag::err_access)
1730 << PlacementRange;
1731
1732 return CheckAccess(*this, OpLoc, Entity);
1733}
1734
1735/// Checks access to a member.
1737 CXXRecordDecl *NamingClass,
1738 DeclAccessPair Found) {
1739 if (!getLangOpts().AccessControl ||
1740 !NamingClass ||
1741 Found.getAccess() == AS_public)
1742 return AR_accessible;
1743
1744 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1745 Found, QualType());
1746
1747 return CheckAccess(*this, UseLoc, Entity);
1748}
1749
1750/// Checks implicit access to a member in a structured binding.
1753 CXXRecordDecl *DecomposedClass,
1754 DeclAccessPair Field) {
1755 if (!getLangOpts().AccessControl ||
1756 Field.getAccess() == AS_public)
1757 return AR_accessible;
1758
1759 AccessTarget Entity(Context, AccessTarget::Member, DecomposedClass, Field,
1760 Context.getRecordType(DecomposedClass));
1761 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1762
1763 return CheckAccess(*this, UseLoc, Entity);
1764}
1765
1767 Expr *ObjectExpr,
1768 const SourceRange &Range,
1769 DeclAccessPair Found) {
1770 if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1771 return AR_accessible;
1772
1773 const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
1774 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
1775
1776 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1777 ObjectExpr->getType());
1778 Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << Range;
1779
1780 return CheckAccess(*this, OpLoc, Entity);
1781}
1782
1783/// Checks access to an overloaded member operator, including
1784/// conversion operators.
1786 Expr *ObjectExpr,
1787 Expr *ArgExpr,
1788 DeclAccessPair Found) {
1790 OpLoc, ObjectExpr, ArgExpr ? ArgExpr->getSourceRange() : SourceRange(),
1791 Found);
1792}
1793
1795 Expr *ObjectExpr,
1796 ArrayRef<Expr *> ArgExprs,
1797 DeclAccessPair FoundDecl) {
1798 SourceRange R;
1799 if (!ArgExprs.empty()) {
1800 R = SourceRange(ArgExprs.front()->getBeginLoc(),
1801 ArgExprs.back()->getEndLoc());
1802 }
1803
1804 return CheckMemberOperatorAccess(OpLoc, ObjectExpr, R, FoundDecl);
1805}
1806
1807/// Checks access to the target of a friend declaration.
1809 assert(isa<CXXMethodDecl>(target->getAsFunction()));
1810
1811 // Friendship lookup is a redeclaration lookup, so there's never an
1812 // inheritance path modifying access.
1813 AccessSpecifier access = target->getAccess();
1814
1815 if (!getLangOpts().AccessControl || access == AS_public)
1816 return AR_accessible;
1817
1818 CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
1819
1820 AccessTarget entity(Context, AccessTarget::Member,
1821 cast<CXXRecordDecl>(target->getDeclContext()),
1822 DeclAccessPair::make(target, access),
1823 /*no instance context*/ QualType());
1824 entity.setDiag(diag::err_access_friend_function)
1825 << (method->getQualifier() ? method->getQualifierLoc().getSourceRange()
1826 : method->getNameInfo().getSourceRange());
1827
1828 // We need to bypass delayed-diagnostics because we might be called
1829 // while the ParsingDeclarator is active.
1830 EffectiveContext EC(CurContext);
1831 switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
1832 case ::AR_accessible: return Sema::AR_accessible;
1833 case ::AR_inaccessible: return Sema::AR_inaccessible;
1834 case ::AR_dependent: return Sema::AR_dependent;
1835 }
1836 llvm_unreachable("invalid access result");
1837}
1838
1840 DeclAccessPair Found) {
1841 if (!getLangOpts().AccessControl ||
1842 Found.getAccess() == AS_none ||
1843 Found.getAccess() == AS_public)
1844 return AR_accessible;
1845
1847 CXXRecordDecl *NamingClass = Ovl->getNamingClass();
1848
1849 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1850 /*no instance context*/ QualType());
1851 Entity.setDiag(diag::err_access)
1852 << Ovl->getSourceRange();
1853
1854 return CheckAccess(*this, Ovl->getNameLoc(), Entity);
1855}
1856
1857/// Checks access for a hierarchy conversion.
1858///
1859/// \param ForceCheck true if this check should be performed even if access
1860/// control is disabled; some things rely on this for semantics
1861/// \param ForceUnprivileged true if this check should proceed as if the
1862/// context had no special privileges
1864 QualType Base,
1865 QualType Derived,
1866 const CXXBasePath &Path,
1867 unsigned DiagID,
1868 bool ForceCheck,
1869 bool ForceUnprivileged) {
1870 if (!ForceCheck && !getLangOpts().AccessControl)
1871 return AR_accessible;
1872
1873 if (Path.Access == AS_public)
1874 return AR_accessible;
1875
1876 CXXRecordDecl *BaseD, *DerivedD;
1877 BaseD = cast<CXXRecordDecl>(Base->castAs<RecordType>()->getDecl());
1878 DerivedD = cast<CXXRecordDecl>(Derived->castAs<RecordType>()->getDecl());
1879
1880 AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
1881 Path.Access);
1882 if (DiagID)
1883 Entity.setDiag(DiagID) << Derived << Base;
1884
1885 if (ForceUnprivileged) {
1886 switch (CheckEffectiveAccess(*this, EffectiveContext(),
1887 AccessLoc, Entity)) {
1888 case ::AR_accessible: return Sema::AR_accessible;
1889 case ::AR_inaccessible: return Sema::AR_inaccessible;
1890 case ::AR_dependent: return Sema::AR_dependent;
1891 }
1892 llvm_unreachable("unexpected result from CheckEffectiveAccess");
1893 }
1894 return CheckAccess(*this, AccessLoc, Entity);
1895}
1896
1897/// Checks access to all the declarations in the given result set.
1899 assert(getLangOpts().AccessControl
1900 && "performing access check without access control");
1901 assert(R.getNamingClass() && "performing access check without naming class");
1902
1903 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
1904 if (I.getAccess() != AS_public) {
1905 AccessTarget Entity(Context, AccessedEntity::Member,
1906 R.getNamingClass(), I.getPair(),
1907 R.getBaseObjectType());
1908 Entity.setDiag(diag::err_access);
1909 CheckAccess(*this, R.getNameLoc(), Entity);
1910 }
1911 }
1912}
1913
1914/// Checks access to Target from the given class. The check will take access
1915/// specifiers into account, but no member access expressions and such.
1916///
1917/// \param Target the declaration to check if it can be accessed
1918/// \param NamingClass the class in which the lookup was started.
1919/// \param BaseType type of the left side of member access expression.
1920/// \p BaseType and \p NamingClass are used for C++ access control.
1921/// Depending on the lookup case, they should be set to the following:
1922/// - lhs.target (member access without a qualifier):
1923/// \p BaseType and \p NamingClass are both the type of 'lhs'.
1924/// - lhs.X::target (member access with a qualifier):
1925/// BaseType is the type of 'lhs', NamingClass is 'X'
1926/// - X::target (qualified lookup without member access):
1927/// BaseType is null, NamingClass is 'X'.
1928/// - target (unqualified lookup).
1929/// BaseType is null, NamingClass is the parent class of 'target'.
1930/// \return true if the Target is accessible from the Class, false otherwise.
1932 QualType BaseType) {
1933 // Perform the C++ accessibility checks first.
1934 if (Target->isCXXClassMember() && NamingClass) {
1935 if (!getLangOpts().CPlusPlus)
1936 return false;
1937 // The unprivileged access is AS_none as we don't know how the member was
1938 // accessed, which is described by the access in DeclAccessPair.
1939 // `IsAccessible` will examine the actual access of Target (i.e.
1940 // Decl->getAccess()) when calculating the access.
1941 AccessTarget Entity(Context, AccessedEntity::Member, NamingClass,
1942 DeclAccessPair::make(Target, AS_none), BaseType);
1943 EffectiveContext EC(CurContext);
1944 return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
1945 }
1946
1947 if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Target)) {
1948 // @public and @package ivars are always accessible.
1949 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public ||
1950 Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package)
1951 return true;
1952
1953 // If we are inside a class or category implementation, determine the
1954 // interface we're in.
1955 ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1956 if (ObjCMethodDecl *MD = getCurMethodDecl())
1957 ClassOfMethodDecl = MD->getClassInterface();
1958 else if (FunctionDecl *FD = getCurFunctionDecl()) {
1959 if (ObjCImplDecl *Impl
1960 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1961 if (ObjCImplementationDecl *IMPD
1962 = dyn_cast<ObjCImplementationDecl>(Impl))
1963 ClassOfMethodDecl = IMPD->getClassInterface();
1964 else if (ObjCCategoryImplDecl* CatImplClass
1965 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1966 ClassOfMethodDecl = CatImplClass->getClassInterface();
1967 }
1968 }
1969
1970 // If we're not in an interface, this ivar is inaccessible.
1971 if (!ClassOfMethodDecl)
1972 return false;
1973
1974 // If we're inside the same interface that owns the ivar, we're fine.
1975 if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))
1976 return true;
1977
1978 // If the ivar is private, it's inaccessible.
1979 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private)
1980 return false;
1981
1982 return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);
1983 }
1984
1985 return true;
1986}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
Defines the clang::Expr interface and subclasses for C++ expressions.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, const EffectiveContext &EC, AccessTarget &Entity)
AccessResult
A copy of Sema's enum without AR_delayed.
Definition: SemaAccess.cpp:30
@ AR_accessible
Definition: SemaAccess.cpp:31
@ AR_dependent
Definition: SemaAccess.cpp:33
@ AR_inaccessible
Definition: SemaAccess.cpp:32
static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC, AccessTarget &Target)
Given that an entity has protected natural access, check whether access might be denied because of th...
static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, const CXXRecordDecl *Target)
Checks whether one class is derived from another, inclusively.
Definition: SemaAccess.cpp:292
static void diagnoseBadDirectAccess(Sema &S, const EffectiveContext &EC, AccessTarget &entity)
We are unable to access a given declaration due to its direct access control; diagnose that.
static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, AccessTarget &Entity)
static AccessResult GetFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Class)
Definition: SemaAccess.cpp:582
static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Friend)
Definition: SemaAccess.cpp:420
static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *InstanceContext, const CXXRecordDecl *NamingClass)
Search for a class P that EC is a friend of, under the constraint InstanceContext <= P if InstanceCon...
Definition: SemaAccess.cpp:723
static bool IsMicrosoftUsingDeclarationAccessBug(Sema &S, SourceLocation AccessLoc, AccessTarget &Entity)
MSVC has a bug where if during an using declaration name lookup, the declaration found is unaccessibl...
static CXXBasePath * FindBestPath(Sema &S, const EffectiveContext &EC, AccessTarget &Target, AccessSpecifier FinalAccess, CXXBasePaths &Paths)
Finds the best path from the naming class to the declaring class, taking friend declarations into acc...
Definition: SemaAccess.cpp:939
static AccessResult IsAccessible(Sema &S, const EffectiveContext &EC, AccessTarget &Entity)
Determines whether the accessed entity is accessible.
static AccessResult HasAccess(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *NamingClass, AccessSpecifier Access, const AccessTarget &Target)
Definition: SemaAccess.cpp:741
static bool MightInstantiateTo(const CXXRecordDecl *From, const CXXRecordDecl *To)
Checks whether one class might instantiate to the other.
Definition: SemaAccess.cpp:272
static void DiagnoseAccessPath(Sema &S, const EffectiveContext &EC, AccessTarget &entity)
Diagnose the path which caused the given declaration or base class to become inaccessible.
static CXXRecordDecl * FindDeclaringClass(NamedDecl *D)
Definition: SemaAccess.cpp:65
static AccessResult CheckEffectiveAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, AccessTarget &Entity)
Checks access to an entity from the given effective context.
static void DelayDependentAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, const AccessTarget &Entity)
Defines various enumerations that describe declaration and type specifiers.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
QualType getRecordType(const RecordDecl *Decl) const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2505
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1559
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
std::list< CXXBasePath >::iterator paths_iterator
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
AccessSpecifier getAccessSpecifierAsWritten() const
Retrieves the access specifier as written in the source code (which may mean that no access specifier...
Definition: DeclCXX.h:238
QualType getType() const
Retrieves the type of the base class.
Definition: DeclCXX.h:245
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
Definition: DeclCXX.h:189
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
Definition: DeclCXX.h:226
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2474
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2738
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2018
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2133
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
base_class_range bases()
Definition: DeclCXX.h:602
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition: DeclCXX.h:1005
bool hasDefinition() const
Definition: DeclCXX.h:555
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:507
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Qualifiers getQualifiers() const
Retrieve all qualifiers.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.
Declaration of a class template.
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
NamedDecl * getDecl() const
AccessSpecifier getAccess() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1393
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1933
bool isFileContext() const
Definition: DeclBase.h:2003
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1186
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
Definition: DeclBase.cpp:1276
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2188
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
Definition: DeclBase.h:1026
virtual bool isOutOfLine() const
Determine whether this declaration is declared out of line (outside its semantic context).
Definition: Decl.cpp:100
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition: DeclBase.cpp:227
bool isInvalidDecl() const
Definition: DeclBase.h:571
bool isLocalExternDecl() const
Determine whether this is a block-scope declaration with linkage.
Definition: DeclBase.h:1134
void setAccess(AccessSpecifier AS)
Definition: DeclBase.h:486
SourceLocation getLocation() const
Definition: DeclBase.h:432
DeclContext * getDeclContext()
Definition: DeclBase.h:441
AccessSpecifier getAccess() const
Definition: DeclBase.h:491
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:883
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:943
The name of a declaration.
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Definition: Decl.h:823
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:831
A dependently-generated diagnostic.
NamedDecl * getAccessNamingClass() const
QualType getAccessBaseObjectType() const
NamedDecl * getAccessTarget() const
SourceLocation getAccessLoc() const
const PartialDiagnostic & getDiagnostic() const
static DependentDiagnostic * Create(ASTContext &Context, DeclContext *Parent, AccessNonce _, SourceLocation Loc, bool IsMemberAccess, AccessSpecifier AS, NamedDecl *TargetDecl, CXXRecordDecl *NamingClass, QualType BaseObjectType, const PartialDiagnostic &PDiag)
AccessSpecifier getAccess() const
This represents one expression.
Definition: Expr.h:110
QualType getType() const
Definition: Expr.h:142
Represents a member of a struct/union/class.
Definition: Decl.h:2941
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition: DeclFriend.h:54
bool isUnsupportedFriend() const
Determines if this friend kind is unsupported.
Definition: DeclFriend.h:172
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition: DeclFriend.h:136
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition: DeclFriend.h:121
Represents a function declaration or definition.
Definition: Decl.h:1917
DeclarationNameInfo getNameInfo() const
Definition: Decl.h:2115
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4041
Declaration of a template function.
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
Describes an entity that is being initialized.
EntityKind getKind() const
Determine the kind of initialization.
QualType getType() const
Retrieve type being initialized.
ValueDecl * getDecl() const
Retrieve the variable, parameter, or field being initialized.
Definition: SemaInit.cpp:3378
const InitializedEntity * getParent() const
Retrieve the parent of the entity being initialized, when the initialization itself is occurring with...
bool isInheritedVirtualBase() const
Return whether the base is an inherited virtual base.
@ EK_Member
The entity being initialized is a non-static data member subobject.
@ EK_Base
The entity being initialized is a base member subobject.
@ EK_Delegating
The initialization is being done by a delegating constructor.
@ EK_LambdaCapture
The entity being initialized is the field that captures a variable in a lambda.
StringRef getCapturedVarName() const
For a lambda capture, return the capture's name.
const CXXBaseSpecifier * getBaseSpecifier() const
Retrieve the base specifier.
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:5509
Represents the results of name lookup.
Definition: Lookup.h:46
SourceLocation getNameLoc() const
Gets the location of the identifier.
Definition: Lookup.h:632
CXXRecordDecl * getNamingClass() const
Returns the 'naming class' for this lookup, i.e.
Definition: Lookup.h:429
QualType getBaseObjectType() const
Returns the base object type associated with this lookup; important for [class.protected].
Definition: Lookup.h:441
iterator end() const
Definition: Lookup.h:336
iterator begin() const
Definition: Lookup.h:335
Data structure that captures multiple levels of template argument lists for use in template instantia...
Definition: Template.h:76
This represents a decl that may have a name.
Definition: Decl.h:247
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:457
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:313
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1646
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition: DeclObjC.h:2531
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2584
Represents an ObjC class declaration.
Definition: DeclObjC.h:1147
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
Definition: DeclObjC.h:1797
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1939
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:138
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
Definition: ExprCXX.h:2954
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
Definition: ExprCXX.h:3014
SourceLocation getNameLoc() const
Gets the location of the name.
Definition: ExprCXX.h:3066
CXXRecordDecl * getNamingClass()
Gets the naming class of this lookup, if any.
Definition: ExprCXX.h:4060
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2788
A (possibly-)qualified type.
Definition: Type.h:736
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:803
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
Definition: Decl.h:4072
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4835
RecordDecl * getDecl() const
Definition: Type.h:4845
bool shouldDelayDiagnostics()
Determines whether diagnostics should be delayed.
Definition: Sema.h:958
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:356
CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD)
Definition: Sema.h:3435
bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS)
SetMemberAccessSpecifier - Set the access specifier of a member.
Definition: SemaAccess.cpp:39
NamedDecl * FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext=false)
Find the instantiation of the given declaration within the current instantiation.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: Sema.cpp:1884
AccessResult CheckFriendAccess(NamedDecl *D)
Checks access to the target of a friend declaration.
AccessResult
Definition: Sema.h:7878
@ AR_dependent
Definition: Sema.h:7881
@ AR_accessible
Definition: Sema.h:7879
@ AR_inaccessible
Definition: Sema.h:7880
@ AR_delayed
Definition: Sema.h:7882
class clang::Sema::DelayedDiagnostics DelayedDiagnostics
bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, DeclAccessPair Found, QualType ObjectType, SourceLocation Loc, const PartialDiagnostic &Diag)
Is the given member accessible for the purposes of deciding whether to define a special member functi...
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
Definition: Sema.cpp:1464
ASTContext & Context
Definition: Sema.h:407
AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType=QualType())
TypeSourceInfo * SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, bool AllowDeducedTST=false)
Perform substitution on the type T with a given set of template arguments.
AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, SourceRange PlacementRange, CXXRecordDecl *NamingClass, DeclAccessPair FoundDecl, bool Diagnose=true)
Checks access to an overloaded operator new or delete.
AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, const SourceRange &, DeclAccessPair FoundDecl)
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
Definition: Sema.cpp:1469
void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs)
const LangOptions & getLangOpts() const
Definition: Sema.h:1645
AccessResult CheckStructuredBindingMemberAccess(SourceLocation UseLoc, CXXRecordDecl *DecomposedClass, DeclAccessPair Field)
Checks implicit access to a member in a structured binding.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E, DeclAccessPair FoundDecl)
Perform access-control checking on a previously-unresolved member access which has now been resolved ...
bool IsSimplyAccessible(NamedDecl *Decl, CXXRecordDecl *NamingClass, QualType BaseType)
Checks access to Target from the given class.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:419
AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, DeclAccessPair FoundDecl, const InitializedEntity &Entity, bool IsCopyBindingRefToTemp=false)
Checks access to a constructor.
AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr, DeclAccessPair FoundDecl)
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
void CheckLookupAccess(const LookupResult &R)
Checks access to all the declarations in the given result set.
AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, DeclAccessPair FoundDecl)
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:24
AccessResult CheckMemberAccess(SourceLocation UseLoc, CXXRecordDecl *NamingClass, DeclAccessPair Found)
Checks access to a member.
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:325
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3440
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:407
A container of type source information.
Definition: Type.h:6620
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7491
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2317
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7424
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3290
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition: ExprCXX.h:3151
CXXRecordDecl * getNamingClass()
Gets the 'naming class' (in the sense of C++0x [class.access.base]p5) of the lookup.
Definition: ExprCXX.h:3223
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition: ExprCXX.h:3887
QualType getBaseType() const
Definition: ExprCXX.h:3969
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition: ExprCXX.h:3979
CXXRecordDecl * getNamingClass()
Retrieve the naming class of this lookup.
Definition: ExprCXX.cpp:1597
SourceLocation getMemberLoc() const
Retrieve the location of the name of the member that this expression refers to.
Definition: ExprCXX.h:3999
The iterator over UnresolvedSets.
Definition: UnresolvedSet.h:35
Represents a C++ using-declaration.
Definition: DeclCXX.h:3449
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3257
QualType getType() const
Definition: Decl.h:712
Represents a variable declaration or definition.
Definition: Decl.h:913
A declaration being accessed, together with information about how it was accessed.
A diagnostic message which has been conditionally emitted pending the complete parsing of the current...
static DelayedDiagnostic makeAccess(SourceLocation Loc, const AccessedEntity &Entity)
@ CPlusPlus
Definition: LangStandard.h:53
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition: DeclBase.h:1244
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:111
@ AS_public
Definition: Specifiers.h:112
@ AS_protected
Definition: Specifiers.h:113
@ AS_none
Definition: Specifiers.h:115
@ AS_private
Definition: Specifiers.h:114
#define false
Definition: stdbool.h:22
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.