clang 22.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"
24
25using namespace clang;
26using namespace sema;
27
28/// A copy of Sema's enum without AR_delayed.
33};
34
36 NamedDecl *PrevMemberDecl,
37 AccessSpecifier LexicalAS) {
38 if (!PrevMemberDecl) {
39 // Use the lexical access specifier.
40 MemberDecl->setAccess(LexicalAS);
41 return false;
42 }
43
44 // C++ [class.access.spec]p3: When a member is redeclared its access
45 // specifier must be same as its initial declaration.
46 if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
47 Diag(MemberDecl->getLocation(),
48 diag::err_class_redeclared_with_different_access)
49 << MemberDecl << LexicalAS;
50 Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
51 << PrevMemberDecl << PrevMemberDecl->getAccess();
52
53 MemberDecl->setAccess(LexicalAS);
54 return true;
55 }
56
57 MemberDecl->setAccess(PrevMemberDecl->getAccess());
58 return false;
59}
60
63
64 // This can only happen at top: enum decls only "publish" their
65 // immediate members.
66 if (isa<EnumDecl>(DC))
67 DC = cast<EnumDecl>(DC)->getDeclContext();
68
69 CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
70 while (DeclaringClass->isAnonymousStructOrUnion())
71 DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
72 return DeclaringClass;
73}
74
75namespace {
76struct EffectiveContext {
77 EffectiveContext() : Inner(nullptr), Dependent(false) {}
78
79 explicit EffectiveContext(DeclContext *DC)
80 : Inner(DC),
81 Dependent(DC->isDependentContext()) {
82
83 // An implicit deduction guide is semantically in the context enclosing the
84 // class template, but for access purposes behaves like the constructor
85 // from which it was produced.
86 if (auto *DGD = dyn_cast<CXXDeductionGuideDecl>(DC)) {
87 if (DGD->isImplicit()) {
88 DC = DGD->getCorrespondingConstructor();
89 if (!DC) {
90 // The copy deduction candidate doesn't have a corresponding
91 // constructor.
92 DC = cast<DeclContext>(DGD->getDeducedTemplate()->getTemplatedDecl());
93 }
94 }
95 }
96
97 // C++11 [class.access.nest]p1:
98 // A nested class is a member and as such has the same access
99 // rights as any other member.
100 // C++11 [class.access]p2:
101 // A member of a class can also access all the names to which
102 // the class has access. A local class of a member function
103 // may access the same names that the member function itself
104 // may access.
105 // This almost implies that the privileges of nesting are transitive.
106 // Technically it says nothing about the local classes of non-member
107 // functions (which can gain privileges through friendship), but we
108 // take that as an oversight.
109 while (true) {
110 // We want to add canonical declarations to the EC lists for
111 // simplicity of checking, but we need to walk up through the
112 // actual current DC chain. Otherwise, something like a local
113 // extern or friend which happens to be the canonical
114 // declaration will really mess us up.
115
116 if (isa<CXXRecordDecl>(DC)) {
117 CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
118 Records.push_back(Record->getCanonicalDecl());
119 DC = Record->getDeclContext();
120 } else if (isa<FunctionDecl>(DC)) {
121 FunctionDecl *Function = cast<FunctionDecl>(DC);
122 Functions.push_back(Function->getCanonicalDecl());
123 if (Function->getFriendObjectKind())
124 DC = Function->getLexicalDeclContext();
125 else
126 DC = Function->getDeclContext();
127 } else if (DC->isFileContext()) {
128 break;
129 } else {
130 DC = DC->getParent();
131 }
132 }
133 }
134
135 bool isDependent() const { return Dependent; }
136
137 bool includesClass(const CXXRecordDecl *R) const {
138 R = R->getCanonicalDecl();
139 return llvm::is_contained(Records, R);
140 }
141
142 /// Retrieves the innermost "useful" context. Can be null if we're
143 /// doing access-control without privileges.
144 DeclContext *getInnerContext() const {
145 return Inner;
146 }
147
149
150 DeclContext *Inner;
153 bool Dependent;
154};
155
156/// Like sema::AccessedEntity, but kindly lets us scribble all over
157/// it.
158struct AccessTarget : public AccessedEntity {
159 AccessTarget(const AccessedEntity &Entity)
160 : AccessedEntity(Entity) {
161 initialize();
162 }
163
164 AccessTarget(ASTContext &Context,
165 MemberNonce _,
166 CXXRecordDecl *NamingClass,
167 DeclAccessPair FoundDecl,
168 QualType BaseObjectType)
169 : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,
170 FoundDecl, BaseObjectType) {
171 initialize();
172 }
173
174 AccessTarget(ASTContext &Context,
175 BaseNonce _,
176 CXXRecordDecl *BaseClass,
177 CXXRecordDecl *DerivedClass,
178 AccessSpecifier Access)
179 : AccessedEntity(Context.getDiagAllocator(), Base, BaseClass, DerivedClass,
180 Access) {
181 initialize();
182 }
183
184 bool isInstanceMember() const {
185 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
186 }
187
188 bool hasInstanceContext() const {
189 return HasInstanceContext;
190 }
191
192 class SavedInstanceContext {
193 public:
194 SavedInstanceContext(SavedInstanceContext &&S)
195 : Target(S.Target), Has(S.Has) {
196 S.Target = nullptr;
197 }
198
199 // The move assignment operator is defined as deleted pending further
200 // motivation.
201 SavedInstanceContext &operator=(SavedInstanceContext &&) = delete;
202
203 // The copy constrcutor and copy assignment operator is defined as deleted
204 // pending further motivation.
205 SavedInstanceContext(const SavedInstanceContext &) = delete;
206 SavedInstanceContext &operator=(const SavedInstanceContext &) = delete;
207
208 ~SavedInstanceContext() {
209 if (Target)
210 Target->HasInstanceContext = Has;
211 }
212
213 private:
214 friend struct AccessTarget;
215 explicit SavedInstanceContext(AccessTarget &Target)
216 : Target(&Target), Has(Target.HasInstanceContext) {}
217 AccessTarget *Target;
218 bool Has;
219 };
220
221 SavedInstanceContext saveInstanceContext() {
222 return SavedInstanceContext(*this);
223 }
224
225 void suppressInstanceContext() {
226 HasInstanceContext = false;
227 }
228
229 const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
230 assert(HasInstanceContext);
231 if (CalculatedInstanceContext)
232 return InstanceContext;
233
234 CalculatedInstanceContext = true;
235 DeclContext *IC = S.computeDeclContext(getBaseObjectType());
236 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
237 : nullptr);
238 return InstanceContext;
239 }
240
241 const CXXRecordDecl *getDeclaringClass() const {
242 return DeclaringClass;
243 }
244
245 /// The "effective" naming class is the canonical non-anonymous
246 /// class containing the actual naming class.
247 const CXXRecordDecl *getEffectiveNamingClass() const {
248 const CXXRecordDecl *namingClass = getNamingClass();
249 while (namingClass->isAnonymousStructOrUnion())
250 namingClass = cast<CXXRecordDecl>(namingClass->getParent());
251 return namingClass->getCanonicalDecl();
252 }
253
254private:
255 void initialize() {
256 HasInstanceContext = (isMemberAccess() &&
257 !getBaseObjectType().isNull() &&
258 getTargetDecl()->isCXXInstanceMember());
259 CalculatedInstanceContext = false;
260 InstanceContext = nullptr;
261
262 if (isMemberAccess())
263 DeclaringClass = FindDeclaringClass(getTargetDecl());
264 else
265 DeclaringClass = getBaseClass();
266 DeclaringClass = DeclaringClass->getCanonicalDecl();
267 }
268
269 bool HasInstanceContext : 1;
270 mutable bool CalculatedInstanceContext : 1;
271 mutable const CXXRecordDecl *InstanceContext;
272 const CXXRecordDecl *DeclaringClass;
273};
274
275}
276
277/// Checks whether one class might instantiate to the other.
278static bool MightInstantiateTo(const CXXRecordDecl *From,
279 const CXXRecordDecl *To) {
280 // Declaration names are always preserved by instantiation.
281 if (From->getDeclName() != To->getDeclName())
282 return false;
283
284 const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
285 const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
286 if (FromDC == ToDC) return true;
287 if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
288
289 // Be conservative.
290 return true;
291}
292
293/// Checks whether one class is derived from another, inclusively.
294/// Properly indicates when it couldn't be determined due to
295/// dependence.
296///
297/// This should probably be donated to AST or at least Sema.
299 const CXXRecordDecl *Target) {
300 assert(Derived->getCanonicalDecl() == Derived);
301 assert(Target->getCanonicalDecl() == Target);
302
303 if (Derived == Target) return AR_accessible;
304
305 bool CheckDependent = Derived->isDependentContext();
306 if (CheckDependent && MightInstantiateTo(Derived, Target))
307 return AR_dependent;
308
309 AccessResult OnFailure = AR_inaccessible;
310 SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
311
312 while (true) {
313 if (Derived->isDependentContext() && !Derived->hasDefinition() &&
314 !Derived->isLambda())
315 return AR_dependent;
316
317 for (const auto &I : Derived->bases()) {
318 const CXXRecordDecl *RD;
319
320 QualType T = I.getType();
321 if (CXXRecordDecl *Rec = T->getAsCXXRecordDecl()) {
322 RD = Rec;
323 } else {
324 assert(T->isDependentType() && "non-dependent base wasn't a record?");
325 OnFailure = AR_dependent;
326 continue;
327 }
328
329 RD = RD->getCanonicalDecl();
330 if (RD == Target) return AR_accessible;
331 if (CheckDependent && MightInstantiateTo(RD, Target))
332 OnFailure = AR_dependent;
333
334 Queue.push_back(RD);
335 }
336
337 if (Queue.empty()) break;
338
339 Derived = Queue.pop_back_val();
340 }
341
342 return OnFailure;
343}
344
345
346static bool MightInstantiateTo(Sema &S, DeclContext *Context,
348 if (Friend == Context)
349 return true;
350
351 assert(!Friend->isDependentContext() &&
352 "can't handle friends with dependent contexts here");
353
354 if (!Context->isDependentContext())
355 return false;
356
357 if (Friend->isFileContext())
358 return false;
359
360 // TODO: this is very conservative
361 return true;
362}
363
364// Asks whether the type in 'context' can ever instantiate to the type
365// in 'friend'.
367 if (Friend == Context)
368 return true;
369
370 if (!Friend->isDependentType() && !Context->isDependentType())
371 return false;
372
373 // TODO: this is very conservative.
374 return true;
375}
376
378 FunctionDecl *Context,
380 if (Context->getDeclName() != Friend->getDeclName())
381 return false;
382
383 if (!MightInstantiateTo(S,
384 Context->getDeclContext(),
385 Friend->getDeclContext()))
386 return false;
387
389 = S.Context.getCanonicalType(Friend->getType())
392 = S.Context.getCanonicalType(Context->getType())
393 ->getAs<FunctionProtoType>();
394
395 // There isn't any way that I know of to add qualifiers
396 // during instantiation.
397 if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
398 return false;
399
400 if (FriendTy->getNumParams() != ContextTy->getNumParams())
401 return false;
402
403 if (!MightInstantiateTo(S, ContextTy->getReturnType(),
404 FriendTy->getReturnType()))
405 return false;
406
407 for (unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
408 if (!MightInstantiateTo(S, ContextTy->getParamType(I),
409 FriendTy->getParamType(I)))
410 return false;
411
412 return true;
413}
414
416 FunctionTemplateDecl *Context,
418 return MightInstantiateTo(S,
419 Context->getTemplatedDecl(),
420 Friend->getTemplatedDecl());
421}
422
424 const EffectiveContext &EC,
425 const CXXRecordDecl *Friend) {
426 if (EC.includesClass(Friend))
427 return AR_accessible;
428
429 if (EC.isDependent()) {
430 for (const CXXRecordDecl *Context : EC.Records) {
431 if (MightInstantiateTo(Context, Friend))
432 return AR_dependent;
433 }
434 }
435
436 return AR_inaccessible;
437}
438
440 const EffectiveContext &EC,
442 if (const auto *RD = Friend->getAsCXXRecordDecl())
443 return MatchesFriend(S, EC, RD);
444
445 // TODO: we can do better than this
446 if (Friend->isDependentType())
447 return AR_dependent;
448
449 return AR_inaccessible;
450}
451
452/// Determines whether the given friend class template matches
453/// anything in the effective context.
455 const EffectiveContext &EC,
457 AccessResult OnFailure = AR_inaccessible;
458
459 // Check whether the friend is the template of a class in the
460 // context chain.
462 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
463 CXXRecordDecl *Record = *I;
464
465 // Figure out whether the current class has a template:
467
468 // A specialization of the template...
469 if (isa<ClassTemplateSpecializationDecl>(Record)) {
470 CTD = cast<ClassTemplateSpecializationDecl>(Record)
471 ->getSpecializedTemplate();
472
473 // ... or the template pattern itself.
474 } else {
475 CTD = Record->getDescribedClassTemplate();
476 if (!CTD) continue;
477 }
478
479 // It's a match.
480 if (Friend == CTD->getCanonicalDecl())
481 return AR_accessible;
482
483 // If the context isn't dependent, it can't be a dependent match.
484 if (!EC.isDependent())
485 continue;
486
487 // If the template names don't match, it can't be a dependent
488 // match.
489 if (CTD->getDeclName() != Friend->getDeclName())
490 continue;
491
492 // If the class's context can't instantiate to the friend's
493 // context, it can't be a dependent match.
494 if (!MightInstantiateTo(S, CTD->getDeclContext(),
495 Friend->getDeclContext()))
496 continue;
497
498 // Otherwise, it's a dependent match.
499 OnFailure = AR_dependent;
500 }
501
502 return OnFailure;
503}
504
505/// Determines whether the given friend function matches anything in
506/// the effective context.
508 const EffectiveContext &EC,
510 AccessResult OnFailure = AR_inaccessible;
511
513 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
514 if (Friend == *I)
515 return AR_accessible;
516
517 if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
518 OnFailure = AR_dependent;
519 }
520
521 return OnFailure;
522}
523
524/// Determines whether the given friend function template matches
525/// anything in the effective context.
527 const EffectiveContext &EC,
529 if (EC.Functions.empty()) return AR_inaccessible;
530
531 AccessResult OnFailure = AR_inaccessible;
532
534 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
535
536 FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
537 if (!FTD)
538 FTD = (*I)->getDescribedFunctionTemplate();
539 if (!FTD)
540 continue;
541
542 FTD = FTD->getCanonicalDecl();
543
544 if (Friend == FTD)
545 return AR_accessible;
546
547 if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
548 OnFailure = AR_dependent;
549 }
550
551 return OnFailure;
552}
553
554/// Determines whether the given friend declaration matches anything
555/// in the effective context.
557 const EffectiveContext &EC,
558 FriendDecl *FriendD) {
559 // Whitelist accesses if there's an invalid or unsupported friend
560 // declaration.
561 if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend())
562 return AR_accessible;
563
564 if (TypeSourceInfo *T = FriendD->getFriendType())
565 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
566
568 = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
569
570 // FIXME: declarations with dependent or templated scope.
571
572 if (isa<ClassTemplateDecl>(Friend))
573 return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
574
575 if (isa<FunctionTemplateDecl>(Friend))
576 return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
577
578 if (isa<CXXRecordDecl>(Friend))
579 return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
580
581 assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
582 return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
583}
584
586 const EffectiveContext &EC,
587 const CXXRecordDecl *Class) {
588 AccessResult OnFailure = AR_inaccessible;
589
590 // Okay, check friends.
591 for (auto *Friend : Class->friends()) {
592 switch (MatchesFriend(S, EC, Friend)) {
593 case AR_accessible:
594 return AR_accessible;
595
596 case AR_inaccessible:
597 continue;
598
599 case AR_dependent:
600 OnFailure = AR_dependent;
601 break;
602 }
603 }
604
605 // That's it, give up.
606 return OnFailure;
607}
608
609namespace {
610
611/// A helper class for checking for a friend which will grant access
612/// to a protected instance member.
613struct ProtectedFriendContext {
614 Sema &S;
615 const EffectiveContext &EC;
616 const CXXRecordDecl *NamingClass;
617 bool CheckDependent;
618 bool EverDependent;
619
620 /// The path down to the current base class.
622
623 ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
624 const CXXRecordDecl *InstanceContext,
625 const CXXRecordDecl *NamingClass)
626 : S(S), EC(EC), NamingClass(NamingClass),
627 CheckDependent(InstanceContext->isDependentContext() ||
628 NamingClass->isDependentContext()),
629 EverDependent(false) {}
630
631 /// Check classes in the current path for friendship, starting at
632 /// the given index.
633 bool checkFriendshipAlongPath(unsigned I) {
634 assert(I < CurPath.size());
635 for (unsigned E = CurPath.size(); I != E; ++I) {
636 switch (GetFriendKind(S, EC, CurPath[I])) {
637 case AR_accessible: return true;
638 case AR_inaccessible: continue;
639 case AR_dependent: EverDependent = true; continue;
640 }
641 }
642 return false;
643 }
644
645 /// Perform a search starting at the given class.
646 ///
647 /// PrivateDepth is the index of the last (least derived) class
648 /// along the current path such that a notional public member of
649 /// the final class in the path would have access in that class.
650 bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
651 // If we ever reach the naming class, check the current path for
652 // friendship. We can also stop recursing because we obviously
653 // won't find the naming class there again.
654 if (Cur == NamingClass)
655 return checkFriendshipAlongPath(PrivateDepth);
656
657 if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
658 EverDependent = true;
659
660 // Recurse into the base classes.
661 for (const auto &I : Cur->bases()) {
662 // If this is private inheritance, then a public member of the
663 // base will not have any access in classes derived from Cur.
664 unsigned BasePrivateDepth = PrivateDepth;
665 if (I.getAccessSpecifier() == AS_private)
666 BasePrivateDepth = CurPath.size() - 1;
667
668 const CXXRecordDecl *RD;
669
670 QualType T = I.getType();
671 if (CXXRecordDecl *Rec = T->getAsCXXRecordDecl()) {
672 RD = Rec;
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.getCanonicalTagType(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.getCanonicalTagType(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 (const auto *RD = dyn_cast<CXXRecordDecl>(TD);
1127 RD && RD->isInjectedClassName())
1128 break;
1129 PrevDecl = TD->getPreviousDecl();
1130 }
1131 if (!PrevDecl) break;
1132 D = PrevDecl;
1133 }
1134
1135 CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
1136 Decl *ImmediateChild;
1137 if (D->getDeclContext() == DeclaringClass)
1138 ImmediateChild = D;
1139 else {
1140 DeclContext *DC = D->getDeclContext();
1141 while (DC->getParent() != DeclaringClass)
1142 DC = DC->getParent();
1143 ImmediateChild = cast<Decl>(DC);
1144 }
1145
1146 // Check whether there's an AccessSpecDecl preceding this in the
1147 // chain of the DeclContext.
1148 bool isImplicit = true;
1149 for (const auto *I : DeclaringClass->decls()) {
1150 if (I == ImmediateChild) break;
1151 if (isa<AccessSpecDecl>(I)) {
1152 isImplicit = false;
1153 break;
1154 }
1155 }
1156
1157 S.Diag(D->getLocation(), diag::note_access_natural)
1158 << (unsigned) (D->getAccess() == AS_protected)
1159 << isImplicit;
1160}
1161
1162/// Diagnose the path which caused the given declaration or base class
1163/// to become inaccessible.
1165 const EffectiveContext &EC,
1166 AccessTarget &entity) {
1167 // Save the instance context to preserve invariants.
1168 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1169
1170 // This basically repeats the main algorithm but keeps some more
1171 // information.
1172
1173 // The natural access so far.
1174 AccessSpecifier accessSoFar = AS_public;
1175
1176 // Check whether we have special rights to the declaring class.
1177 if (entity.isMemberAccess()) {
1178 NamedDecl *D = entity.getTargetDecl();
1179 accessSoFar = D->getAccess();
1180 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1181
1182 switch (HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1183 // If the declaration is accessible when named in its declaring
1184 // class, then we must be constrained by the path.
1185 case AR_accessible:
1186 accessSoFar = AS_public;
1187 entity.suppressInstanceContext();
1188 break;
1189
1190 case AR_inaccessible:
1191 if (accessSoFar == AS_private ||
1192 declaringClass == entity.getEffectiveNamingClass())
1193 return diagnoseBadDirectAccess(S, EC, entity);
1194 break;
1195
1196 case AR_dependent:
1197 llvm_unreachable("cannot diagnose dependent access");
1198 }
1199 }
1200
1201 CXXBasePaths paths;
1202 CXXBasePath &path = *FindBestPath(S, EC, entity, accessSoFar, paths);
1203 assert(path.Access != AS_public);
1204
1205 CXXBasePath::iterator i = path.end(), e = path.begin();
1206 CXXBasePath::iterator constrainingBase = i;
1207 while (i != e) {
1208 --i;
1209
1210 assert(accessSoFar != AS_none && accessSoFar != AS_private);
1211
1212 // Is the entity accessible when named in the deriving class, as
1213 // modified by the base specifier?
1214 const CXXRecordDecl *derivingClass = i->Class->getCanonicalDecl();
1215 const CXXBaseSpecifier *base = i->Base;
1216
1217 // If the access to this base is worse than the access we have to
1218 // the declaration, remember it.
1219 AccessSpecifier baseAccess = base->getAccessSpecifier();
1220 if (baseAccess > accessSoFar) {
1221 constrainingBase = i;
1222 accessSoFar = baseAccess;
1223 }
1224
1225 switch (HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1226 case AR_inaccessible: break;
1227 case AR_accessible:
1228 accessSoFar = AS_public;
1229 entity.suppressInstanceContext();
1230 constrainingBase = nullptr;
1231 break;
1232 case AR_dependent:
1233 llvm_unreachable("cannot diagnose dependent access");
1234 }
1235
1236 // If this was private inheritance, but we don't have access to
1237 // the deriving class, we're done.
1238 if (accessSoFar == AS_private) {
1239 assert(baseAccess == AS_private);
1240 assert(constrainingBase == i);
1241 break;
1242 }
1243 }
1244
1245 // If we don't have a constraining base, the access failure must be
1246 // due to the original declaration.
1247 if (constrainingBase == path.end())
1248 return diagnoseBadDirectAccess(S, EC, entity);
1249
1250 // We're constrained by inheritance, but we want to say
1251 // "declared private here" if we're diagnosing a hierarchy
1252 // conversion and this is the final step.
1253 unsigned diagnostic;
1254 if (entity.isMemberAccess() ||
1255 constrainingBase + 1 != path.end()) {
1256 diagnostic = diag::note_access_constrained_by_path;
1257 } else {
1258 diagnostic = diag::note_access_natural;
1259 }
1260
1261 const CXXBaseSpecifier *base = constrainingBase->Base;
1262
1263 S.Diag(base->getSourceRange().getBegin(), diagnostic)
1264 << base->getSourceRange()
1265 << (base->getAccessSpecifier() == AS_protected)
1266 << (base->getAccessSpecifierAsWritten() == AS_none);
1267
1268 if (entity.isMemberAccess())
1269 S.Diag(entity.getTargetDecl()->getLocation(),
1270 diag::note_member_declared_at);
1271}
1272
1274 const EffectiveContext &EC,
1275 AccessTarget &Entity) {
1276 const CXXRecordDecl *NamingClass = Entity.getNamingClass();
1277 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1278 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr);
1279
1280 S.Diag(Loc, Entity.getDiag())
1281 << (Entity.getAccess() == AS_protected)
1282 << (D ? D->getDeclName() : DeclarationName())
1283 << S.Context.getCanonicalTagType(NamingClass)
1284 << S.Context.getCanonicalTagType(DeclaringClass);
1285 DiagnoseAccessPath(S, EC, Entity);
1286}
1287
1288/// MSVC has a bug where if during an using declaration name lookup,
1289/// the declaration found is unaccessible (private) and that declaration
1290/// was bring into scope via another using declaration whose target
1291/// declaration is accessible (public) then no error is generated.
1292/// Example:
1293/// class A {
1294/// public:
1295/// int f();
1296/// };
1297/// class B : public A {
1298/// private:
1299/// using A::f;
1300/// };
1301/// class C : public B {
1302/// private:
1303/// using B::f;
1304/// };
1305///
1306/// Here, B::f is private so this should fail in Standard C++, but
1307/// because B::f refers to A::f which is public MSVC accepts it.
1309 SourceLocation AccessLoc,
1310 AccessTarget &Entity) {
1311 if (UsingShadowDecl *Shadow =
1312 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1313 if (UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1314 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1315 if (Entity.getTargetDecl()->getAccess() == AS_private &&
1316 (OrigDecl->getAccess() == AS_public ||
1317 OrigDecl->getAccess() == AS_protected)) {
1318 S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1319 << UD->getQualifiedNameAsString()
1320 << OrigDecl->getQualifiedNameAsString();
1321 return true;
1322 }
1323 }
1324 return false;
1325}
1326
1327/// Determines whether the accessed entity is accessible. Public members
1328/// have been weeded out by this point.
1330 const EffectiveContext &EC,
1331 AccessTarget &Entity) {
1332 // Determine the actual naming class.
1333 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1334
1335 AccessSpecifier UnprivilegedAccess = Entity.getAccess();
1336 assert(UnprivilegedAccess != AS_public && "public access not weeded out");
1337
1338 // Before we try to recalculate access paths, try to white-list
1339 // accesses which just trade in on the final step, i.e. accesses
1340 // which don't require [M4] or [B4]. These are by far the most
1341 // common forms of privileged access.
1342 if (UnprivilegedAccess != AS_none) {
1343 switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1344 case AR_dependent:
1345 // This is actually an interesting policy decision. We don't
1346 // *have* to delay immediately here: we can do the full access
1347 // calculation in the hope that friendship on some intermediate
1348 // class will make the declaration accessible non-dependently.
1349 // But that's not cheap, and odds are very good (note: assertion
1350 // made without data) that the friend declaration will determine
1351 // access.
1352 return AR_dependent;
1353
1354 case AR_accessible: return AR_accessible;
1355 case AR_inaccessible: break;
1356 }
1357 }
1358
1359 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1360
1361 // We lower member accesses to base accesses by pretending that the
1362 // member is a base class of its declaring class.
1363 AccessSpecifier FinalAccess;
1364
1365 if (Entity.isMemberAccess()) {
1366 // Determine if the declaration is accessible from EC when named
1367 // in its declaring class.
1368 NamedDecl *Target = Entity.getTargetDecl();
1369 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1370
1371 FinalAccess = Target->getAccess();
1372 switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1373 case AR_accessible:
1374 // Target is accessible at EC when named in its declaring class.
1375 // We can now hill-climb and simply check whether the declaring
1376 // class is accessible as a base of the naming class. This is
1377 // equivalent to checking the access of a notional public
1378 // member with no instance context.
1379 FinalAccess = AS_public;
1380 Entity.suppressInstanceContext();
1381 break;
1382 case AR_inaccessible: break;
1383 case AR_dependent: return AR_dependent; // see above
1384 }
1385
1386 if (DeclaringClass == NamingClass)
1387 return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
1388 } else {
1389 FinalAccess = AS_public;
1390 }
1391
1392 assert(Entity.getDeclaringClass() != NamingClass);
1393
1394 // Append the declaration's access if applicable.
1395 CXXBasePaths Paths;
1396 CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
1397 if (!Path)
1398 return AR_dependent;
1399
1400 assert(Path->Access <= UnprivilegedAccess &&
1401 "access along best path worse than direct?");
1402 if (Path->Access == AS_public)
1403 return AR_accessible;
1404 return AR_inaccessible;
1405}
1406
1408 const EffectiveContext &EC,
1410 const AccessTarget &Entity) {
1411 assert(EC.isDependent() && "delaying non-dependent access");
1412 DeclContext *DC = EC.getInnerContext();
1413 assert(DC->isDependentContext() && "delaying non-dependent access");
1415 Loc,
1416 Entity.isMemberAccess(),
1417 Entity.getAccess(),
1418 Entity.getTargetDecl(),
1419 Entity.getNamingClass(),
1420 Entity.getBaseObjectType(),
1421 Entity.getDiag());
1422}
1423
1424/// Checks access to an entity from the given effective context.
1426 const EffectiveContext &EC,
1428 AccessTarget &Entity) {
1429 assert(Entity.getAccess() != AS_public && "called for public access!");
1430
1431 switch (IsAccessible(S, EC, Entity)) {
1432 case AR_dependent:
1433 DelayDependentAccess(S, EC, Loc, Entity);
1434 return AR_dependent;
1435
1436 case AR_inaccessible:
1437 if (S.getLangOpts().MSVCCompat &&
1439 return AR_accessible;
1440 if (!Entity.isQuiet())
1441 DiagnoseBadAccess(S, Loc, EC, Entity);
1442 return AR_inaccessible;
1443
1444 case AR_accessible:
1445 return AR_accessible;
1446 }
1447
1448 // silence unnecessary warning
1449 llvm_unreachable("invalid access result");
1450}
1451
1453 AccessTarget &Entity) {
1454 // If the access path is public, it's accessible everywhere.
1455 if (Entity.getAccess() == AS_public)
1456 return Sema::AR_accessible;
1457
1458 // If we're currently parsing a declaration, we may need to delay
1459 // access control checking, because our effective context might be
1460 // different based on what the declaration comes out as.
1461 //
1462 // For example, we might be parsing a declaration with a scope
1463 // specifier, like this:
1464 // A::private_type A::foo() { ... }
1465 //
1466 // friend declaration should not be delayed because it may lead to incorrect
1467 // redeclaration chain, such as:
1468 // class D {
1469 // class E{
1470 // class F{};
1471 // friend void foo(D::E::F& q);
1472 // };
1473 // friend void foo(D::E::F& q);
1474 // };
1476 // [class.friend]p9:
1477 // A member nominated by a friend declaration shall be accessible in the
1478 // class containing the friend declaration. The meaning of the friend
1479 // declaration is the same whether the friend declaration appears in the
1480 // private, protected, or public ([class.mem]) portion of the class
1481 // member-specification.
1482 Scope *TS = S.getCurScope();
1483 bool IsFriendDeclaration = false;
1484 while (TS && !IsFriendDeclaration) {
1485 IsFriendDeclaration = TS->isFriendScope();
1486 TS = TS->getParent();
1487 }
1488 if (!IsFriendDeclaration) {
1490 return Sema::AR_delayed;
1491 }
1492 }
1493
1494 EffectiveContext EC(S.CurContext);
1495 switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
1498 case AR_dependent: return Sema::AR_dependent;
1499 }
1500 llvm_unreachable("invalid access result");
1501}
1502
1504 // Access control for names used in the declarations of functions
1505 // and function templates should normally be evaluated in the context
1506 // of the declaration, just in case it's a friend of something.
1507 // However, this does not apply to local extern declarations.
1508
1509 DeclContext *DC = D->getDeclContext();
1510 if (D->isLocalExternDecl()) {
1511 DC = D->getLexicalDeclContext();
1512 } else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1513 DC = FN;
1514 } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1515 if (auto *D = dyn_cast_if_present<DeclContext>(TD->getTemplatedDecl()))
1516 DC = D;
1517 } else if (auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
1518 DC = RD;
1519 }
1520
1521 EffectiveContext EC(DC);
1522
1523 AccessTarget Target(DD.getAccessData());
1524
1525 if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
1526 DD.Triggered = true;
1527}
1528
1530 const MultiLevelTemplateArgumentList &TemplateArgs) {
1532 AccessSpecifier Access = DD.getAccess();
1533
1535 TemplateArgs);
1536 if (!NamingD) return;
1538 TemplateArgs);
1539 if (!TargetD) return;
1540
1541 if (DD.isAccessToMember()) {
1542 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
1543 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1544 QualType BaseObjectType = DD.getAccessBaseObjectType();
1545 if (!BaseObjectType.isNull()) {
1546 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1547 DeclarationName());
1548 if (BaseObjectType.isNull()) return;
1549 }
1550
1551 AccessTarget Entity(Context,
1552 AccessTarget::Member,
1553 NamingClass,
1554 DeclAccessPair::make(TargetDecl, Access),
1555 BaseObjectType);
1556 Entity.setDiag(DD.getDiagnostic());
1557 CheckAccess(*this, Loc, Entity);
1558 } else {
1559 AccessTarget Entity(Context,
1560 AccessTarget::Base,
1561 cast<CXXRecordDecl>(TargetD),
1562 cast<CXXRecordDecl>(NamingD),
1563 Access);
1564 Entity.setDiag(DD.getDiagnostic());
1565 CheckAccess(*this, Loc, Entity);
1566 }
1567}
1568
1571 if (!getLangOpts().AccessControl ||
1572 !E->getNamingClass() ||
1573 Found.getAccess() == AS_public)
1574 return AR_accessible;
1575
1576 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1577 Found, QualType());
1578 Entity.setDiag(diag::err_access) << E->getSourceRange();
1579
1580 return CheckAccess(*this, E->getNameLoc(), Entity);
1581}
1582
1585 if (!getLangOpts().AccessControl ||
1586 Found.getAccess() == AS_public)
1587 return AR_accessible;
1588
1589 QualType BaseType = E->getBaseType();
1590 if (E->isArrow())
1591 BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1592
1593 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1594 Found, BaseType);
1595 Entity.setDiag(diag::err_access) << E->getSourceRange();
1596
1597 return CheckAccess(*this, E->getMemberLoc(), Entity);
1598}
1599
1602 QualType ObjectType,
1604 const PartialDiagnostic &Diag) {
1605 // Fast path.
1606 if (Found.getAccess() == AS_public || !getLangOpts().AccessControl)
1607 return true;
1608
1609 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1610 ObjectType);
1611
1612 // Suppress diagnostics.
1613 Entity.setDiag(Diag);
1614
1615 switch (CheckAccess(*this, Loc, Entity)) {
1616 case AR_accessible: return true;
1617 case AR_inaccessible: return false;
1618 case AR_dependent: llvm_unreachable("dependent for =delete computation");
1619 case AR_delayed: llvm_unreachable("cannot delay =delete computation");
1620 }
1621 llvm_unreachable("bad access result");
1622}
1623
1625 CXXDestructorDecl *Dtor,
1626 const PartialDiagnostic &PDiag,
1627 QualType ObjectTy) {
1628 if (!getLangOpts().AccessControl)
1629 return AR_accessible;
1630
1631 // There's never a path involved when checking implicit destructor access.
1632 AccessSpecifier Access = Dtor->getAccess();
1633 if (Access == AS_public)
1634 return AR_accessible;
1635
1636 CXXRecordDecl *NamingClass = Dtor->getParent();
1637 if (ObjectTy.isNull())
1638 ObjectTy = Context.getCanonicalTagType(NamingClass);
1639
1640 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1641 DeclAccessPair::make(Dtor, Access),
1642 ObjectTy);
1643 Entity.setDiag(PDiag); // TODO: avoid copy
1644
1645 return CheckAccess(*this, Loc, Entity);
1646}
1647
1651 const InitializedEntity &Entity,
1652 bool IsCopyBindingRefToTemp) {
1653 if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1654 return AR_accessible;
1655
1657 switch (Entity.getKind()) {
1658 default:
1659 PD = PDiag(IsCopyBindingRefToTemp
1660 ? diag::ext_rvalue_to_reference_access_ctor
1661 : diag::err_access_ctor);
1662
1663 break;
1664
1666 PD = PDiag(diag::err_access_base_ctor);
1667 PD << Entity.isInheritedVirtualBase()
1669 break;
1670
1673 const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
1674 PD = PDiag(diag::err_access_field_ctor);
1675 PD << Field->getType() << getSpecialMember(Constructor);
1676 break;
1677 }
1678
1680 StringRef VarName = Entity.getCapturedVarName();
1681 PD = PDiag(diag::err_access_lambda_capture);
1682 PD << VarName << Entity.getType() << getSpecialMember(Constructor);
1683 break;
1684 }
1685
1686 }
1687
1688 return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD);
1689}
1690
1694 const InitializedEntity &Entity,
1695 const PartialDiagnostic &PD) {
1696 if (!getLangOpts().AccessControl ||
1697 Found.getAccess() == AS_public)
1698 return AR_accessible;
1699
1700 CXXRecordDecl *NamingClass = Constructor->getParent();
1701
1702 // Initializing a base sub-object is an instance method call on an
1703 // object of the derived class. Otherwise, we have an instance method
1704 // call on an object of the constructed type.
1705 //
1706 // FIXME: If we have a parent, we're initializing the base class subobject
1707 // in aggregate initialization. It's not clear whether the object class
1708 // should be the base class or the derived class in that case.
1709 CXXRecordDecl *ObjectClass;
1710 if ((Entity.getKind() == InitializedEntity::EK_Base ||
1712 !Entity.getParent()) {
1713 ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1714 } else if (auto *Shadow =
1715 dyn_cast<ConstructorUsingShadowDecl>(Found.getDecl())) {
1716 // If we're using an inheriting constructor to construct an object,
1717 // the object class is the derived class, not the base class.
1718 ObjectClass = Shadow->getParent();
1719 } else {
1720 ObjectClass = NamingClass;
1721 }
1722
1723 AccessTarget AccessEntity(
1724 Context, AccessTarget::Member, NamingClass,
1726 Context.getCanonicalTagType(ObjectClass));
1727 AccessEntity.setDiag(PD);
1728
1729 return CheckAccess(*this, UseLoc, AccessEntity);
1730}
1731
1733 SourceRange PlacementRange,
1734 CXXRecordDecl *NamingClass,
1736 bool Diagnose) {
1737 if (!getLangOpts().AccessControl ||
1738 !NamingClass ||
1739 Found.getAccess() == AS_public)
1740 return AR_accessible;
1741
1742 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1743 QualType());
1744 if (Diagnose)
1745 Entity.setDiag(diag::err_access)
1746 << PlacementRange;
1747
1748 return CheckAccess(*this, OpLoc, Entity);
1749}
1750
1752 CXXRecordDecl *NamingClass,
1754 if (!getLangOpts().AccessControl ||
1755 !NamingClass ||
1756 Found.getAccess() == AS_public)
1757 return AR_accessible;
1758
1759 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1760 Found, QualType());
1761
1762 return CheckAccess(*this, UseLoc, Entity);
1763}
1764
1767 CXXRecordDecl *DecomposedClass,
1768 DeclAccessPair Field) {
1769 if (!getLangOpts().AccessControl ||
1770 Field.getAccess() == AS_public)
1771 return AR_accessible;
1772
1773 AccessTarget Entity(Context, AccessTarget::Member, DecomposedClass, Field,
1774 Context.getCanonicalTagType(DecomposedClass));
1775 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1776
1777 return CheckAccess(*this, UseLoc, Entity);
1778}
1779
1781 Expr *ObjectExpr,
1782 const SourceRange &Range,
1784 if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1785 return AR_accessible;
1786
1787 auto *NamingClass = ObjectExpr->getType()->castAsCXXRecordDecl();
1788 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1789 ObjectExpr->getType());
1790 Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << Range;
1791
1792 return CheckAccess(*this, OpLoc, Entity);
1793}
1794
1796 Expr *ObjectExpr,
1797 Expr *ArgExpr,
1800 OpLoc, ObjectExpr, ArgExpr ? ArgExpr->getSourceRange() : SourceRange(),
1801 Found);
1802}
1803
1805 Expr *ObjectExpr,
1806 ArrayRef<Expr *> ArgExprs,
1807 DeclAccessPair FoundDecl) {
1808 SourceRange R;
1809 if (!ArgExprs.empty()) {
1810 R = SourceRange(ArgExprs.front()->getBeginLoc(),
1811 ArgExprs.back()->getEndLoc());
1812 }
1813
1814 return CheckMemberOperatorAccess(OpLoc, ObjectExpr, R, FoundDecl);
1815}
1816
1818 assert(isa<CXXMethodDecl>(target->getAsFunction()));
1819
1820 // Friendship lookup is a redeclaration lookup, so there's never an
1821 // inheritance path modifying access.
1822 AccessSpecifier access = target->getAccess();
1823
1824 if (!getLangOpts().AccessControl || access == AS_public)
1825 return AR_accessible;
1826
1827 CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
1828
1829 AccessTarget entity(Context, AccessTarget::Member,
1830 cast<CXXRecordDecl>(target->getDeclContext()),
1831 DeclAccessPair::make(target, access),
1832 /*no instance context*/ QualType());
1833 entity.setDiag(diag::err_access_friend_function)
1834 << (method->getQualifier() ? method->getQualifierLoc().getSourceRange()
1835 : method->getNameInfo().getSourceRange());
1836
1837 // We need to bypass delayed-diagnostics because we might be called
1838 // while the ParsingDeclarator is active.
1839 EffectiveContext EC(CurContext);
1840 switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
1841 case ::AR_accessible: return Sema::AR_accessible;
1842 case ::AR_inaccessible: return Sema::AR_inaccessible;
1843 case ::AR_dependent: return Sema::AR_dependent;
1844 }
1845 llvm_unreachable("invalid access result");
1846}
1847
1850 if (!getLangOpts().AccessControl ||
1851 Found.getAccess() == AS_none ||
1852 Found.getAccess() == AS_public)
1853 return AR_accessible;
1854
1856 CXXRecordDecl *NamingClass = Ovl->getNamingClass();
1857
1858 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1859 /*no instance context*/ QualType());
1860 Entity.setDiag(diag::err_access)
1861 << Ovl->getSourceRange();
1862
1863 return CheckAccess(*this, Ovl->getNameLoc(), Entity);
1864}
1865
1867 SourceLocation AccessLoc, CXXRecordDecl *Base, CXXRecordDecl *Derived,
1868 const CXXBasePath &Path, unsigned DiagID,
1869 llvm::function_ref<void(PartialDiagnostic &)> SetupPDiag, bool ForceCheck,
1870 bool ForceUnprivileged) {
1871 if (!ForceCheck && !getLangOpts().AccessControl)
1872 return AR_accessible;
1873
1874 if (Path.Access == AS_public)
1875 return AR_accessible;
1876
1877 AccessTarget Entity(Context, AccessTarget::Base, Base, Derived, Path.Access);
1878 if (DiagID)
1879 SetupPDiag(Entity.setDiag(DiagID));
1880
1881 if (ForceUnprivileged) {
1882 switch (
1883 CheckEffectiveAccess(*this, EffectiveContext(), AccessLoc, Entity)) {
1884 case ::AR_accessible:
1885 return Sema::AR_accessible;
1886 case ::AR_inaccessible:
1887 return Sema::AR_inaccessible;
1888 case ::AR_dependent:
1889 return Sema::AR_dependent;
1890 }
1891 llvm_unreachable("unexpected result from CheckEffectiveAccess");
1892 }
1893 return CheckAccess(*this, AccessLoc, Entity);
1894}
1895
1897 QualType Base, QualType Derived,
1898 const CXXBasePath &Path,
1899 unsigned DiagID, bool ForceCheck,
1900 bool ForceUnprivileged) {
1901 return CheckBaseClassAccess(
1902 AccessLoc, Base->getAsCXXRecordDecl(), Derived->getAsCXXRecordDecl(),
1903 Path, DiagID, [&](PartialDiagnostic &PD) { PD << Derived << Base; },
1904 ForceCheck, ForceUnprivileged);
1905}
1906
1908 assert(getLangOpts().AccessControl
1909 && "performing access check without access control");
1910 assert(R.getNamingClass() && "performing access check without naming class");
1911
1912 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
1913 if (I.getAccess() != AS_public) {
1914 AccessTarget Entity(Context, AccessedEntity::Member,
1915 R.getNamingClass(), I.getPair(),
1916 R.getBaseObjectType());
1917 Entity.setDiag(diag::err_access);
1918 CheckAccess(*this, R.getNameLoc(), Entity);
1919 }
1920 }
1921}
1922
1924 QualType BaseType) {
1925 // Perform the C++ accessibility checks first.
1926 if (Target->isCXXClassMember() && NamingClass) {
1927 if (!getLangOpts().CPlusPlus)
1928 return false;
1929 // The unprivileged access is AS_none as we don't know how the member was
1930 // accessed, which is described by the access in DeclAccessPair.
1931 // `IsAccessible` will examine the actual access of Target (i.e.
1932 // Decl->getAccess()) when calculating the access.
1933 AccessTarget Entity(Context, AccessedEntity::Member, NamingClass,
1934 DeclAccessPair::make(Target, AS_none), BaseType);
1935 EffectiveContext EC(CurContext);
1936 return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
1937 }
1938
1939 if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Target)) {
1940 // @public and @package ivars are always accessible.
1941 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public ||
1942 Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package)
1943 return true;
1944
1945 // If we are inside a class or category implementation, determine the
1946 // interface we're in.
1947 ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1948 if (ObjCMethodDecl *MD = getCurMethodDecl())
1949 ClassOfMethodDecl = MD->getClassInterface();
1950 else if (FunctionDecl *FD = getCurFunctionDecl()) {
1951 if (ObjCImplDecl *Impl
1952 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1953 if (ObjCImplementationDecl *IMPD
1954 = dyn_cast<ObjCImplementationDecl>(Impl))
1955 ClassOfMethodDecl = IMPD->getClassInterface();
1956 else if (ObjCCategoryImplDecl* CatImplClass
1957 = dyn_cast<ObjCCategoryImplDecl>(Impl))
1958 ClassOfMethodDecl = CatImplClass->getClassInterface();
1959 }
1960 }
1961
1962 // If we're not in an interface, this ivar is inaccessible.
1963 if (!ClassOfMethodDecl)
1964 return false;
1965
1966 // If we're inside the same interface that owns the ivar, we're fine.
1967 if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))
1968 return true;
1969
1970 // If the ivar is private, it's inaccessible.
1971 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private)
1972 return false;
1973
1974 return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);
1975 }
1976
1977 return true;
1978}
Defines the clang::ASTContext interface.
const Decl * D
IndirectLocalPath & Path
Expr * E
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:29
@ AR_accessible
Definition: SemaAccess.cpp:30
@ AR_dependent
Definition: SemaAccess.cpp:32
@ AR_inaccessible
Definition: SemaAccess.cpp:31
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:298
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:585
static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Friend)
Definition: SemaAccess.cpp:423
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:278
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:61
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:753
SourceLocation Loc
Definition: SemaObjC.cpp:754
Defines various enumerations that describe declaration and type specifiers.
static 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:188
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2851
CanQualType getCanonicalTagType(const TagDecl *TD) const
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:2604
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2869
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2129
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2255
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
base_class_range bases()
Definition: DeclCXX.h:608
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition: DeclCXX.h:1018
bool hasDefinition() const
Definition: DeclCXX.h:561
bool isInjectedClassName() const
Determines whether this declaration represents the injected class name.
Definition: DeclCXX.cpp:2146
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:522
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)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1449
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2109
bool isFileContext() const
Definition: DeclBase.h:2180
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1358
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
Definition: DeclBase.cpp:1459
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2373
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:1061
virtual bool isOutOfLine() const
Determine whether this declaration is declared out of line (outside its semantic context).
Definition: Decl.cpp:99
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition: DeclBase.cpp:251
bool isInvalidDecl() const
Definition: DeclBase.h:588
bool isLocalExternDecl() const
Determine whether this is a block-scope declaration with linkage.
Definition: DeclBase.h:1169
void setAccess(AccessSpecifier AS)
Definition: DeclBase.h:502
SourceLocation getLocation() const
Definition: DeclBase.h:439
DeclContext * getDeclContext()
Definition: DeclBase.h:448
AccessSpecifier getAccess() const
Definition: DeclBase.h:507
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:918
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:978
The name of a declaration.
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:844
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
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:112
QualType getType() const
Definition: Expr.h:144
Represents a member of a struct/union/class.
Definition: Decl.h:3157
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:183
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition: DeclFriend.h:139
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition: DeclFriend.h:125
Represents a function declaration or definition.
Definition: Decl.h:1999
DeclarationNameInfo getNameInfo() const
Definition: Decl.h:2210
Represents a prototype with parameter type info, e.g.
Definition: TypeBase.h:5282
Declaration of a template function.
Definition: DeclTemplate.h:952
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:3701
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.
Represents the results of name lookup.
Definition: Lookup.h:147
SourceLocation getNameLoc() const
Gets the location of the identifier.
Definition: Lookup.h:666
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:273
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:486
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:339
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1680
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:2545
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2597
Represents an ObjC class declaration.
Definition: DeclObjC.h:1154
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:1810
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1952
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:3122
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
Definition: ExprCXX.h:3183
SourceLocation getNameLoc() const
Gets the location of the name.
Definition: ExprCXX.h:3235
CXXRecordDecl * getNamingClass()
Gets the naming class of this lookup, if any.
Definition: ExprCXX.h:4293
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: TypeBase.h:3346
A (possibly-)qualified type.
Definition: TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: TypeBase.h:1004
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
Definition: Decl.h:4361
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:631
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition: Scope.h:287
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:61
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaBase.cpp:33
bool shouldDelayDiagnostics()
Determines whether diagnostics should be delayed.
Definition: Sema.h:1364
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:850
Scope * getCurScope() const
Retrieve the parser's current scope.
Definition: Sema.h:1113
CXXSpecialMemberKind getSpecialMember(const CXXMethodDecl *MD)
Definition: Sema.h:6264
bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS)
SetMemberAccessSpecifier - Set the access specifier of a member.
Definition: SemaAccess.cpp:35
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:1650
@ AR_dependent
Definition: Sema.h:1653
@ AR_accessible
Definition: Sema.h:1651
@ AR_inaccessible
Definition: Sema.h:1652
@ AR_delayed
Definition: Sema.h:1654
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:1647
ASTContext & Context
Definition: Sema.h:1276
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:1652
void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs)
const LangOptions & getLangOpts() const
Definition: Sema.h:911
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:1411
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:334
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3714
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:396
A container of type source information.
Definition: TypeBase.h:8314
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.h:26
CXXRecordDecl * castAsCXXRecordDecl() const
Definition: Type.h:36
CanQualType getCanonicalTypeUnqualified() const
const T * castAs() const
Member-template castAs<specific type>.
Definition: TypeBase.h:9226
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: TypeBase.h:2800
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3559
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition: ExprCXX.h:3384
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition: ExprCXX.h:4120
The iterator over UnresolvedSets.
Definition: UnresolvedSet.h:35
Represents a C++ using-declaration.
Definition: DeclCXX.h:3585
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3393
Represents a variable declaration or definition.
Definition: Decl.h:925
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)
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:123
@ AS_public
Definition: Specifiers.h:124
@ AS_protected
Definition: Specifiers.h:125
@ AS_none
Definition: Specifiers.h:127
@ AS_private
Definition: Specifiers.h:126
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition: DeclBase.h:1288
@ Class
The "class" keyword introduces the elaborated-type-specifier.
#define false
Definition: stdbool.h:26
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.