ScopeInfo.cpp revision 6afcf8875d4e447645cd7bf3733dd8e2eb8455dc
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
1067fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,
1077fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose                                                const ObjCPropertyDecl *Prop)
1087fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose    : Base(0, true), Property(Prop) {
1097fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose  if (BaseE)
1107fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose    Base = getBaseInfo(BaseE);
1117fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose  // else, this is a message accessing a property on super.
1127fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose}
1137fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose
114a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
115a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose                                                      const DeclRefExpr *DRE)
116a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  : Base(0, true), Property(DRE->getDecl()) {
117a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  assert(isa<VarDecl>(Property));
118a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose}
119a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose
120a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
121a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose                                                  const ObjCIvarRefExpr *IvarE)
122a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) {
123a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose}
124a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose
1257fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rosevoid FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg,
1267fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose                                        const ObjCPropertyDecl *Prop) {
1277fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose  assert(Msg && Prop);
1287fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose  WeakUseVector &Uses =
1297fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose    WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)];
1307fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose  Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0));
1317fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose}
1327fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose
133a55d32d1b8f799bf58c02540983976368c42d895Jordan Rosevoid FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
134c88f8ef9d85a537233b4423d31dbf8bc81be525aJordan Rose  E = E->IgnoreParenCasts();
135a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose
136a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
137a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    markSafeWeakUse(POE->getSyntacticForm());
138a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    return;
139a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  }
140a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose
141a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) {
142a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    markSafeWeakUse(Cond->getTrueExpr());
143a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    markSafeWeakUse(Cond->getFalseExpr());
144a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    return;
145a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  }
146a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose
147a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  if (const BinaryConditionalOperator *Cond =
148a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose        dyn_cast<BinaryConditionalOperator>(E)) {
149a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    markSafeWeakUse(Cond->getCommon());
150a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    markSafeWeakUse(Cond->getFalseExpr());
151a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    return;
152a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  }
153a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose
154a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  // Has this weak object been seen before?
155a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
156a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E))
1577fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose    Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
158a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
1597fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose    Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
160a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
1617fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose    Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
162f1c1ba089cd8930c1193fcd20fb38cab834a8f94Jordan Rose  else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
1637fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose    Uses = WeakObjectUses.end();
1647fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose    if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
1657fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose      if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
1667fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose        Uses =
1677fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose          WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(),
1687fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose                                                  Prop));
1697fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose      }
1707fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose    }
1717fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose  }
172a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  else
173a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    return;
174a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose
175a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  if (Uses == WeakObjectUses.end())
176a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    return;
177a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose
178a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  // Has there been a read from the object using this Expr?
179a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse =
180a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    std::find(Uses->second.rbegin(), Uses->second.rend(), WeakUseTy(E, true));
181a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  if (ThisUse == Uses->second.rend())
182a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose    return;
183a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose
184a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose  ThisUse->markSafe();
185a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose}
186a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose
187a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseFunctionScopeInfo::~FunctionScopeInfo() { }
188a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseBlockScopeInfo::~BlockScopeInfo() { }
189a55d32d1b8f799bf58c02540983976368c42d895Jordan RoseLambdaScopeInfo::~LambdaScopeInfo() { }
1906afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. SirajCapturedRegionScopeInfo::~CapturedRegionScopeInfo() { }
191