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