clang 24.0.0git
SemaAccess.cpp
Go to the documentation of this file.
1//===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file provides Sema routines for C++ access control semantics.
10//
11//===----------------------------------------------------------------------===//
12
15#include "clang/AST/DeclCXX.h"
17#include "clang/AST/DeclObjC.h"
19#include "clang/AST/ExprCXX.h"
23#include "clang/Sema/Lookup.h"
24#include "clang/Sema/Template.h"
26#include "llvm/ADT/ScopeExit.h"
27
28using namespace clang;
29using namespace sema;
30
31/// A copy of Sema's enum without AR_delayed.
37
39 NamedDecl *PrevMemberDecl,
40 AccessSpecifier LexicalAS) {
41 if (!PrevMemberDecl) {
42 // Use the lexical access specifier.
43 MemberDecl->setAccess(LexicalAS);
44 return false;
45 }
46
47 // C++ [class.access.spec]p3: When a member is redeclared its access
48 // specifier must be same as its initial declaration.
49 if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
50 Diag(MemberDecl->getLocation(),
51 diag::err_class_redeclared_with_different_access)
52 << MemberDecl << LexicalAS;
53 Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
54 << PrevMemberDecl << PrevMemberDecl->getAccess();
55
56 MemberDecl->setAccess(LexicalAS);
57 return true;
58 }
59
60 MemberDecl->setAccess(PrevMemberDecl->getAccess());
61 return false;
62}
63
65 DeclContext *DC = D->getDeclContext();
66
67 // This can only happen at top: enum decls only "publish" their
68 // immediate members.
69 if (isa<EnumDecl>(DC))
70 DC = cast<EnumDecl>(DC)->getDeclContext();
71
72 CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
73 while (DeclaringClass->isAnonymousStructOrUnion())
74 DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
75 return DeclaringClass;
76}
77
78namespace {
79struct EffectiveContext {
80 EffectiveContext() : Inner(nullptr), Dependent(false) {}
81
82 explicit EffectiveContext(DeclContext *DC)
83 : Inner(DC),
84 Dependent(DC->isDependentContext()) {
85
86 // An implicit deduction guide is semantically in the context enclosing the
87 // class template, but for access purposes behaves like the constructor
88 // from which it was produced.
89 if (auto *DGD = dyn_cast<CXXDeductionGuideDecl>(DC)) {
90 if (DGD->isImplicit()) {
91 DC = DGD->getCorrespondingConstructor();
92 if (!DC) {
93 // The copy deduction candidate doesn't have a corresponding
94 // constructor.
95 DC = cast<DeclContext>(DGD->getDeducedTemplate()->getTemplatedDecl());
96 }
97 }
98 }
99
100 // C++11 [class.access.nest]p1:
101 // A nested class is a member and as such has the same access
102 // rights as any other member.
103 // C++11 [class.access]p2:
104 // A member of a class can also access all the names to which
105 // the class has access. A local class of a member function
106 // may access the same names that the member function itself
107 // may access.
108 // This almost implies that the privileges of nesting are transitive.
109 // Technically it says nothing about the local classes of non-member
110 // functions (which can gain privileges through friendship), but we
111 // take that as an oversight.
112 while (true) {
113 // We want to add canonical declarations to the EC lists for
114 // simplicity of checking, but we need to walk up through the
115 // actual current DC chain. Otherwise, something like a local
116 // extern or friend which happens to be the canonical
117 // declaration will really mess us up.
118
119 if (isa<CXXRecordDecl>(DC)) {
120 CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
121 Records.push_back(Record->getCanonicalDecl());
122 DC = Record->getDeclContext();
123 } else if (isa<FunctionDecl>(DC)) {
124 FunctionDecl *Function = cast<FunctionDecl>(DC);
125 Functions.push_back(Function->getCanonicalDecl());
126 if (Function->getFriendObjectKind())
127 DC = Function->getLexicalDeclContext();
128 else
129 DC = Function->getDeclContext();
130 } else if (DC->isFileContext()) {
131 break;
132 } else {
133 DC = DC->getParent();
134 }
135 }
136 }
137
138 bool isDependent() const { return Dependent; }
139
140 bool includesClass(const CXXRecordDecl *R) const {
141 R = R->getCanonicalDecl();
142 return llvm::is_contained(Records, R);
143 }
144
145 /// Retrieves the innermost "useful" context. Can be null if we're
146 /// doing access-control without privileges.
147 DeclContext *getInnerContext() const {
148 return Inner;
149 }
150
151 typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
152
153 DeclContext *Inner;
154 SmallVector<FunctionDecl*, 4> Functions;
155 SmallVector<CXXRecordDecl*, 4> Records;
156 bool Dependent;
157};
158
159/// Like sema::AccessedEntity, but kindly lets us scribble all over
160/// it.
161struct AccessTarget : public AccessedEntity {
162 AccessTarget(const AccessedEntity &Entity)
163 : AccessedEntity(Entity) {
164 initialize();
165 }
166
167 AccessTarget(ASTContext &Context,
168 MemberNonce _,
169 CXXRecordDecl *NamingClass,
170 DeclAccessPair FoundDecl,
171 QualType BaseObjectType)
172 : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,
173 FoundDecl, BaseObjectType) {
174 initialize();
175 }
176
177 AccessTarget(ASTContext &Context,
178 BaseNonce _,
179 CXXRecordDecl *BaseClass,
180 CXXRecordDecl *DerivedClass,
181 AccessSpecifier Access)
182 : AccessedEntity(Context.getDiagAllocator(), Base, BaseClass, DerivedClass,
183 Access) {
184 initialize();
185 }
186
187 bool isInstanceMember() const {
188 return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
189 }
190
191 bool hasInstanceContext() const {
192 return HasInstanceContext;
193 }
194
195 class SavedInstanceContext {
196 public:
197 SavedInstanceContext(SavedInstanceContext &&S)
198 : Target(S.Target), Has(S.Has) {
199 S.Target = nullptr;
200 }
201
202 // The move assignment operator is defined as deleted pending further
203 // motivation.
204 SavedInstanceContext &operator=(SavedInstanceContext &&) = delete;
205
206 // The copy constrcutor and copy assignment operator is defined as deleted
207 // pending further motivation.
208 SavedInstanceContext(const SavedInstanceContext &) = delete;
209 SavedInstanceContext &operator=(const SavedInstanceContext &) = delete;
210
211 ~SavedInstanceContext() {
212 if (Target)
213 Target->HasInstanceContext = Has;
214 }
215
216 private:
217 friend struct AccessTarget;
218 explicit SavedInstanceContext(AccessTarget &Target)
219 : Target(&Target), Has(Target.HasInstanceContext) {}
220 AccessTarget *Target;
221 bool Has;
222 };
223
224 SavedInstanceContext saveInstanceContext() {
225 return SavedInstanceContext(*this);
226 }
227
228 void suppressInstanceContext() {
229 HasInstanceContext = false;
230 }
231
232 const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
233 assert(HasInstanceContext);
234 if (CalculatedInstanceContext)
235 return InstanceContext;
236
237 CalculatedInstanceContext = true;
238 DeclContext *IC = S.computeDeclContext(getBaseObjectType());
239 InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
240 : nullptr);
241 return InstanceContext;
242 }
243
244 const CXXRecordDecl *getDeclaringClass() const {
245 return DeclaringClass;
246 }
247
248 /// The "effective" naming class is the canonical non-anonymous
249 /// class containing the actual naming class.
250 const CXXRecordDecl *getEffectiveNamingClass() const {
251 const CXXRecordDecl *namingClass = getNamingClass();
252 while (namingClass->isAnonymousStructOrUnion())
253 namingClass = cast<CXXRecordDecl>(namingClass->getParent());
254 return namingClass->getCanonicalDecl();
255 }
256
257private:
258 void initialize() {
259 HasInstanceContext = (isMemberAccess() &&
260 !getBaseObjectType().isNull() &&
261 getTargetDecl()->isCXXInstanceMember());
262 CalculatedInstanceContext = false;
263 InstanceContext = nullptr;
264
265 if (isMemberAccess())
266 DeclaringClass = FindDeclaringClass(getTargetDecl());
267 else
268 DeclaringClass = getBaseClass();
269 DeclaringClass = DeclaringClass->getCanonicalDecl();
270 }
271
272 bool HasInstanceContext : 1;
273 mutable bool CalculatedInstanceContext : 1;
274 mutable const CXXRecordDecl *InstanceContext;
275 const CXXRecordDecl *DeclaringClass;
276};
277} // namespace
278
280 QualType Ty) {
281 return Context.getCanonicalType(Ty)->getAs<FunctionProtoType>();
282}
283
286 return GetCanonicalFunctionProto(Context, FD->getType());
287}
288
289static const TemplateSpecializationType *
292 if (!NNS || NNS.getKind() != NestedNameSpecifier::Kind::Type)
293 return nullptr;
294
295 QualType Ty(NNS.getAsType(), 0);
296 if (const auto *ICNT = Ty->getAs<InjectedClassNameType>())
297 Ty = ICNT->getDecl()->getCanonicalTemplateSpecializationType(Context);
298
299 const auto *TST = Ty->getAsNonAliasTemplateSpecializationType();
300 if (TST && isa_and_nonnull<ClassTemplateDecl>(
301 TST->getTemplateName().getAsTemplateDecl()))
302 return TST;
303
304 return nullptr;
305}
306
308 if (auto *FTD = FD->getPrimaryTemplate())
309 return FTD->getCanonicalDecl();
310
311 if (auto *FTD = FD->getDescribedFunctionTemplate())
312 return FTD->getCanonicalDecl();
313
314 if (FunctionDecl *Pattern =
315 FD->getTemplateInstantiationPattern(/*ForDefinition=*/false)) {
316 if (auto *FTD = Pattern->getDescribedFunctionTemplate())
317 return FTD->getCanonicalDecl();
318 if (auto *FTD = Pattern->getPrimaryTemplate())
319 return FTD->getCanonicalDecl();
320 }
321
322 return nullptr;
323}
324
327 CTD = Pattern;
328 return CTD;
329}
330
332 if (auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(RD))
333 return Spec->getSpecializedTemplate();
334 return RD->getDescribedClassTemplate();
335}
336
339 const MultiLevelTemplateArgumentList &Args) {
340 TemplateParameterList *InstTPL =
341 S.SubstTemplateParams(TPL, DC, Args,
342 /*EvaluateConstraints=*/false);
343 if (!InstTPL || !TPL->getRequiresClause())
344 return InstTPL;
345
346 ExprResult InstRequiresClause =
348 if (!InstRequiresClause.isUsable())
349 return nullptr;
350
352 S.Context, InstTPL->getTemplateLoc(), InstTPL->getLAngleLoc(),
353 InstTPL->asArray(), InstTPL->getRAngleLoc(), InstRequiresClause.get());
354}
355
356static AccessResult
358 const TemplateSpecializationType *TST,
360 TemplateSpecCandidateSet *FailedTSC,
361 MultiLevelTemplateArgumentList &DeducedArgs) {
362 const auto *CandidateRD = dyn_cast<CXXRecordDecl>(DC);
363 if (!CandidateRD)
364 return AR_inaccessible;
365
366 ClassTemplateDecl *CandidateCTD = CandidateRD->getDescribedClassTemplate();
367 ArrayRef<TemplateArgument> CandidateArgs;
368 if (CandidateCTD) {
369 CandidateArgs = CandidateCTD->getInjectedTemplateArgs(S.Context);
370 } else {
371 const auto *CandidateSpec =
372 dyn_cast<ClassTemplateSpecializationDecl>(CandidateRD);
373 if (!CandidateSpec)
374 return AR_inaccessible;
375 CandidateCTD = CandidateSpec->getSpecializedTemplate();
376 CandidateArgs = CandidateSpec->getTemplateArgs().asArray();
377 }
378
379 auto *PatternCTD = dyn_cast_if_present<ClassTemplateDecl>(
380 TST->getTemplateName().getAsTemplateDecl());
381 if (!PatternCTD || !declaresSameEntity(GetClassTemplatePattern(CandidateCTD),
382 GetClassTemplatePattern(PatternCTD)))
383 return AR_inaccessible;
384
385 if (S.DeduceTemplateArguments(FTD, PatternCTD, CandidateCTD, TPLs,
386 TST->template_arguments(), CandidateArgs,
387 FTD->getLocation(), FailedTSC, DeducedArgs))
388 return AR_accessible;
389
390 return CandidateRD->isDependentContext() ? AR_dependent : AR_inaccessible;
391}
392
394 Sema &S;
399 Sema::SFINAETrap Trap;
400 LocalInstantiationScope InstantiationScope;
402
403public:
405 : S(S), FTD(FTD), Inst(S, FTD->getLocation(), FTD),
406 Info(FTD->getLocation()), Trap(S, Info), InstantiationScope(S) {}
407
408 AccessResult deduce(DeclContext *DC, const TemplateSpecializationType *TST,
410 TemplateSpecCandidateSet *FailedTSC) {
411 if (Inst.isInvalid())
412 return Result = AR_inaccessible;
413 return Result = DeduceTemplateArguments(S, FTD, DC, TST, TPLs, FailedTSC,
414 DeducedArgs);
415 }
416
417 AccessResult getAccessResult() const { return Result; }
419
420 bool hasDeducedArgs() const { return Result == AR_accessible; }
421 bool hasErrorOccurred() const { return Trap.hasErrorOccurred(); }
422};
423
424static bool HasSameFunctionType(Sema &S, QualType FriendType,
425 QualType ContextType, SourceLocation Loc) {
427 ContextType))
428 return false;
429
430 const auto *FriendFPT = FriendType->castAs<FunctionProtoType>();
431 const auto *ContextFPT = ContextType->castAs<FunctionProtoType>();
432 return !S.CheckEquivalentExceptionSpec(S.PDiag(), S.PDiag(), FriendFPT, Loc,
433 ContextFPT, Loc);
434}
435
436/// Checks whether one class might instantiate to the other.
437static bool MightInstantiateTo(const CXXRecordDecl *From,
438 const CXXRecordDecl *To) {
439 // Declaration names are always preserved by instantiation.
440 if (From->getDeclName() != To->getDeclName())
441 return false;
442
443 const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
444 const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
445
446 if (FromDC == ToDC)
447 return true;
448
449 if (FromDC->isFileContext() || ToDC->isFileContext())
450 return false;
451
452 // Be conservative.
453 return true;
454}
455
456/// Checks whether one class is derived from another, inclusively.
457/// Properly indicates when it couldn't be determined due to
458/// dependence.
459///
460/// This should probably be donated to AST or at least Sema.
462 const CXXRecordDecl *Target) {
463 assert(Derived->getCanonicalDecl() == Derived);
464 assert(Target->getCanonicalDecl() == Target);
465
466 if (Derived == Target) return AR_accessible;
467
468 bool CheckDependent = Derived->isDependentContext();
469 if (CheckDependent && MightInstantiateTo(Derived, Target))
470 return AR_dependent;
471
472 AccessResult OnFailure = AR_inaccessible;
473 SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
474
475 while (true) {
476 if (Derived->isDependentContext() && !Derived->hasDefinition() &&
477 !Derived->isLambda())
478 return AR_dependent;
479
480 for (const auto &I : Derived->bases()) {
481 const CXXRecordDecl *RD;
482
483 QualType T = I.getType();
484 if (CXXRecordDecl *Rec = T->getAsCXXRecordDecl()) {
485 RD = Rec;
486 } else {
487 assert(T->isDependentType() && "non-dependent base wasn't a record?");
488 OnFailure = AR_dependent;
489 continue;
490 }
491
492 RD = RD->getCanonicalDecl();
493 if (RD == Target) return AR_accessible;
494 if (CheckDependent && MightInstantiateTo(RD, Target))
495 OnFailure = AR_dependent;
496
497 Queue.push_back(RD);
498 }
499
500 if (Queue.empty()) break;
501
502 Derived = Queue.pop_back_val();
503 }
504
505 return OnFailure;
506}
507
509 if (Friend == Context)
510 return true;
511
512 assert(!Friend->isDependentContext() &&
513 "can't handle friends with dependent contexts here");
514
515 if (!Context->isDependentContext())
516 return false;
517
518 if (Friend->isFileContext())
519 return false;
520
521 // TODO: this is very conservative
522 return true;
523}
524
525// Asks whether the type in 'context' can ever instantiate to the type
526// in 'friend'.
528 if (Friend == Context)
529 return true;
530
531 if (!Friend->isDependentType() && !Context->isDependentType())
532 return false;
533
534 // TODO: this is very conservative.
535 return true;
536}
537
540 if (Friend.getQualifiers() != Context.getQualifiers())
541 return false;
542
543 if (Friend->getNumParams() != Context->getNumParams())
544 return false;
545
546 if (!MightInstantiateTo(Context->getReturnType(), Friend->getReturnType()))
547 return false;
548
549 for (unsigned I = 0, E = Friend->getNumParams(); I != E; ++I)
550 if (!MightInstantiateTo(Context->getParamType(I), Friend->getParamType(I)))
551 return false;
552
553 return true;
554}
555
558 if (Context == Friend)
559 return true;
560
561 if (Context.getNameKind() != Friend.getNameKind())
562 return false;
563
564 switch (Context.getNameKind()) {
568 return MightInstantiateTo(Ctx.getCanonicalType(Context.getCXXNameType()),
569 Ctx.getCanonicalType(Friend.getCXXNameType()));
570
571 default:
572 return false;
573 }
574}
575
576static bool MightInstantiateTo(ASTContext &Ctx, FunctionDecl *Context,
578 if (!MightInstantiateTo(Ctx, Context->getDeclName(), Friend->getDeclName()))
579 return false;
580
581 DeclContext *ContextDC = Context->getDeclContext();
582 DeclContext *FriendDC = Friend->getDeclContext();
583
584 if (!FriendDC->isDependentContext() &&
585 !MightInstantiateTo(ContextDC, FriendDC))
586 return false;
587
590 GetCanonicalFunctionProto(Ctx, Context);
591
592 return MightInstantiateTo(ContextTy, FriendTy);
593}
594
597 return MightInstantiateTo(Ctx, Context->getTemplatedDecl(),
598 Friend->getTemplatedDecl());
599}
600
602 const EffectiveContext &EC,
603 const CXXRecordDecl *Friend) {
604 if (EC.includesClass(Friend))
605 return AR_accessible;
606
607 if (EC.isDependent()) {
608 for (const CXXRecordDecl *Context : EC.Records) {
609 if (MightInstantiateTo(Context, Friend))
610 return AR_dependent;
611 }
612 }
613
614 return AR_inaccessible;
615}
616
618 const EffectiveContext &EC,
620 if (const auto *RD = Friend->getAsCXXRecordDecl())
621 return MatchesFriend(S, EC, RD);
622
623 // TODO: we can do better than this
624 if (Friend->isDependentType())
625 return AR_dependent;
626
627 return AR_inaccessible;
628}
629
630/// Determines whether the given friend class template matches
631/// anything in the effective context.
633 const EffectiveContext &EC,
635 AccessResult OnFailure = AR_inaccessible;
636
637 // Check whether the friend is the template of a class in the
638 // context chain.
640 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
641 CXXRecordDecl *Record = *I;
642
643 // Figure out whether the current class has a template:
645
646 // A specialization of the template...
649 ->getSpecializedTemplate();
650
651 // ... or the template pattern itself.
652 } else {
653 CTD = Record->getDescribedClassTemplate();
654 if (!CTD) continue;
655 }
656
657 // It's a match.
658 if (declaresSameEntity(Friend, CTD))
659 return AR_accessible;
660
661 // If the context isn't dependent, it can't be a dependent match.
662 if (!EC.isDependent())
663 continue;
664
665 // If the template names don't match, it can't be a dependent
666 // match.
667 if (CTD->getDeclName() != Friend->getDeclName())
668 continue;
669
670 // If the class's context can't instantiate to the friend's
671 // context, it can't be a dependent match.
672 if (!MightInstantiateTo(CTD->getDeclContext(), Friend->getDeclContext()))
673 continue;
674
675 // Otherwise, it's a dependent match.
676 OnFailure = AR_dependent;
677 }
678
679 return OnFailure;
680}
681
682/// Determines whether the given friend function matches anything in
683/// the effective context.
685 const EffectiveContext &EC,
687 AccessResult OnFailure = AR_inaccessible;
688
690 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
691 if (Friend == *I)
692 return AR_accessible;
693
694 if (EC.isDependent() && MightInstantiateTo(S.Context, *I, Friend))
695 OnFailure = AR_dependent;
696 }
697
698 return OnFailure;
699}
700
701/// Determines whether the given friend function template matches
702/// anything in the effective context.
704 const EffectiveContext &EC,
706 if (EC.Functions.empty()) return AR_inaccessible;
707
708 AccessResult OnFailure = AR_inaccessible;
709
711 I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
712
714 if (!FTD)
715 continue;
716
717 if (Friend == FTD)
718 return AR_accessible;
719
720 if (EC.isDependent() && MightInstantiateTo(S.Context, FTD, Friend))
721 OnFailure = AR_dependent;
722 }
723
724 return OnFailure;
725}
726
727static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC,
728 NamedDecl *ND) {
730 if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
731 return MatchesFriend(S, EC, CTD);
732
733 if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
734 return MatchesFriend(S, EC, FTD);
735
736 if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND))
737 return MatchesFriend(S, EC, RD);
738
739 assert(isa<FunctionDecl>(ND) && "unknown friend decl kind");
740 return MatchesFriend(S, EC, cast<FunctionDecl>(ND));
741}
742
744 DeclarationName FriendName,
745 TagTypeKind FriendTagKind,
746 ClassTemplateDecl *ContextCTD,
747 const TemplateSpecializationType *FriendTST,
749 TemplateParameterList *MemberTPL,
750 TemplateSpecCandidateSet *FailedTSC) {
751 if (FriendName != ContextCTD->getDeclName())
752 return AR_inaccessible;
753
754 if ((FriendTagKind == TagTypeKind::Union) !=
755 ContextCTD->getTemplatedDecl()->isUnion())
756 return AR_inaccessible;
757
758 DeclContext *ContextDC = ContextCTD->getDeclContext();
759 AccessResult OnFailure =
761
762 FriendTemplateMatchContext FTMC(S, FTD);
763 AccessResult Result = FTMC.deduce(ContextDC, FriendTST, TPLs, FailedTSC);
764 if (!FTMC.hasDeducedArgs())
765 return Result;
766
768 S, MemberTPL, ContextDC, FTMC.getDeducedArgs());
769 if (!InstTPL || FTMC.hasErrorOccurred())
770 return OnFailure;
771
773 ContextDC, FTD->getLexicalDeclContext(), FTD->getLocation());
775 FriendInfo, InstTPL, ContextCTD, ContextCTD->getTemplateParameters(),
776 /*Complain=*/false, Sema::TPL_TemplateMatch))
777 return AR_accessible;
778 return OnFailure;
779}
780
781static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC,
783 ClassTemplateDecl *FriendCTD,
784 NestedNameSpecifier Qualifier,
785 TemplateSpecCandidateSet *FailedTSC) {
786 const auto *FriendTST =
788 if (!FriendTST)
789 return MatchesFriend(S, EC, FriendCTD);
790
792
793 AccessResult OnFailure = AR_inaccessible;
794 for (CXXRecordDecl *ContextRD : EC.Records) {
795 ClassTemplateDecl *ContextCTD = GetClassTemplateDecl(ContextRD);
796 if (!ContextCTD)
797 continue;
798
800 MatchesFriend(S, FTD, FriendCTD->getDeclName(),
801 FriendCTD->getTemplatedDecl()->getTagKind(), ContextCTD,
802 FriendTST, TPLs.drop_back(), TPLs.back(), FailedTSC);
803 if (Result == AR_accessible)
804 return AR_accessible;
805 if (Result == AR_dependent)
806 OnFailure = AR_dependent;
807 }
808
809 return OnFailure;
810}
811
812static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC,
815 ClassTemplateDecl *FriendCTD,
816 TemplateSpecCandidateSet *FailedTSC) {
817 NestedNameSpecifier Qualifier = FriendTemplate.getQualifier();
818 if (FriendTemplate.getAsUsingShadowDecl())
819 Qualifier = FriendCTD->getTemplatedDecl()->getQualifier();
820 return MatchesFriend(S, EC, FTD, FriendCTD, Qualifier, FailedTSC);
821}
822
823static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC,
825 ClassTemplateDecl *FriendCTD,
826 TemplateSpecCandidateSet *FailedTSC) {
827 return MatchesFriend(S, EC, FTD, FriendCTD,
828 FriendCTD->getTemplatedDecl()->getQualifier(),
829 FailedTSC);
830}
831
833 FunctionDecl *FriendFD,
834 FunctionDecl *ContextFD,
835 const TemplateSpecializationType *FriendTST,
837 TemplateSpecCandidateSet *FailedTSC) {
838 if (!MightInstantiateTo(S.Context, ContextFD->getDeclName(),
839 FriendFD->getDeclName()))
840 return AR_inaccessible;
841
844 FunctionTemplateDecl *ContextTemplate = TryGetFunctionTemplateDecl(ContextFD);
845
846 if (FriendTemplate && !ContextTemplate)
847 return AR_inaccessible;
848
849 DeclContext *ContextDC = ContextFD->getDeclContext();
850 AccessResult OnFailure =
852
853 FriendTemplateMatchContext FTMC(S, FTD);
854 AccessResult Result = FTMC.deduce(ContextDC, FriendTST, TPLs, FailedTSC);
855 if (!FTMC.hasDeducedArgs())
856 return Result;
857
859 ContextDC, FTD->getLexicalDeclContext(), FTD->getLocation());
860 if (FriendTemplate) {
861 TemplateParameterList *InstTPL =
862 SubstTemplateParameterList(S, FriendTemplate->getTemplateParameters(),
863 ContextDC, FTMC.getDeducedArgs());
864 if (!InstTPL || !S.TemplateParameterListsAreEqual(
865 FriendInfo, InstTPL, ContextTemplate,
866 ContextTemplate->getTemplateParameters(),
867 /*Complain=*/false, Sema::TPL_TemplateMatch))
868 return OnFailure;
869
870 ContextFD = ContextTemplate->getTemplatedDecl();
871 }
872
873 Sema::ContextRAII SavedContext(S, FTD->getDeclContext());
874 QualType InstFriendType =
875 S.SubstType(FriendFD->getType(), FTMC.getDeducedArgs(),
876 FriendFD->getLocation(), FriendFD->getDeclName());
877 SavedContext.pop();
878 if (InstFriendType.isNull() || FTMC.hasErrorOccurred())
879 return OnFailure;
880
881 if (ContextTemplate && !FriendTemplate) {
882 AccessResult OnSpecializationFailure =
883 ContextFD->isDependentContext() ? AR_dependent : OnFailure;
884 const ASTTemplateArgumentListInfo *ArgsWritten =
887 if (ArgsWritten) {
888 InstArgs.setLAngleLoc(ArgsWritten->getLAngleLoc());
889 InstArgs.setRAngleLoc(ArgsWritten->getRAngleLoc());
890 if (S.SubstTemplateArguments(ArgsWritten->arguments(),
891 FTMC.getDeducedArgs(), InstArgs))
892 return OnSpecializationFailure;
893 }
894
895 FunctionDecl *ContextSpecialization = nullptr;
896 TemplateDeductionInfo FunctionInfo(FTD->getLocation());
898 ContextTemplate, ArgsWritten ? &InstArgs : nullptr, InstFriendType,
899 ContextSpecialization,
900 FunctionInfo) != TemplateDeductionResult::Success ||
901 !ContextSpecialization || FTMC.hasErrorOccurred() ||
902 !declaresSameEntity(ContextSpecialization, ContextFD))
903 return OnSpecializationFailure;
904
905 ContextFD = ContextSpecialization;
906 }
907
908 if (!HasSameFunctionType(S, InstFriendType, ContextFD->getType(),
909 FTD->getLocation()) ||
910 FTMC.hasErrorOccurred())
911 return OnFailure;
912
913 if (!FriendTemplate)
914 return AR_accessible;
915
916 AssociatedConstraint FriendRequiresClause =
917 FriendFD->getTrailingRequiresClause();
918 AssociatedConstraint ContextRequiresClause =
919 ContextFD->getTrailingRequiresClause();
920 if (FriendRequiresClause.isNull() != ContextRequiresClause.isNull())
921 return AR_inaccessible;
922
923 if (!FriendRequiresClause)
924 return AR_accessible;
925
926 ExprResult InstFriendRequiresClause =
928 const_cast<Expr *>(FriendRequiresClause.ConstraintExpr),
929 FTMC.getDeducedArgs());
930
931 if (!InstFriendRequiresClause.isUsable())
932 return OnFailure;
933
935 ContextFD, ContextRequiresClause.ConstraintExpr, FriendInfo,
936 InstFriendRequiresClause.get()))
937 return OnFailure;
939}
940
941static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC,
943 FunctionDecl *FriendFD,
944 TemplateSpecCandidateSet *FailedTSC) {
945 const auto *FriendTST = GetQualifierClassTemplateSpecializationType(
946 S.Context, FriendFD->getQualifier());
947 if (!FriendTST)
948 return AR_inaccessible;
949
951
952 AccessResult OnFailure = AR_inaccessible;
953 for (FunctionDecl *ContextFD : EC.Functions) {
955 MatchesFriend(S, FTD, FriendFD, ContextFD, FriendTST, TPLs, FailedTSC);
956 if (Result == AR_accessible)
957 return AR_accessible;
958
959 if (Result == AR_dependent)
960 OnFailure = AR_dependent;
961 }
962 return OnFailure;
963}
964
965static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC,
967 TemplateSpecCandidateSet *FailedTSC) {
969 if (auto *FriendCTD = dyn_cast_if_present<ClassTemplateDecl>(
970 FriendTemplate.getAsTemplateDecl()))
971 return MatchesFriend(S, EC, FTD, FriendTemplate, FriendCTD, FailedTSC);
972 if (auto *FriendCTD = dyn_cast<ClassTemplateDecl>(Friend))
973 return MatchesFriend(S, EC, FTD, FriendCTD, FailedTSC);
974 if (FunctionDecl *FriendFD = Friend->getAsFunction())
975 return MatchesFriend(S, EC, FTD, FriendFD, FailedTSC);
976 return MatchesFriend(S, EC, Friend);
977}
978
979static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC,
981 TypeSourceInfo *FriendTSI,
982 TemplateSpecCandidateSet *FailedTSC) {
983 QualType FriendType = FriendTSI->getType();
984 if (!FriendType->isDependentType())
985 return MatchesFriend(S, EC, S.Context.getCanonicalType(FriendType));
986
987 AccessResult OnFailure = AR_inaccessible;
988 if (auto FriendTSTL =
990 const auto *FriendTST = FriendTSTL.getTypePtr();
991 const auto *FriendQTST = GetQualifierClassTemplateSpecializationType(
992 S.Context, FriendTSTL.getQualifierLoc().getNestedNameSpecifier());
993 if (!FriendQTST)
994 return OnFailure;
995
997
998 TemplateName FriendTemplate = FriendTST->getTemplateName();
999 DeclarationName FriendName;
1000 if (TemplateDecl *TD = FriendTemplate.getAsTemplateDecl())
1001 FriendName = TD->getDeclName();
1002 else if (DependentTemplateName *DTN =
1003 FriendTemplate.getAsDependentTemplateName())
1004 FriendName = DTN->getName().getIdentifier();
1005
1006 TagTypeKind FriendTagKind =
1007 TypeWithKeyword::getTagTypeKindForKeyword(FriendTST->getKeyword());
1008
1009 for (CXXRecordDecl *ContextRD : EC.Records) {
1010 ClassTemplateDecl *ContextCTD = GetClassTemplateDecl(ContextRD);
1011 if (!ContextCTD)
1012 continue;
1013
1014 if (FriendName && ContextCTD->getDeclName() != FriendName)
1015 continue;
1016
1017 if ((FriendTagKind == TagTypeKind::Union) !=
1018 ContextCTD->getTemplatedDecl()->isUnion())
1019 continue;
1020
1021 FriendTemplateMatchContext FTMC(S, FTD);
1023 FTMC.deduce(ContextRD->getDeclContext(), FriendQTST, TPLs, FailedTSC);
1024 if (!FTMC.hasDeducedArgs()) {
1025 if (Result == AR_dependent)
1026 OnFailure = AR_dependent;
1027 continue;
1028 }
1029
1030 TypeSourceInfo *InstFriendTSI =
1031 S.SubstFriendType(FriendTSI, FTMC.getDeducedArgs(),
1032 FTD->getLocation(), DeclarationName());
1033 if (InstFriendTSI && !FTMC.hasErrorOccurred() &&
1034 S.Context.hasSameType(InstFriendTSI->getType(),
1035 S.Context.getCanonicalTagType(ContextRD)))
1036 return AR_accessible;
1037
1038 if (ContextRD->isDependentContext())
1039 OnFailure = AR_dependent;
1040 }
1041
1042 return OnFailure;
1043 }
1044
1045 const auto *FriendDNT = FriendType->getAs<DependentNameType>();
1046 if (!FriendDNT)
1047 return OnFailure;
1048
1049 const auto *FriendTST = GetQualifierClassTemplateSpecializationType(
1050 S.Context, FriendDNT->getQualifier());
1051 if (!FriendTST)
1052 return OnFailure;
1053
1055
1056 TagTypeKind FriendTagKind =
1057 TypeWithKeyword::getTagTypeKindForKeyword(FriendDNT->getKeyword());
1058 for (CXXRecordDecl *ContextRD : EC.Records) {
1059 if (ContextRD->getDeclName() != FriendDNT->getIdentifier())
1060 continue;
1061
1062 if (ClassTemplateDecl *ContextCTD = GetClassTemplateDecl(ContextRD)) {
1063 if (FTD->getFriendTemplateName().isNull()) {
1064 if (FailedTSC) {
1066 DeduceTemplateArguments(S, FTD, ContextCTD->getDeclContext(),
1067 FriendTST, TPLs, FailedTSC, DeducedArgs);
1068 }
1069 continue;
1070 }
1071
1073 S, FTD, FriendDNT->getIdentifier(), FriendTagKind, ContextCTD,
1074 FriendTST, TPLs.drop_back(), TPLs.back(), FailedTSC);
1075 if (Result == AR_accessible)
1076 return AR_accessible;
1077 if (Result == AR_dependent)
1078 OnFailure = AR_dependent;
1079 continue;
1080 }
1081
1082 if (!FTD->getFriendTemplateName().isNull())
1083 continue;
1084
1085 if ((FriendTagKind == TagTypeKind::Union) != ContextRD->isUnion())
1086 continue;
1087
1090 DeduceTemplateArguments(S, FTD, ContextRD->getDeclContext(), FriendTST,
1091 TPLs, FailedTSC, DeducedArgs);
1092 if (Result == AR_accessible)
1093 return AR_accessible;
1094 if (Result == AR_dependent)
1095 OnFailure = AR_dependent;
1096 }
1097 return OnFailure;
1098}
1099
1100/// Determines whether the given friend declaration matches anything
1101/// in the effective context.
1103 const EffectiveContext &EC,
1104 FriendDecl *FriendD) {
1105 // Whitelist accesses if there's an invalid friend declaration.
1106 if (FriendD->isInvalidDecl())
1107 return AR_accessible;
1108
1109 if (NamedDecl *Friend = FriendD->getFriendDecl())
1110 return MatchesFriend(S, EC, Friend);
1111
1112 if (TypeSourceInfo *T = FriendD->getFriendType())
1113 return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
1114
1115 return AR_inaccessible;
1116}
1117
1118static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC,
1119 FriendTemplateDecl *FTD,
1120 TemplateSpecCandidateSet *FailedTSC) {
1121 if (FTD->isInvalidDecl())
1122 return AR_accessible;
1123
1124 if (TypeSourceInfo *TSI = FTD->getFriendType())
1125 return MatchesFriend(S, EC, FTD, TSI, FailedTSC);
1126
1127 NamedDecl *Friend = FTD->getFriendDecl();
1128 assert(Friend && "friend template must name a type or declaration");
1129 return MatchesFriend(S, EC, FTD, Friend, FailedTSC);
1130}
1131
1132static AccessResult GetFriendKind(Sema &S, const EffectiveContext &EC,
1133 const CXXRecordDecl *Class,
1134 TemplateSpecCandidateSet *FailedTSC) {
1135 AccessResult OnFailure = AR_inaccessible;
1136
1137 // Okay, check friends.
1138 for (FriendDecl *Friend : Class->friends()) {
1139 AccessResult AR;
1140 if (auto *FTD = dyn_cast<FriendTemplateDecl>(Friend))
1141 AR = MatchesFriend(S, EC, FTD, FailedTSC);
1142 else
1143 AR = MatchesFriend(S, EC, Friend);
1144
1145 switch (AR) {
1146 case AR_accessible:
1147 return AR_accessible;
1148
1149 case AR_inaccessible:
1150 continue;
1151
1152 case AR_dependent:
1153 OnFailure = AR_dependent;
1154 break;
1155 }
1156 }
1157
1158 // That's it, give up.
1159 return OnFailure;
1160}
1161
1162namespace {
1163
1164/// A helper class for checking for a friend which will grant access
1165/// to a protected instance member.
1166struct ProtectedFriendContext {
1167 Sema &S;
1168 const EffectiveContext &EC;
1169 TemplateSpecCandidateSet *FailedTSC;
1170 const CXXRecordDecl *NamingClass;
1171 bool CheckDependent;
1172 bool EverDependent;
1173
1174 /// The path down to the current base class.
1175 SmallVector<const CXXRecordDecl*, 20> CurPath;
1176
1177 ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
1178 const CXXRecordDecl *InstanceContext,
1179 const CXXRecordDecl *NamingClass,
1180 TemplateSpecCandidateSet *FailedTSC)
1181 : S(S), EC(EC), FailedTSC(FailedTSC), NamingClass(NamingClass),
1182 CheckDependent(InstanceContext->isDependentContext() ||
1183 NamingClass->isDependentContext()),
1184 EverDependent(false) {}
1185
1186 /// Check classes in the current path for friendship, starting at
1187 /// the given index.
1188 bool checkFriendshipAlongPath(unsigned I) {
1189 assert(I < CurPath.size());
1190 for (unsigned E = CurPath.size(); I != E; ++I) {
1191 switch (GetFriendKind(S, EC, CurPath[I], FailedTSC)) {
1192 case AR_accessible: return true;
1193 case AR_inaccessible: continue;
1194 case AR_dependent: EverDependent = true; continue;
1195 }
1196 }
1197 return false;
1198 }
1199
1200 /// Perform a search starting at the given class.
1201 ///
1202 /// PrivateDepth is the index of the last (least derived) class
1203 /// along the current path such that a notional public member of
1204 /// the final class in the path would have access in that class.
1205 bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
1206 // If we ever reach the naming class, check the current path for
1207 // friendship. We can also stop recursing because we obviously
1208 // won't find the naming class there again.
1209 if (Cur == NamingClass)
1210 return checkFriendshipAlongPath(PrivateDepth);
1211
1212 if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
1213 EverDependent = true;
1214
1215 // Recurse into the base classes.
1216 for (const auto &I : Cur->bases()) {
1217 // If this is private inheritance, then a public member of the
1218 // base will not have any access in classes derived from Cur.
1219 unsigned BasePrivateDepth = PrivateDepth;
1220 if (I.getAccessSpecifier() == AS_private)
1221 BasePrivateDepth = CurPath.size() - 1;
1222
1223 const CXXRecordDecl *RD;
1224
1225 QualType T = I.getType();
1226 if (CXXRecordDecl *Rec = T->getAsCXXRecordDecl()) {
1227 RD = Rec;
1228 } else {
1229 assert(T->isDependentType() && "non-dependent base wasn't a record?");
1230 EverDependent = true;
1231 continue;
1232 }
1233
1234 // Recurse. We don't need to clean up if this returns true.
1235 CurPath.push_back(RD);
1236 if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
1237 return true;
1238 CurPath.pop_back();
1239 }
1240
1241 return false;
1242 }
1243
1244 bool findFriendship(const CXXRecordDecl *Cur) {
1245 assert(CurPath.empty());
1246 CurPath.push_back(Cur);
1247 return findFriendship(Cur, 0);
1248 }
1249};
1250}
1251
1252/// Search for a class P that EC is a friend of, under the constraint
1253/// InstanceContext <= P
1254/// if InstanceContext exists, or else
1255/// NamingClass <= P
1256/// and with the additional restriction that a protected member of
1257/// NamingClass would have some natural access in P, which implicitly
1258/// imposes the constraint that P <= NamingClass.
1259///
1260/// This isn't quite the condition laid out in the standard.
1261/// Instead of saying that a notional protected member of NamingClass
1262/// would have to have some natural access in P, it says the actual
1263/// target has to have some natural access in P, which opens up the
1264/// possibility that the target (which is not necessarily a member
1265/// of NamingClass) might be more accessible along some path not
1266/// passing through it. That's really a bad idea, though, because it
1267/// introduces two problems:
1268/// - Most importantly, it breaks encapsulation because you can
1269/// access a forbidden base class's members by directly subclassing
1270/// it elsewhere.
1271/// - It also makes access substantially harder to compute because it
1272/// breaks the hill-climbing algorithm: knowing that the target is
1273/// accessible in some base class would no longer let you change
1274/// the question solely to whether the base class is accessible,
1275/// because the original target might have been more accessible
1276/// because of crazy subclassing.
1277/// So we don't implement that.
1279 Sema &S, const EffectiveContext &EC, const CXXRecordDecl *InstanceContext,
1280 const CXXRecordDecl *NamingClass, TemplateSpecCandidateSet *FailedTSC) {
1281 assert(InstanceContext == nullptr ||
1282 InstanceContext->getCanonicalDecl() == InstanceContext);
1283 assert(NamingClass->getCanonicalDecl() == NamingClass);
1284
1285 // If we don't have an instance context, our constraints give us
1286 // that NamingClass <= P <= NamingClass, i.e. P == NamingClass.
1287 // This is just the usual friendship check.
1288 if (!InstanceContext)
1289 return GetFriendKind(S, EC, NamingClass, FailedTSC);
1290
1291 ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass, FailedTSC);
1292 if (PRC.findFriendship(InstanceContext)) return AR_accessible;
1293 if (PRC.EverDependent) return AR_dependent;
1294 return AR_inaccessible;
1295}
1296
1297static AccessResult HasAccess(Sema &S, const EffectiveContext &EC,
1298 const CXXRecordDecl *NamingClass,
1299 AccessSpecifier Access,
1300 const AccessTarget &Target,
1301 TemplateSpecCandidateSet *FailedTSC) {
1302 assert(NamingClass->getCanonicalDecl() == NamingClass &&
1303 "declaration should be canonicalized before being passed here");
1304
1305 if (Access == AS_public) return AR_accessible;
1306 assert(Access == AS_private || Access == AS_protected);
1307
1308 AccessResult OnFailure = AR_inaccessible;
1309
1310 for (EffectiveContext::record_iterator
1311 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1312 // All the declarations in EC have been canonicalized, so pointer
1313 // equality from this point on will work fine.
1314 const CXXRecordDecl *ECRecord = *I;
1315
1316 // [B2] and [M2]
1317 if (Access == AS_private) {
1318 if (ECRecord == NamingClass)
1319 return AR_accessible;
1320
1321 if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
1322 OnFailure = AR_dependent;
1323
1324 // [B3] and [M3]
1325 } else {
1326 assert(Access == AS_protected);
1327 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
1328 case AR_accessible: break;
1329 case AR_inaccessible: continue;
1330 case AR_dependent: OnFailure = AR_dependent; continue;
1331 }
1332
1333 // C++ [class.protected]p1:
1334 // An additional access check beyond those described earlier in
1335 // [class.access] is applied when a non-static data member or
1336 // non-static member function is a protected member of its naming
1337 // class. As described earlier, access to a protected member is
1338 // granted because the reference occurs in a friend or member of
1339 // some class C. If the access is to form a pointer to member,
1340 // the nested-name-specifier shall name C or a class derived from
1341 // C. All other accesses involve a (possibly implicit) object
1342 // expression. In this case, the class of the object expression
1343 // shall be C or a class derived from C.
1344 //
1345 // We interpret this as a restriction on [M3].
1346
1347 // In this part of the code, 'C' is just our context class ECRecord.
1348
1349 // These rules are different if we don't have an instance context.
1350 if (!Target.hasInstanceContext()) {
1351 // If it's not an instance member, these restrictions don't apply.
1352 if (!Target.isInstanceMember()) return AR_accessible;
1353
1354 // If it's an instance member, use the pointer-to-member rule
1355 // that the naming class has to be derived from the effective
1356 // context.
1357
1358 // Emulate a MSVC bug where the creation of pointer-to-member
1359 // to protected member of base class is allowed but only from
1360 // static member functions.
1361 if (S.getLangOpts().MSVCCompat && !EC.Functions.empty())
1362 if (CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
1363 if (MD->isStatic()) return AR_accessible;
1364
1365 // Despite the standard's confident wording, there is a case
1366 // where you can have an instance member that's neither in a
1367 // pointer-to-member expression nor in a member access: when
1368 // it names a field in an unevaluated context that can't be an
1369 // implicit member. Pending clarification, we just apply the
1370 // same naming-class restriction here.
1371 // FIXME: we're probably not correctly adding the
1372 // protected-member restriction when we retroactively convert
1373 // an expression to being evaluated.
1374
1375 // We know that ECRecord derives from NamingClass. The
1376 // restriction says to check whether NamingClass derives from
1377 // ECRecord, but that's not really necessary: two distinct
1378 // classes can't be recursively derived from each other. So
1379 // along this path, we just need to check whether the classes
1380 // are equal.
1381 if (NamingClass == ECRecord) return AR_accessible;
1382
1383 // Otherwise, this context class tells us nothing; on to the next.
1384 continue;
1385 }
1386
1387 assert(Target.isInstanceMember());
1388
1389 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
1390 if (!InstanceContext) {
1391 OnFailure = AR_dependent;
1392 continue;
1393 }
1394
1395 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
1396 case AR_accessible: return AR_accessible;
1397 case AR_inaccessible: continue;
1398 case AR_dependent: OnFailure = AR_dependent; continue;
1399 }
1400 }
1401 }
1402
1403 // [M3] and [B3] say that, if the target is protected in N, we grant
1404 // access if the access occurs in a friend or member of some class P
1405 // that's a subclass of N and where the target has some natural
1406 // access in P. The 'member' aspect is easy to handle because P
1407 // would necessarily be one of the effective-context records, and we
1408 // address that above. The 'friend' aspect is completely ridiculous
1409 // to implement because there are no restrictions at all on P
1410 // *unless* the [class.protected] restriction applies. If it does,
1411 // however, we should ignore whether the naming class is a friend,
1412 // and instead rely on whether any potential P is a friend.
1413 if (Access == AS_protected && Target.isInstanceMember()) {
1414 // Compute the instance context if possible.
1415 const CXXRecordDecl *InstanceContext = nullptr;
1416 if (Target.hasInstanceContext()) {
1417 InstanceContext = Target.resolveInstanceContext(S);
1418 if (!InstanceContext) return AR_dependent;
1419 }
1420
1421 switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass,
1422 FailedTSC)) {
1423 case AR_accessible: return AR_accessible;
1424 case AR_inaccessible: return OnFailure;
1425 case AR_dependent: return AR_dependent;
1426 }
1427 llvm_unreachable("impossible friendship kind");
1428 }
1429
1430 switch (GetFriendKind(S, EC, NamingClass, FailedTSC)) {
1431 case AR_accessible: return AR_accessible;
1432 case AR_inaccessible: return OnFailure;
1433 case AR_dependent: return AR_dependent;
1434 }
1435
1436 // Silence bogus warnings
1437 llvm_unreachable("impossible friendship kind");
1438}
1439
1440/// Finds the best path from the naming class to the declaring class,
1441/// taking friend declarations into account.
1442///
1443/// C++0x [class.access.base]p5:
1444/// A member m is accessible at the point R when named in class N if
1445/// [M1] m as a member of N is public, or
1446/// [M2] m as a member of N is private, and R occurs in a member or
1447/// friend of class N, or
1448/// [M3] m as a member of N is protected, and R occurs in a member or
1449/// friend of class N, or in a member or friend of a class P
1450/// derived from N, where m as a member of P is public, private,
1451/// or protected, or
1452/// [M4] there exists a base class B of N that is accessible at R, and
1453/// m is accessible at R when named in class B.
1454///
1455/// C++0x [class.access.base]p4:
1456/// A base class B of N is accessible at R, if
1457/// [B1] an invented public member of B would be a public member of N, or
1458/// [B2] R occurs in a member or friend of class N, and an invented public
1459/// member of B would be a private or protected member of N, or
1460/// [B3] R occurs in a member or friend of a class P derived from N, and an
1461/// invented public member of B would be a private or protected member
1462/// of P, or
1463/// [B4] there exists a class S such that B is a base class of S accessible
1464/// at R and S is a base class of N accessible at R.
1465///
1466/// Along a single inheritance path we can restate both of these
1467/// iteratively:
1468///
1469/// First, we note that M1-4 are equivalent to B1-4 if the member is
1470/// treated as a notional base of its declaring class with inheritance
1471/// access equivalent to the member's access. Therefore we need only
1472/// ask whether a class B is accessible from a class N in context R.
1473///
1474/// Let B_1 .. B_n be the inheritance path in question (i.e. where
1475/// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
1476/// B_i). For i in 1..n, we will calculate ACAB(i), the access to the
1477/// closest accessible base in the path:
1478/// Access(a, b) = (* access on the base specifier from a to b *)
1479/// Merge(a, forbidden) = forbidden
1480/// Merge(a, private) = forbidden
1481/// Merge(a, b) = min(a,b)
1482/// Accessible(c, forbidden) = false
1483/// Accessible(c, private) = (R is c) || IsFriend(c, R)
1484/// Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
1485/// Accessible(c, public) = true
1486/// ACAB(n) = public
1487/// ACAB(i) =
1488/// let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
1489/// if Accessible(B_i, AccessToBase) then public else AccessToBase
1490///
1491/// B is an accessible base of N at R iff ACAB(1) = public.
1492///
1493/// \param FinalAccess the access of the "final step", or AS_public if
1494/// there is no final step.
1495/// \return null if friendship is dependent
1497 const EffectiveContext &EC,
1498 AccessTarget &Target,
1499 AccessSpecifier FinalAccess,
1500 CXXBasePaths &Paths) {
1501 // Derive the paths to the desired base.
1502 const CXXRecordDecl *Derived = Target.getNamingClass();
1503 const CXXRecordDecl *Base = Target.getDeclaringClass();
1504
1505 // FIXME: fail correctly when there are dependent paths.
1506 bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
1507 Paths);
1508 assert(isDerived && "derived class not actually derived from base");
1509 (void) isDerived;
1510
1511 CXXBasePath *BestPath = nullptr;
1512
1513 assert(FinalAccess != AS_none && "forbidden access after declaring class");
1514
1515 bool AnyDependent = false;
1516
1517 // Derive the friend-modified access along each path.
1518 for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
1519 PI != PE; ++PI) {
1520 AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
1521
1522 // Walk through the path backwards.
1523 AccessSpecifier PathAccess = FinalAccess;
1524 CXXBasePath::iterator I = PI->end(), E = PI->begin();
1525 while (I != E) {
1526 --I;
1527
1528 assert(PathAccess != AS_none);
1529
1530 // If the declaration is a private member of a base class, there
1531 // is no level of friendship in derived classes that can make it
1532 // accessible.
1533 if (PathAccess == AS_private) {
1534 PathAccess = AS_none;
1535 break;
1536 }
1537
1538 const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
1539
1540 AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
1541 PathAccess = std::max(PathAccess, BaseAccess);
1542
1543 switch (HasAccess(S, EC, NC, PathAccess, Target,
1544 /*FailedTSC=*/nullptr)) {
1545 case AR_inaccessible: break;
1546 case AR_accessible:
1547 PathAccess = AS_public;
1548
1549 // Future tests are not against members and so do not have
1550 // instance context.
1551 Target.suppressInstanceContext();
1552 break;
1553 case AR_dependent:
1554 AnyDependent = true;
1555 goto Next;
1556 }
1557 }
1558
1559 // Note that we modify the path's Access field to the
1560 // friend-modified access.
1561 if (BestPath == nullptr || PathAccess < BestPath->Access) {
1562 BestPath = &*PI;
1563 BestPath->Access = PathAccess;
1564
1565 // Short-circuit if we found a public path.
1566 if (BestPath->Access == AS_public)
1567 return BestPath;
1568 }
1569
1570 Next: ;
1571 }
1572
1573 assert((!BestPath || BestPath->Access != AS_public) &&
1574 "fell out of loop with public path");
1575
1576 // We didn't find a public path, but at least one path was subject
1577 // to dependent friendship, so delay the check.
1578 if (AnyDependent)
1579 return nullptr;
1580
1581 return BestPath;
1582}
1583
1584/// Given that an entity has protected natural access, check whether
1585/// access might be denied because of the protected member access
1586/// restriction.
1587///
1588/// \return true if a note was emitted
1589static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
1590 AccessTarget &Target) {
1591 // Only applies to instance accesses.
1592 if (!Target.isInstanceMember())
1593 return false;
1594
1595 assert(Target.isMemberAccess());
1596
1597 const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass();
1598
1599 for (EffectiveContext::record_iterator
1600 I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1601 const CXXRecordDecl *ECRecord = *I;
1602 switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
1603 case AR_accessible: break;
1604 case AR_inaccessible: continue;
1605 case AR_dependent: continue;
1606 }
1607
1608 // The effective context is a subclass of the declaring class.
1609 // Check whether the [class.protected] restriction is limiting
1610 // access.
1611
1612 // To get this exactly right, this might need to be checked more
1613 // holistically; it's not necessarily the case that gaining
1614 // access here would grant us access overall.
1615
1616 NamedDecl *D = Target.getTargetDecl();
1617
1618 // If we don't have an instance context, [class.protected] says the
1619 // naming class has to equal the context class.
1620 if (!Target.hasInstanceContext()) {
1621 // If it does, the restriction doesn't apply.
1622 if (NamingClass == ECRecord) continue;
1623
1624 // TODO: it would be great to have a fixit here, since this is
1625 // such an obvious error.
1626 S.Diag(D->getLocation(), diag::note_access_protected_restricted_noobject)
1627 << S.Context.getCanonicalTagType(ECRecord);
1628 return true;
1629 }
1630
1631 const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
1632 assert(InstanceContext && "diagnosing dependent access");
1633
1634 switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
1635 case AR_accessible: continue;
1636 case AR_dependent: continue;
1637 case AR_inaccessible:
1638 break;
1639 }
1640
1641 // Okay, the restriction seems to be what's limiting us.
1642
1643 // Use a special diagnostic for constructors and destructors.
1647 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1648 return S.Diag(D->getLocation(),
1649 diag::note_access_protected_restricted_ctordtor)
1651 }
1652
1653 // Otherwise, use the generic diagnostic.
1654 return S.Diag(D->getLocation(),
1655 diag::note_access_protected_restricted_object)
1656 << S.Context.getCanonicalTagType(ECRecord);
1657 }
1658
1659 return false;
1660}
1661
1662/// We are unable to access a given declaration due to its direct
1663/// access control; diagnose that.
1665 const EffectiveContext &EC,
1666 AccessTarget &entity) {
1667 assert(entity.isMemberAccess());
1668 NamedDecl *D = entity.getTargetDecl();
1669
1670 if (D->getAccess() == AS_protected &&
1671 TryDiagnoseProtectedAccess(S, EC, entity))
1672 return;
1673
1674 // Find an original declaration.
1675 while (D->isOutOfLine()) {
1676 NamedDecl *PrevDecl = nullptr;
1677 if (VarDecl *VD = dyn_cast<VarDecl>(D))
1678 PrevDecl = VD->getPreviousDecl();
1679 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1680 PrevDecl = FD->getPreviousDecl();
1681 else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
1682 PrevDecl = TND->getPreviousDecl();
1683 else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
1684 if (const auto *RD = dyn_cast<CXXRecordDecl>(TD);
1685 RD && RD->isInjectedClassName())
1686 break;
1687 PrevDecl = TD->getPreviousDecl();
1688 }
1689 if (!PrevDecl) break;
1690 D = PrevDecl;
1691 }
1692
1693 CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
1694 Decl *ImmediateChild;
1695 if (D->getDeclContext() == DeclaringClass)
1696 ImmediateChild = D;
1697 else {
1698 DeclContext *DC = D->getDeclContext();
1699 while (DC->getParent() != DeclaringClass)
1700 DC = DC->getParent();
1701 ImmediateChild = cast<Decl>(DC);
1702 }
1703
1704 // Check whether there's an AccessSpecDecl preceding this in the
1705 // chain of the DeclContext.
1706 bool isImplicit = true;
1707 for (const auto *I : DeclaringClass->decls()) {
1708 if (I == ImmediateChild) break;
1709 if (isa<AccessSpecDecl>(I)) {
1710 isImplicit = false;
1711 break;
1712 }
1713 }
1714
1715 S.Diag(D->getLocation(), diag::note_access_natural)
1716 << (unsigned) (D->getAccess() == AS_protected)
1717 << isImplicit;
1718}
1719
1720/// Diagnose the path which caused the given declaration or base class
1721/// to become inaccessible.
1723 const EffectiveContext &EC,
1724 AccessTarget &entity) {
1725 // Save the instance context to preserve invariants.
1726 AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1727
1728 // This basically repeats the main algorithm but keeps some more
1729 // information.
1730
1731 // The natural access so far.
1732 AccessSpecifier accessSoFar = AS_public;
1733
1734 // Check whether we have special rights to the declaring class.
1735 if (entity.isMemberAccess()) {
1736 NamedDecl *D = entity.getTargetDecl();
1737 accessSoFar = D->getAccess();
1738 const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1739
1740 switch (HasAccess(S, EC, declaringClass, accessSoFar, entity,
1741 /*FailedTSC=*/nullptr)) {
1742 // If the declaration is accessible when named in its declaring
1743 // class, then we must be constrained by the path.
1744 case AR_accessible:
1745 accessSoFar = AS_public;
1746 entity.suppressInstanceContext();
1747 break;
1748
1749 case AR_inaccessible:
1750 if (accessSoFar == AS_private ||
1751 declaringClass == entity.getEffectiveNamingClass())
1752 return diagnoseBadDirectAccess(S, EC, entity);
1753 break;
1754
1755 case AR_dependent:
1756 llvm_unreachable("cannot diagnose dependent access");
1757 }
1758 }
1759
1760 CXXBasePaths paths;
1761 CXXBasePath &path = *FindBestPath(S, EC, entity, accessSoFar, paths);
1762 assert(path.Access != AS_public);
1763
1764 CXXBasePath::iterator i = path.end(), e = path.begin();
1765 CXXBasePath::iterator constrainingBase = i;
1766 while (i != e) {
1767 --i;
1768
1769 assert(accessSoFar != AS_none && accessSoFar != AS_private);
1770
1771 // Is the entity accessible when named in the deriving class, as
1772 // modified by the base specifier?
1773 const CXXRecordDecl *derivingClass = i->Class->getCanonicalDecl();
1774 const CXXBaseSpecifier *base = i->Base;
1775
1776 // If the access to this base is worse than the access we have to
1777 // the declaration, remember it.
1778 AccessSpecifier baseAccess = base->getAccessSpecifier();
1779 if (baseAccess > accessSoFar) {
1780 constrainingBase = i;
1781 accessSoFar = baseAccess;
1782 }
1783
1784 switch (HasAccess(S, EC, derivingClass, accessSoFar, entity,
1785 /*FailedTSC=*/nullptr)) {
1786 case AR_inaccessible: break;
1787 case AR_accessible:
1788 accessSoFar = AS_public;
1789 entity.suppressInstanceContext();
1790 constrainingBase = nullptr;
1791 break;
1792 case AR_dependent:
1793 llvm_unreachable("cannot diagnose dependent access");
1794 }
1795
1796 // If this was private inheritance, but we don't have access to
1797 // the deriving class, we're done.
1798 if (accessSoFar == AS_private) {
1799 assert(baseAccess == AS_private);
1800 assert(constrainingBase == i);
1801 break;
1802 }
1803 }
1804
1805 // If we don't have a constraining base, the access failure must be
1806 // due to the original declaration.
1807 if (constrainingBase == path.end())
1808 return diagnoseBadDirectAccess(S, EC, entity);
1809
1810 // We're constrained by inheritance, but we want to say
1811 // "declared private here" if we're diagnosing a hierarchy
1812 // conversion and this is the final step.
1813 unsigned diagnostic;
1814 if (entity.isMemberAccess() ||
1815 constrainingBase + 1 != path.end()) {
1816 diagnostic = diag::note_access_constrained_by_path;
1817 } else {
1818 diagnostic = diag::note_access_natural;
1819 }
1820
1821 const CXXBaseSpecifier *base = constrainingBase->Base;
1822
1823 S.Diag(base->getSourceRange().getBegin(), diagnostic)
1824 << base->getSourceRange()
1825 << (base->getAccessSpecifier() == AS_protected)
1826 << (base->getAccessSpecifierAsWritten() == AS_none);
1827
1828 if (entity.isMemberAccess())
1829 S.Diag(entity.getTargetDecl()->getLocation(),
1830 diag::note_member_declared_at);
1831}
1832
1834 const EffectiveContext &EC,
1835 AccessTarget &Entity) {
1836 const CXXRecordDecl *NamingClass = Entity.getNamingClass();
1837 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1838 NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr);
1839
1840 S.Diag(Loc, Entity.getDiag())
1841 << (Entity.getAccess() == AS_protected)
1842 << (D ? D->getDeclName() : DeclarationName())
1843 << S.Context.getCanonicalTagType(NamingClass)
1844 << S.Context.getCanonicalTagType(DeclaringClass);
1845 DiagnoseAccessPath(S, EC, Entity);
1846}
1847
1848/// MSVC has a bug where if during an using declaration name lookup,
1849/// the declaration found is unaccessible (private) and that declaration
1850/// was bring into scope via another using declaration whose target
1851/// declaration is accessible (public) then no error is generated.
1852/// Example:
1853/// class A {
1854/// public:
1855/// int f();
1856/// };
1857/// class B : public A {
1858/// private:
1859/// using A::f;
1860/// };
1861/// class C : public B {
1862/// private:
1863/// using B::f;
1864/// };
1865///
1866/// Here, B::f is private so this should fail in Standard C++, but
1867/// because B::f refers to A::f which is public MSVC accepts it.
1869 SourceLocation AccessLoc,
1870 AccessTarget &Entity) {
1871 if (UsingShadowDecl *Shadow =
1872 dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1873 if (UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1874 const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1875 if (Entity.getTargetDecl()->getAccess() == AS_private &&
1876 (OrigDecl->getAccess() == AS_public ||
1877 OrigDecl->getAccess() == AS_protected)) {
1878 S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1879 << UD->getQualifiedNameAsString()
1880 << OrigDecl->getQualifiedNameAsString();
1881 return true;
1882 }
1883 }
1884 return false;
1885}
1886
1887/// Determines whether the accessed entity is accessible. Public members
1888/// have been weeded out by this point.
1889static AccessResult IsAccessible(Sema &S, const EffectiveContext &EC,
1890 AccessTarget &Entity,
1891 TemplateSpecCandidateSet *FailedTSC) {
1892 // Determine the actual naming class.
1893 const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1894
1895 AccessSpecifier UnprivilegedAccess = Entity.getAccess();
1896 assert(UnprivilegedAccess != AS_public && "public access not weeded out");
1897
1898 // Before we try to recalculate access paths, try to white-list
1899 // accesses which just trade in on the final step, i.e. accesses
1900 // which don't require [M4] or [B4]. These are by far the most
1901 // common forms of privileged access.
1902 if (UnprivilegedAccess != AS_none) {
1903 switch (
1904 HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity, FailedTSC)) {
1905 case AR_dependent:
1906 // This is actually an interesting policy decision. We don't
1907 // *have* to delay immediately here: we can do the full access
1908 // calculation in the hope that friendship on some intermediate
1909 // class will make the declaration accessible non-dependently.
1910 // But that's not cheap, and odds are very good (note: assertion
1911 // made without data) that the friend declaration will determine
1912 // access.
1913 return AR_dependent;
1914
1915 case AR_accessible: return AR_accessible;
1916 case AR_inaccessible: break;
1917 }
1918 }
1919
1920 AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1921
1922 // We lower member accesses to base accesses by pretending that the
1923 // member is a base class of its declaring class.
1924 AccessSpecifier FinalAccess;
1925
1926 if (Entity.isMemberAccess()) {
1927 // Determine if the declaration is accessible from EC when named
1928 // in its declaring class.
1929 NamedDecl *Target = Entity.getTargetDecl();
1930 const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1931
1932 FinalAccess = Target->getAccess();
1933 switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity, FailedTSC)) {
1934 case AR_accessible:
1935 // Target is accessible at EC when named in its declaring class.
1936 // We can now hill-climb and simply check whether the declaring
1937 // class is accessible as a base of the naming class. This is
1938 // equivalent to checking the access of a notional public
1939 // member with no instance context.
1940 FinalAccess = AS_public;
1941 Entity.suppressInstanceContext();
1942 break;
1943 case AR_inaccessible: break;
1944 case AR_dependent: return AR_dependent; // see above
1945 }
1946
1947 if (DeclaringClass == NamingClass)
1948 return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
1949 } else {
1950 FinalAccess = AS_public;
1951 }
1952
1953 assert(Entity.getDeclaringClass() != NamingClass);
1954
1955 // Append the declaration's access if applicable.
1956 CXXBasePaths Paths;
1957 CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
1958 if (!Path)
1959 return AR_dependent;
1960
1961 assert(Path->Access <= UnprivilegedAccess &&
1962 "access along best path worse than direct?");
1963 if (Path->Access == AS_public)
1964 return AR_accessible;
1965 return AR_inaccessible;
1966}
1967
1969 const EffectiveContext &EC,
1970 SourceLocation Loc,
1971 const AccessTarget &Entity) {
1972 assert(EC.isDependent() && "delaying non-dependent access");
1973 DeclContext *DC = EC.getInnerContext();
1974 assert(DC->isDependentContext() && "delaying non-dependent access");
1976 Loc,
1977 Entity.isMemberAccess(),
1978 Entity.getAccess(),
1979 Entity.getTargetDecl(),
1980 Entity.getNamingClass(),
1981 Entity.getBaseObjectType(),
1982 Entity.getDiag());
1983}
1984
1985static AccessResult CheckEffectiveAccess(Sema &S, const EffectiveContext &EC,
1986 SourceLocation Loc,
1987 AccessTarget &Entity,
1988 TemplateSpecCandidateSet *FailedTSC) {
1989 assert((Entity.isQuiet() || FailedTSC) &&
1990 "non-quiet access check requires a candidate set");
1991
1992 switch (IsAccessible(S, EC, Entity, FailedTSC)) {
1993 case AR_dependent:
1994 DelayDependentAccess(S, EC, Loc, Entity);
1995 return AR_dependent;
1996
1997 case AR_inaccessible: {
1998 if (S.getLangOpts().MSVCCompat &&
2000 return AR_accessible;
2001
2002 if (Entity.isQuiet())
2003 return AR_inaccessible;
2004
2005 DiagnoseBadAccess(S, Loc, EC, Entity);
2006 FailedTSC->NoteCandidates(S, Loc);
2007 return AR_inaccessible;
2008 }
2009
2010 case AR_accessible:
2011 return AR_accessible;
2012 }
2013
2014 // silence unnecessary warning
2015 llvm_unreachable("invalid access result");
2016}
2017
2018static AccessResult CheckEffectiveAccess(Sema &S, const EffectiveContext &EC,
2019 SourceLocation Loc,
2020 AccessTarget &Entity) {
2021 assert(Entity.getAccess() != AS_public && "called for public access!");
2022
2023 if (Entity.isQuiet())
2024 return CheckEffectiveAccess(S, EC, Loc, Entity, /*FailedTSC=*/nullptr);
2025
2026 TemplateSpecCandidateSet FailedTSC(
2027 Loc, /*ForTakingAddress=*/false,
2029 return CheckEffectiveAccess(S, EC, Loc, Entity, &FailedTSC);
2030}
2031
2033 AccessTarget &Entity) {
2034 // If the access path is public, it's accessible everywhere.
2035 if (Entity.getAccess() == AS_public)
2036 return Sema::AR_accessible;
2037
2038 // If we're currently parsing a declaration, we may need to delay
2039 // access control checking, because our effective context might be
2040 // different based on what the declaration comes out as.
2041 //
2042 // For example, we might be parsing a declaration with a scope
2043 // specifier, like this:
2044 // A::private_type A::foo() { ... }
2045 //
2046 // friend declaration should not be delayed because it may lead to incorrect
2047 // redeclaration chain, such as:
2048 // class D {
2049 // class E{
2050 // class F{};
2051 // friend void foo(D::E::F& q);
2052 // };
2053 // friend void foo(D::E::F& q);
2054 // };
2056 // [class.friend]p9:
2057 // A member nominated by a friend declaration shall be accessible in the
2058 // class containing the friend declaration. The meaning of the friend
2059 // declaration is the same whether the friend declaration appears in the
2060 // private, protected, or public ([class.mem]) portion of the class
2061 // member-specification.
2062 Scope *TS = S.getCurScope();
2063 bool IsFriendDeclaration = false;
2064 while (TS && !IsFriendDeclaration) {
2065 IsFriendDeclaration = TS->isFriendScope();
2066 TS = TS->getParent();
2067 }
2068 if (!IsFriendDeclaration) {
2070 return Sema::AR_delayed;
2071 }
2072 }
2073
2074 EffectiveContext EC(S.CurContext);
2075 switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
2078 case AR_dependent: return Sema::AR_dependent;
2079 }
2080 llvm_unreachable("invalid access result");
2081}
2082
2084 // Access control for names used in the declarations of functions
2085 // and function templates should normally be evaluated in the context
2086 // of the declaration, just in case it's a friend of something.
2087 // However, this does not apply to local extern declarations.
2088
2089 DeclContext *DC = D->getDeclContext();
2090 if (D->isLocalExternDecl()) {
2091 DC = D->getLexicalDeclContext();
2092 } else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
2093 DC = FN;
2094 } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
2095 if (auto *D = dyn_cast_if_present<DeclContext>(TD->getTemplatedDecl()))
2096 DC = D;
2097 } else if (auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
2098 DC = RD;
2099 }
2100
2101 EffectiveContext EC(DC);
2102
2103 AccessTarget Target(DD.getAccessData());
2104
2105 if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
2106 DD.Triggered = true;
2107}
2108
2110 const MultiLevelTemplateArgumentList &TemplateArgs) {
2111 SourceLocation Loc = DD.getAccessLoc();
2112 AccessSpecifier Access = DD.getAccess();
2113
2114 Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
2115 TemplateArgs);
2116 if (!NamingD) return;
2117 Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
2118 TemplateArgs);
2119 if (!TargetD) return;
2120
2121 if (DD.isAccessToMember()) {
2122 CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
2123 NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
2124 QualType BaseObjectType = DD.getAccessBaseObjectType();
2125 if (!BaseObjectType.isNull()) {
2126 BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
2127 DeclarationName());
2128 if (BaseObjectType.isNull()) return;
2129 }
2130
2131 AccessTarget Entity(Context,
2132 AccessTarget::Member,
2133 NamingClass,
2134 DeclAccessPair::make(TargetDecl, Access),
2135 BaseObjectType);
2136 Entity.setDiag(DD.getDiagnostic());
2137 CheckAccess(*this, Loc, Entity);
2138 } else {
2139 AccessTarget Entity(Context,
2140 AccessTarget::Base,
2141 cast<CXXRecordDecl>(TargetD),
2142 cast<CXXRecordDecl>(NamingD),
2143 Access);
2144 Entity.setDiag(DD.getDiagnostic());
2145 CheckAccess(*this, Loc, Entity);
2146 }
2147}
2148
2151 if (!getLangOpts().AccessControl ||
2152 !E->getNamingClass() ||
2153 Found.getAccess() == AS_public)
2154 return AR_accessible;
2155
2156 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
2157 Found, QualType());
2158 Entity.setDiag(diag::err_access) << E->getSourceRange();
2159
2160 return CheckAccess(*this, E->getNameLoc(), Entity);
2161}
2162
2165 if (!getLangOpts().AccessControl ||
2166 Found.getAccess() == AS_public)
2167 return AR_accessible;
2168
2169 QualType BaseType = E->getBaseType();
2170 if (E->isArrow())
2171 BaseType = BaseType->castAs<PointerType>()->getPointeeType();
2172
2173 AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
2174 Found, BaseType);
2175 Entity.setDiag(diag::err_access) << E->getSourceRange();
2176
2177 return CheckAccess(*this, E->getMemberLoc(), Entity);
2178}
2179
2182 QualType ObjectType,
2183 SourceLocation Loc,
2184 const PartialDiagnostic &Diag) {
2185 // Fast path.
2186 if (Found.getAccess() == AS_public || !getLangOpts().AccessControl)
2187 return true;
2188
2189 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
2190 ObjectType);
2191
2192 // Suppress diagnostics.
2193 Entity.setDiag(Diag);
2194
2195 // We don't want to delay access checking even we are inside an enclosing
2196 // delayed-diagnostics scope (e.g. when parsing a later declaration whose
2197 // initializer requires explaining why a defaulted comparison operator is
2198 // deleted)
2199 llvm::scope_exit UndelayDiags(
2200 [&, CurrentState(DelayedDiagnostics.pushUndelayed())] {
2201 DelayedDiagnostics.popUndelayed(CurrentState);
2202 });
2203
2204 switch (CheckAccess(*this, Loc, Entity)) {
2205 case AR_accessible: return true;
2206 case AR_inaccessible: return false;
2207 case AR_dependent: llvm_unreachable("dependent for =delete computation");
2208 case AR_delayed: llvm_unreachable("cannot delay =delete computation");
2209 }
2210 llvm_unreachable("bad access result");
2211}
2212
2214 CXXDestructorDecl *Dtor,
2215 const PartialDiagnostic &PDiag,
2216 QualType ObjectTy) {
2217 if (!getLangOpts().AccessControl)
2218 return AR_accessible;
2219
2220 // There's never a path involved when checking implicit destructor access.
2221 AccessSpecifier Access = Dtor->getAccess();
2222 if (Access == AS_public)
2223 return AR_accessible;
2224
2225 CXXRecordDecl *NamingClass = Dtor->getParent();
2226 if (ObjectTy.isNull())
2227 ObjectTy = Context.getCanonicalTagType(NamingClass);
2228
2229 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
2230 DeclAccessPair::make(Dtor, Access),
2231 ObjectTy);
2232 Entity.setDiag(PDiag); // TODO: avoid copy
2233
2234 return CheckAccess(*this, Loc, Entity);
2235}
2236
2240 const InitializedEntity &Entity,
2241 bool IsCopyBindingRefToTemp) {
2242 if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
2243 return AR_accessible;
2244
2246 switch (Entity.getKind()) {
2247 default:
2248 PD = PDiag(IsCopyBindingRefToTemp
2249 ? diag::ext_rvalue_to_reference_access_ctor
2250 : diag::err_access_ctor);
2251
2252 break;
2253
2255 PD = PDiag(diag::err_access_base_ctor);
2256 PD << Entity.isInheritedVirtualBase()
2257 << Entity.getBaseSpecifier()->getType()
2258 << Constructor->getSpecialMemberKind();
2259 break;
2260
2263 const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
2264 PD = PDiag(diag::err_access_field_ctor);
2265 PD << Field->getType() << Constructor->getSpecialMemberKind();
2266 break;
2267 }
2268
2270 StringRef VarName = Entity.getCapturedVarName();
2271 PD = PDiag(diag::err_access_lambda_capture);
2272 PD << VarName << Entity.getType() << Constructor->getSpecialMemberKind();
2273 break;
2274 }
2275
2276 }
2277
2278 return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD);
2279}
2280
2284 const InitializedEntity &Entity,
2285 const PartialDiagnostic &PD) {
2286 if (!getLangOpts().AccessControl ||
2287 Found.getAccess() == AS_public)
2288 return AR_accessible;
2289
2290 CXXRecordDecl *NamingClass = Constructor->getParent();
2291
2292 // Initializing a base sub-object is an instance method call on an
2293 // object of the derived class. Otherwise, we have an instance method
2294 // call on an object of the constructed type.
2295 //
2296 // FIXME: If we have a parent, we're initializing the base class subobject
2297 // in aggregate initialization. It's not clear whether the object class
2298 // should be the base class or the derived class in that case.
2299 CXXRecordDecl *ObjectClass;
2300 if ((Entity.getKind() == InitializedEntity::EK_Base ||
2302 !Entity.getParent()) {
2303 ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
2304 } else if (auto *Shadow =
2305 dyn_cast<ConstructorUsingShadowDecl>(Found.getDecl())) {
2306 // If we're using an inheriting constructor to construct an object,
2307 // the object class is the derived class, not the base class.
2308 ObjectClass = Shadow->getParent();
2309 } else {
2310 ObjectClass = NamingClass;
2311 }
2312
2313 AccessTarget AccessEntity(
2314 Context, AccessTarget::Member, NamingClass,
2316 Context.getCanonicalTagType(ObjectClass));
2317 AccessEntity.setDiag(PD);
2318
2319 return CheckAccess(*this, UseLoc, AccessEntity);
2320}
2321
2323 SourceRange PlacementRange,
2324 CXXRecordDecl *NamingClass,
2326 bool Diagnose) {
2327 if (!getLangOpts().AccessControl ||
2328 !NamingClass ||
2329 Found.getAccess() == AS_public)
2330 return AR_accessible;
2331
2332 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
2333 QualType());
2334 if (Diagnose)
2335 Entity.setDiag(diag::err_access)
2336 << PlacementRange;
2337
2338 return CheckAccess(*this, OpLoc, Entity);
2339}
2340
2342 CXXRecordDecl *NamingClass,
2344 if (!getLangOpts().AccessControl ||
2345 !NamingClass ||
2346 Found.getAccess() == AS_public)
2347 return AR_accessible;
2348
2349 AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
2350 Found, QualType());
2351
2352 return CheckAccess(*this, UseLoc, Entity);
2353}
2354
2357 CXXRecordDecl *DecomposedClass,
2358 DeclAccessPair Field) {
2359 if (!getLangOpts().AccessControl ||
2360 Field.getAccess() == AS_public)
2361 return AR_accessible;
2362
2363 AccessTarget Entity(Context, AccessTarget::Member, DecomposedClass, Field,
2364 Context.getCanonicalTagType(DecomposedClass));
2365 Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
2366
2367 return CheckAccess(*this, UseLoc, Entity);
2368}
2369
2371 Expr *ObjectExpr,
2372 const SourceRange &Range,
2374 if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
2375 return AR_accessible;
2376
2377 auto *NamingClass = ObjectExpr->getType()->castAsCXXRecordDecl();
2378 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
2379 ObjectExpr->getType());
2380 Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << Range;
2381
2382 return CheckAccess(*this, OpLoc, Entity);
2383}
2384
2386 Expr *ObjectExpr,
2387 Expr *ArgExpr,
2390 OpLoc, ObjectExpr, ArgExpr ? ArgExpr->getSourceRange() : SourceRange(),
2391 Found);
2392}
2393
2395 Expr *ObjectExpr,
2396 ArrayRef<Expr *> ArgExprs,
2397 DeclAccessPair FoundDecl) {
2398 SourceRange R;
2399 if (!ArgExprs.empty()) {
2400 R = SourceRange(ArgExprs.front()->getBeginLoc(),
2401 ArgExprs.back()->getEndLoc());
2402 }
2403
2404 return CheckMemberOperatorAccess(OpLoc, ObjectExpr, R, FoundDecl);
2405}
2406
2408 assert(isa<CXXMethodDecl>(target->getAsFunction()));
2409
2410 // Friendship lookup is a redeclaration lookup, so there's never an
2411 // inheritance path modifying access.
2412 AccessSpecifier access = target->getAccess();
2413
2414 if (!getLangOpts().AccessControl || access == AS_public)
2415 return AR_accessible;
2416
2417 CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
2418
2419 AccessTarget entity(Context, AccessTarget::Member,
2421 DeclAccessPair::make(target, access),
2422 /*no instance context*/ QualType());
2423 entity.setDiag(diag::err_access_friend_function)
2424 << (method->getQualifier() ? method->getQualifierLoc().getSourceRange()
2425 : method->getNameInfo().getSourceRange());
2426
2427 // We need to bypass delayed-diagnostics because we might be called
2428 // while the ParsingDeclarator is active.
2429 EffectiveContext EC(CurContext);
2430 switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
2431 case ::AR_accessible: return Sema::AR_accessible;
2432 case ::AR_inaccessible: return Sema::AR_inaccessible;
2433 case ::AR_dependent: return Sema::AR_dependent;
2434 }
2435 llvm_unreachable("invalid access result");
2436}
2437
2440 if (!getLangOpts().AccessControl ||
2441 Found.getAccess() == AS_none ||
2442 Found.getAccess() == AS_public)
2443 return AR_accessible;
2444
2446 CXXRecordDecl *NamingClass = Ovl->getNamingClass();
2447
2448 AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
2449 /*no instance context*/ QualType());
2450 Entity.setDiag(diag::err_access)
2451 << Ovl->getSourceRange();
2452
2453 return CheckAccess(*this, Ovl->getNameLoc(), Entity);
2454}
2455
2457 SourceLocation AccessLoc, CXXRecordDecl *Base, CXXRecordDecl *Derived,
2458 const CXXBasePath &Path, unsigned DiagID,
2459 llvm::function_ref<void(PartialDiagnostic &)> SetupPDiag, bool ForceCheck,
2460 bool ForceUnprivileged) {
2461 if (!ForceCheck && !getLangOpts().AccessControl)
2462 return AR_accessible;
2463
2464 if (Path.Access == AS_public)
2465 return AR_accessible;
2466
2467 AccessTarget Entity(Context, AccessTarget::Base, Base, Derived, Path.Access);
2468 if (DiagID)
2469 SetupPDiag(Entity.setDiag(DiagID));
2470
2471 if (ForceUnprivileged) {
2472 switch (
2473 CheckEffectiveAccess(*this, EffectiveContext(), AccessLoc, Entity)) {
2474 case ::AR_accessible:
2475 return Sema::AR_accessible;
2476 case ::AR_inaccessible:
2477 return Sema::AR_inaccessible;
2478 case ::AR_dependent:
2479 return Sema::AR_dependent;
2480 }
2481 llvm_unreachable("unexpected result from CheckEffectiveAccess");
2482 }
2483 return CheckAccess(*this, AccessLoc, Entity);
2484}
2485
2487 QualType Base, QualType Derived,
2488 const CXXBasePath &Path,
2489 unsigned DiagID, bool ForceCheck,
2490 bool ForceUnprivileged) {
2491 return CheckBaseClassAccess(
2492 AccessLoc, Base->getAsCXXRecordDecl(), Derived->getAsCXXRecordDecl(),
2493 Path, DiagID, [&](PartialDiagnostic &PD) { PD << Derived << Base; },
2494 ForceCheck, ForceUnprivileged);
2495}
2496
2498 assert(getLangOpts().AccessControl
2499 && "performing access check without access control");
2500 assert(R.getNamingClass() && "performing access check without naming class");
2501
2502 for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
2503 if (I.getAccess() != AS_public) {
2504 AccessTarget Entity(Context, AccessedEntity::Member,
2505 R.getNamingClass(), I.getPair(),
2506 R.getBaseObjectType());
2507 Entity.setDiag(diag::err_access);
2508 CheckAccess(*this, R.getNameLoc(), Entity);
2509 }
2510 }
2511}
2512
2514 QualType BaseType) {
2515 // Perform the C++ accessibility checks first.
2516 if (Target->isCXXClassMember() && NamingClass) {
2517 if (!getLangOpts().CPlusPlus)
2518 return false;
2519 // The unprivileged access is AS_none as we don't know how the member was
2520 // accessed, which is described by the access in DeclAccessPair.
2521 // `IsAccessible` will examine the actual access of Target (i.e.
2522 // Decl->getAccess()) when calculating the access.
2523 AccessTarget Entity(Context, AccessedEntity::Member, NamingClass,
2524 DeclAccessPair::make(Target, AS_none), BaseType);
2525 EffectiveContext EC(CurContext);
2526 return ::IsAccessible(*this, EC, Entity, /*FailedTSC=*/nullptr) !=
2528 }
2529
2530 if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Target)) {
2531 // @public and @package ivars are always accessible.
2532 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public ||
2533 Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package)
2534 return true;
2535
2536 // If we are inside a class or category implementation, determine the
2537 // interface we're in.
2538 ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
2539 if (ObjCMethodDecl *MD = getCurMethodDecl())
2540 ClassOfMethodDecl = MD->getClassInterface();
2541 else if (FunctionDecl *FD = getCurFunctionDecl()) {
2542 if (ObjCImplDecl *Impl
2543 = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
2544 if (ObjCImplementationDecl *IMPD
2545 = dyn_cast<ObjCImplementationDecl>(Impl))
2546 ClassOfMethodDecl = IMPD->getClassInterface();
2547 else if (ObjCCategoryImplDecl* CatImplClass
2548 = dyn_cast<ObjCCategoryImplDecl>(Impl))
2549 ClassOfMethodDecl = CatImplClass->getClassInterface();
2550 }
2551 }
2552
2553 // If we're not in an interface, this ivar is inaccessible.
2554 if (!ClassOfMethodDecl)
2555 return false;
2556
2557 // If we're inside the same interface that owns the ivar, we're fine.
2558 if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))
2559 return true;
2560
2561 // If the ivar is private, it's inaccessible.
2562 if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private)
2563 return false;
2564
2565 return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);
2566 }
2567
2568 return true;
2569}
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.
FormatToken * Next
The next token in the unwrapped line.
Result
Implement __builtin_bit_cast and related operations.
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 AccessResult CheckEffectiveAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, AccessTarget &Entity, TemplateSpecCandidateSet *FailedTSC)
static bool HasSameFunctionType(Sema &S, QualType FriendType, QualType ContextType, SourceLocation Loc)
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc, const EffectiveContext &EC, AccessTarget &Entity)
static AccessResult HasAccess(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *NamingClass, AccessSpecifier Access, const AccessTarget &Target, TemplateSpecCandidateSet *FailedTSC)
AccessResult
A copy of Sema's enum without AR_delayed.
@ AR_accessible
@ AR_dependent
@ AR_inaccessible
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.
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 ClassTemplateDecl * GetClassTemplatePattern(ClassTemplateDecl *CTD)
static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc, AccessTarget &Entity)
static AccessResult DeduceTemplateArguments(Sema &S, FriendTemplateDecl *FTD, DeclContext *DC, const TemplateSpecializationType *TST, ArrayRef< TemplateParameterList * > TPLs, TemplateSpecCandidateSet *FailedTSC, MultiLevelTemplateArgumentList &DeducedArgs)
static ClassTemplateDecl * GetClassTemplateDecl(CXXRecordDecl *RD)
static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Friend)
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...
static AccessResult IsAccessible(Sema &S, const EffectiveContext &EC, AccessTarget &Entity, TemplateSpecCandidateSet *FailedTSC)
Determines whether the accessed entity is accessible.
static FunctionTemplateDecl * TryGetFunctionTemplateDecl(FunctionDecl *FD)
static TemplateParameterList * SubstTemplateParameterList(Sema &S, TemplateParameterList *TPL, DeclContext *DC, const MultiLevelTemplateArgumentList &Args)
static const TemplateSpecializationType * GetQualifierClassTemplateSpecializationType(ASTContext &Context, NestedNameSpecifier NNS)
static CanQual< FunctionProtoType > GetCanonicalFunctionProto(ASTContext &Context, QualType Ty)
static bool MightInstantiateTo(const CXXRecordDecl *From, const CXXRecordDecl *To)
Checks whether one class might instantiate to the other.
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 AccessResult GetFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Class, TemplateSpecCandidateSet *FailedTSC)
static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *InstanceContext, const CXXRecordDecl *NamingClass, TemplateSpecCandidateSet *FailedTSC)
Search for a class P that EC is a friend of, under the constraint InstanceContext <= P if InstanceCon...
static CXXRecordDecl * FindDeclaringClass(NamedDecl *D)
static void DelayDependentAccess(Sema &S, const EffectiveContext &EC, SourceLocation Loc, const AccessTarget &Entity)
Defines various enumerations that describe declaration and type specifiers.
static QualType getPointeeType(const MemRegion *R)
MultiLevelTemplateArgumentList & getDeducedArgs()
FriendTemplateMatchContext(Sema &S, FriendTemplateDecl *FTD)
AccessResult getAccessResult() const
AccessResult deduce(DeclContext *DC, const TemplateSpecializationType *TST, ArrayRef< TemplateParameterList * > TPLs, TemplateSpecCandidateSet *FailedTSC)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U) const
Determine whether two function types are the same, ignoring exception specifications in cases where t...
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
CanQualType getCanonicalTagType(const TagDecl *TD) const
PtrTy get() const
Definition Ownership.h:171
bool isUsable() const
Definition Ownership.h:169
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...
paths_iterator begin()
paths_iterator end()
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:2637
Represents a C++ destructor within a class.
Definition DeclCXX.h:2902
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2145
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
base_class_range bases()
Definition DeclCXX.h:608
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition DeclCXX.h:1023
bool hasDefinition() const
Definition DeclCXX.h:561
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
Definition DeclCXX.cpp:2054
bool isInjectedClassName() const
Determines whether this declaration represents the injected class name.
Definition DeclCXX.cpp:2154
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition DeclCXX.h:522
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Represents a canonical, potentially-qualified type.
CanProxy< U > getAs() const
Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.
Declaration of a class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
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:1466
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
bool isFileContext() const
Definition DeclBase.h:2197
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition DeclBase.h:2403
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:1078
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:273
bool isInvalidDecl() const
Definition DeclBase.h:596
bool isLocalExternDecl() const
Determine whether this is a block-scope declaration with linkage.
Definition DeclBase.h:1186
void setAccess(AccessSpecifier AS)
Definition DeclBase.h:510
SourceLocation getLocation() const
Definition DeclBase.h:447
DeclContext * getDeclContext()
Definition DeclBase.h:456
AccessSpecifier getAccess() const
Definition DeclBase.h:515
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition DeclBase.h:935
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:995
The name of a declaration.
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition Decl.h:855
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition Decl.h:845
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Definition Decl.h:837
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:113
QualType getType() const
Definition Expr.h:145
Represents a member of a struct/union/class.
Definition Decl.h:3294
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition DeclFriend.h:46
virtual NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition DeclFriend.h:102
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition DeclFriend.h:96
Declaration of a friend template.
NamedDecl * getFriendDecl() const override
If this friend declaration doesn't name a type, return the inner declaration.
TemplateName getFriendTemplateName() const
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Represents a function declaration or definition.
Definition Decl.h:2058
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4237
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
Definition Decl.cpp:4308
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition Decl.cpp:4357
DeclarationNameInfo getNameInfo() const
Definition Decl.h:2324
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
Definition Decl.cpp:4383
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5421
Declaration of a template function.
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
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.
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.
A stack-allocated class that identifies which local variable declaration instantiations are present i...
Definition Template.h:377
Represents the results of name lookup.
Definition Lookup.h:147
UnresolvedSetImpl::iterator iterator
Definition Lookup.h:154
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:274
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
std::string getQualifiedNameAsString() const
Definition Decl.cpp:1684
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition DeclObjC.h:2551
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition DeclObjC.h:2603
Represents an ObjC class declaration.
Definition DeclObjC.h:1160
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:1816
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1958
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:3142
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
Definition ExprCXX.h:3203
SourceLocation getNameLoc() const
Gets the location of the name.
Definition ExprCXX.h:3255
CXXRecordDecl * getNamingClass()
Gets the naming class of this lookup, if any.
Definition ExprCXX.h:4350
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3408
A (possibly-)qualified type.
Definition TypeBase.h:938
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
Definition Decl.h:4511
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
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:617
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition Scope.h:280
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition SemaBase.cpp:33
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition SemaBase.cpp:61
A RAII object to temporarily push a declaration context.
Definition Sema.h:3532
A class which encapsulates the logic for delaying diagnostics during parsing and other processing.
Definition Sema.h:1384
bool shouldDelayDiagnostics()
Determines whether diagnostics should be delayed.
Definition Sema.h:1396
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
DelayedDiagnosticsState pushUndelayed()
Enter a new scope where access and deprecation diagnostics are not delayed.
Definition Sema.h:1419
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Definition Sema.h:12546
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:863
Scope * getCurScope() const
Retrieve the parser's current scope.
Definition Sema.h:1137
bool SetMemberAccessSpecifier(NamedDecl *MemberDecl, NamedDecl *PrevMemberDecl, AccessSpecifier LexicalAS)
SetMemberAccessSpecifier - Set the access specifier of a member.
NamedDecl * FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, const MultiLevelTemplateArgumentList &TemplateArgs, bool FindingInstantiatedContext=false)
Find the instantiation of the given declaration within the current instantiation.
TypeSourceInfo * SubstFriendType(TypeSourceInfo *TSI, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity)
AccessResult CheckFriendAccess(NamedDecl *D)
Checks access to the target of a friend declaration.
bool TemplateParameterListsAreEqual(const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc=SourceLocation())
Determine whether the given template parameter lists are equivalent.
@ AR_dependent
Definition Sema.h:1690
@ AR_accessible
Definition Sema.h:1688
@ AR_inaccessible
Definition Sema.h:1689
@ AR_delayed
Definition Sema.h:1691
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:1768
ASTContext & Context
Definition Sema.h:1304
AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType=QualType())
ExprResult SubstConstraintExprWithoutSatisfaction(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
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)
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
Definition Sema.cpp:1773
void HandleDependentAccessCheck(const DependentDiagnostic &DD, const MultiLevelTemplateArgumentList &TemplateArgs)
@ TPL_TemplateMatch
We are matching the template parameter lists of two templates that might be redeclarations.
Definition Sema.h:12244
const LangOptions & getLangOpts() const
Definition Sema.h:928
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.
bool AreConstraintExpressionsEqual(const NamedDecl *Old, const Expr *OldConstr, const TemplateCompareNewDeclInfo &New, const Expr *NewConstr)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition Sema.h:1444
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.
TemplateParameterList * SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs, bool EvaluateConstraints=true)
AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E, DeclAccessPair FoundDecl)
bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New)
AccessResult CheckMemberAccess(SourceLocation UseLoc, CXXRecordDecl *NamingClass, DeclAccessPair Found)
Checks access to a member.
TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)
void HandleDelayedAccessCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
Definition Sema.h:6446
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:343
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3851
bool isUnion() const
Definition Decl.h:4062
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Definition Decl.h:4097
TagKind getTagKind() const
Definition Decl.h:4051
A convenient class for passing around template argument information.
void setLAngleLoc(SourceLocation Loc)
void setRAngleLoc(SourceLocation Loc)
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
bool isNull() const
Determine whether this template name is NULL.
Stores a list of template parameters for a TemplateDecl and its derived classes.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
SourceLocation getRAngleLoc() const
SourceLocation getLAngleLoc() const
ArrayRef< NamedDecl * > asArray()
SourceLocation getTemplateLoc() const
TemplateSpecCandidateSet - A set of generalized overload candidates, used in template specializations...
void NoteCandidates(Sema &S, SourceLocation Loc)
NoteCandidates - When no template specialization match is found, prints diagnostic messages containin...
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition TypeLoc.h:89
A container of type source information.
Definition TypeBase.h:8473
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition TypeLoc.h:267
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8484
const TemplateSpecializationType * getAsNonAliasTemplateSpecializationType() const
Look through sugar for an instance of TemplateSpecializationType which is not a type alias,...
Definition Type.cpp:1996
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
CXXRecordDecl * castAsCXXRecordDecl() const
Definition Type.h:36
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9405
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition TypeBase.h:2859
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9338
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3696
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition ExprCXX.h:3372
CXXRecordDecl * getNamingClass()
Gets the 'naming class' (in the sense of C++0x [class.access.base]p5) of the lookup.
Definition ExprCXX.h:3446
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition ExprCXX.h:4177
QualType getBaseType() const
Definition ExprCXX.h:4259
bool isArrow() const
Determine whether this member expression used the '->' operator; otherwise, it used the '.
Definition ExprCXX.h:4269
CXXRecordDecl * getNamingClass()
Retrieve the naming class of this lookup.
Definition ExprCXX.cpp:1715
SourceLocation getMemberLoc() const
Retrieve the location of the name of the member that this expression refers to.
Definition ExprCXX.h:4289
Represents a C++ using-declaration.
Definition DeclCXX.h:3616
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition DeclCXX.h:3424
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:932
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)
Provides information about an attempted template argument deduction, whose success or failure was des...
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition Specifiers.h:124
@ AS_public
Definition Specifiers.h:125
@ AS_protected
Definition Specifiers.h:126
@ AS_none
Definition Specifiers.h:128
@ AS_private
Definition Specifiers.h:127
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
Definition Parser.h:142
const FunctionProtoType * T
TagTypeKind
The kind of a tag type.
Definition TypeBase.h:6045
@ Union
The "union" keyword.
Definition TypeBase.h:6053
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition DeclBase.h:1305
@ Success
Template argument deduction was successful.
Definition Sema.h:376
U cast(CodeGen::Address addr)
Definition Address.h:327
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
#define false
Definition stdbool.h:26
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
SourceLocation getLAngleLoc() const
ArrayRef< TemplateArgumentLoc > arguments() const
SourceLocation getRAngleLoc() const
bool isNull() const
Definition Decl.h:99
const Expr * ConstraintExpr
Definition Decl.h:88
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.
static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword)
Converts an elaborated type keyword into a TagTypeKind.
Definition Type.cpp:3434
A stack object to be created when performing template instantiation.
Definition Sema.h:13400