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