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