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