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