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