ScopeInfo.cpp revision bbff82f302a1dd67589f65912351978905f0c5a7
1a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose//===--- ScopeInfo.cpp - Information about a semantic context -------------===// 2a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// 3a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// The LLVM Compiler Infrastructure 4a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// 5a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// This file is distributed under the University of Illinois Open Source 6a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// License. See LICENSE.TXT for details. 7a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// 8a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose//===----------------------------------------------------------------------===// 9a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// 10a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// This file implements FunctionScopeInfo and its subclasses, which contain 11a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// information about a single function, block, lambda, or method body. 12a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// 13a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose//===----------------------------------------------------------------------===// 14a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 15a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/Sema/ScopeInfo.h" 16a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/AST/Decl.h" 17a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/AST/DeclObjC.h" 18a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/AST/Expr.h" 19a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/AST/ExprCXX.h" 20a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose#include "clang/AST/ExprObjC.h" 21a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 22a55d32d1b8f799bf58c02540983976368c42d895Jordan Roseusing namespace clang; 23a55d32d1b8f799bf58c02540983976368c42d895Jordan Roseusing namespace sema; 24a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 25a55d32d1b8f799bf58c02540983976368c42d895Jordan Rosevoid FunctionScopeInfo::Clear() { 26a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose HasBranchProtectedScope = false; 27a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose HasBranchIntoScope = false; 28a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose HasIndirectGoto = false; 29a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 30a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose SwitchStack.clear(); 31a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose Returns.clear(); 32a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose ErrorTrap.reset(); 33a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose PossiblyUnreachableDiags.clear(); 34a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose WeakObjectUses.clear(); 35a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 36a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 37a55d32d1b8f799bf58c02540983976368c42d895Jordan Rosestatic const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) { 38a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (PropE->isExplicitProperty()) 39a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return PropE->getExplicitProperty(); 40a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 41a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return PropE->getImplicitPropertyGetter(); 42a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 43a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 44a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy 45a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) { 46a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose E = E->IgnoreParenCasts(); 47a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 48a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const NamedDecl *D = 0; 49a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose bool IsExact = false; 50a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 51a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose switch (E->getStmtClass()) { 52a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose case Stmt::DeclRefExprClass: 53a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose D = cast<DeclRefExpr>(E)->getDecl(); 54a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose IsExact = isa<VarDecl>(D); 55a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose break; 56a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose case Stmt::MemberExprClass: { 57a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const MemberExpr *ME = cast<MemberExpr>(E); 58a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose D = ME->getMemberDecl(); 59a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()); 60a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose break; 61a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 62a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose case Stmt::ObjCIvarRefExprClass: { 63a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E); 64a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose D = IE->getDecl(); 65bbff82f302a1dd67589f65912351978905f0c5a7Anna Zaks IsExact = IE->getBase()->isObjCSelfExpr(); 66a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose break; 67a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 68a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose case Stmt::PseudoObjectExprClass: { 69a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E); 70a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const ObjCPropertyRefExpr *BaseProp = 71a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm()); 72a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (BaseProp) { 73a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose D = getBestPropertyDecl(BaseProp); 74a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 75a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const Expr *DoubleBase = BaseProp->getBase(); 76a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase)) 77a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose DoubleBase = OVE->getSourceExpr(); 78a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 79bbff82f302a1dd67589f65912351978905f0c5a7Anna Zaks IsExact = DoubleBase->isObjCSelfExpr(); 80a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 81a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose break; 82a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 83a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose default: 84a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose break; 85a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 86a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 87a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return BaseInfoTy(D, IsExact); 88a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 89a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 90a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 91a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 92a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const ObjCPropertyRefExpr *PropE) 93a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose : Base(0, true), Property(getBestPropertyDecl(PropE)) { 94a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 95a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (PropE->isObjectReceiver()) { 96a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase()); 97a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const Expr *E = OVE->getSourceExpr(); 98a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose Base = getBaseInfo(E); 99a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } else if (PropE->isClassReceiver()) { 100a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose Base.setPointer(PropE->getClassReceiver()); 101a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } else { 102a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose assert(PropE->isSuperReceiver()); 103a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 104a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 105a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 106a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 107a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const DeclRefExpr *DRE) 108a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose : Base(0, true), Property(DRE->getDecl()) { 109a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose assert(isa<VarDecl>(Property)); 110a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 111a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 112a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy( 113a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose const ObjCIvarRefExpr *IvarE) 114a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) { 115a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 116a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 117a55d32d1b8f799bf58c02540983976368c42d895Jordan Rosevoid FunctionScopeInfo::markSafeWeakUse(const Expr *E) { 118a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose E = E->IgnoreParenImpCasts(); 119a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 120a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) { 121a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose markSafeWeakUse(POE->getSyntacticForm()); 122a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 123a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 124a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 125a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) { 126a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose markSafeWeakUse(Cond->getTrueExpr()); 127a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose markSafeWeakUse(Cond->getFalseExpr()); 128a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 129a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 130a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 131a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (const BinaryConditionalOperator *Cond = 132a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose dyn_cast<BinaryConditionalOperator>(E)) { 133a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose markSafeWeakUse(Cond->getCommon()); 134a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose markSafeWeakUse(Cond->getFalseExpr()); 135a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 136a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose } 137a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 138a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose // Has this weak object been seen before? 139a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose FunctionScopeInfo::WeakObjectUseMap::iterator Uses; 140a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) 141a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose Uses = WeakObjectUses.find(FunctionScopeInfo::WeakObjectProfileTy(RefExpr)); 142a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E)) 143a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose Uses = WeakObjectUses.find(FunctionScopeInfo::WeakObjectProfileTy(IvarE)); 144a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 145a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose Uses = WeakObjectUses.find(FunctionScopeInfo::WeakObjectProfileTy(DRE)); 146a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose else 147a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 148a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 149a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (Uses == WeakObjectUses.end()) 150a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 151a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 152a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose // Has there been a read from the object using this Expr? 153a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse = 154a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose std::find(Uses->second.rbegin(), Uses->second.rend(), WeakUseTy(E, true)); 155a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose if (ThisUse == Uses->second.rend()) 156a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose return; 157a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 158a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose ThisUse->markSafe(); 159a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose} 160a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose 161a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::~FunctionScopeInfo() { } 162a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseBlockScopeInfo::~BlockScopeInfo() { } 163a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseLambdaScopeInfo::~LambdaScopeInfo() { } 164