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