ScopeInfo.cpp revision 243791
1115140Strhodes//===--- ScopeInfo.cpp - Information about a semantic context -------------===//
2115140Strhodes//
3115140Strhodes//                     The LLVM Compiler Infrastructure
4115140Strhodes//
5115140Strhodes// This file is distributed under the University of Illinois Open Source
6115140Strhodes// License. See LICENSE.TXT for details.
7115140Strhodes//
8115140Strhodes//===----------------------------------------------------------------------===//
9115140Strhodes//
10115140Strhodes// This file implements FunctionScopeInfo and its subclasses, which contain
11115140Strhodes// information about a single function, block, lambda, or method body.
12115140Strhodes//
13115140Strhodes//===----------------------------------------------------------------------===//
14115140Strhodes
15115140Strhodes#include "clang/Sema/ScopeInfo.h"
16115140Strhodes#include "clang/AST/Decl.h"
17115140Strhodes#include "clang/AST/DeclObjC.h"
18115140Strhodes#include "clang/AST/Expr.h"
19115140Strhodes#include "clang/AST/ExprCXX.h"
20115140Strhodes#include "clang/AST/ExprObjC.h"
21115140Strhodes
22115140Strhodesusing namespace clang;
23115140Strhodesusing namespace sema;
24115140Strhodes
25115140Strhodesvoid FunctionScopeInfo::Clear() {
26115140Strhodes  HasBranchProtectedScope = false;
27115140Strhodes  HasBranchIntoScope = false;
28115140Strhodes  HasIndirectGoto = false;
29115140Strhodes
30115140Strhodes  SwitchStack.clear();
31115140Strhodes  Returns.clear();
32232507Seadler  ErrorTrap.reset();
33115140Strhodes  PossiblyUnreachableDiags.clear();
34115140Strhodes  WeakObjectUses.clear();
35115140Strhodes}
36115140Strhodes
37115140Strhodesstatic const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
38115140Strhodes  if (PropE->isExplicitProperty())
39115140Strhodes    return PropE->getExplicitProperty();
40115140Strhodes
41115140Strhodes  return PropE->getImplicitPropertyGetter();
42115140Strhodes}
43115140Strhodes
44115140StrhodesFunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy
45115140StrhodesFunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {
46115140Strhodes  E = E->IgnoreParenCasts();
47115140Strhodes
48115140Strhodes  const NamedDecl *D = 0;
49115140Strhodes  bool IsExact = false;
50115140Strhodes
51115140Strhodes  switch (E->getStmtClass()) {
52115140Strhodes  case Stmt::DeclRefExprClass:
53115140Strhodes    D = cast<DeclRefExpr>(E)->getDecl();
54115140Strhodes    IsExact = isa<VarDecl>(D);
55115140Strhodes    break;
56115140Strhodes  case Stmt::MemberExprClass: {
57115140Strhodes    const MemberExpr *ME = cast<MemberExpr>(E);
58115140Strhodes    D = ME->getMemberDecl();
59115140Strhodes    IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts());
60115140Strhodes    break;
61115140Strhodes  }
62115140Strhodes  case Stmt::ObjCIvarRefExprClass: {
63115140Strhodes    const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E);
64115140Strhodes    D = IE->getDecl();
65115140Strhodes    IsExact = IE->getBase()->isObjCSelfExpr();
66115140Strhodes    break;
67115140Strhodes  }
68115140Strhodes  case Stmt::PseudoObjectExprClass: {
69115140Strhodes    const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E);
70115140Strhodes    const ObjCPropertyRefExpr *BaseProp =
71115140Strhodes      dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
72115140Strhodes    if (BaseProp) {
73219004Shselasky      D = getBestPropertyDecl(BaseProp);
74115140Strhodes
75115140Strhodes      const Expr *DoubleBase = BaseProp->getBase();
76115140Strhodes      if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase))
77115140Strhodes        DoubleBase = OVE->getSourceExpr();
78115140Strhodes
79115140Strhodes      IsExact = DoubleBase->isObjCSelfExpr();
80115140Strhodes    }
81115140Strhodes    break;
82219004Shselasky  }
83232501Seadler  default:
84232501Seadler    break;
85232501Seadler  }
86232501Seadler
87232501Seadler  return BaseInfoTy(D, IsExact);
88219004Shselasky}
89219004Shselasky
90219004Shselasky
91219004ShselaskyFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
92219004Shselasky                                          const ObjCPropertyRefExpr *PropE)
93219004Shselasky    : Base(0, true), Property(getBestPropertyDecl(PropE)) {
94219004Shselasky
95219004Shselasky  if (PropE->isObjectReceiver()) {
96219004Shselasky    const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase());
97219004Shselasky    const Expr *E = OVE->getSourceExpr();
98219004Shselasky    Base = getBaseInfo(E);
99219004Shselasky  } else if (PropE->isClassReceiver()) {
100219004Shselasky    Base.setPointer(PropE->getClassReceiver());
101219004Shselasky  } else {
102    assert(PropE->isSuperReceiver());
103  }
104}
105
106FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,
107                                                const ObjCPropertyDecl *Prop)
108    : Base(0, true), Property(Prop) {
109  if (BaseE)
110    Base = getBaseInfo(BaseE);
111  // else, this is a message accessing a property on super.
112}
113
114FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
115                                                      const DeclRefExpr *DRE)
116  : Base(0, true), Property(DRE->getDecl()) {
117  assert(isa<VarDecl>(Property));
118}
119
120FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
121                                                  const ObjCIvarRefExpr *IvarE)
122  : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) {
123}
124
125void FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg,
126                                        const ObjCPropertyDecl *Prop) {
127  assert(Msg && Prop);
128  WeakUseVector &Uses =
129    WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)];
130  Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0));
131}
132
133void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
134  E = E->IgnoreParenCasts();
135
136  if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
137    markSafeWeakUse(POE->getSyntacticForm());
138    return;
139  }
140
141  if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) {
142    markSafeWeakUse(Cond->getTrueExpr());
143    markSafeWeakUse(Cond->getFalseExpr());
144    return;
145  }
146
147  if (const BinaryConditionalOperator *Cond =
148        dyn_cast<BinaryConditionalOperator>(E)) {
149    markSafeWeakUse(Cond->getCommon());
150    markSafeWeakUse(Cond->getFalseExpr());
151    return;
152  }
153
154  // Has this weak object been seen before?
155  FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
156  if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E))
157    Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
158  else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
159    Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
160  else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
161    Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
162  else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
163    Uses = WeakObjectUses.end();
164    if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
165      if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
166        Uses =
167          WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(),
168                                                  Prop));
169      }
170    }
171  }
172  else
173    return;
174
175  if (Uses == WeakObjectUses.end())
176    return;
177
178  // Has there been a read from the object using this Expr?
179  FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse =
180    std::find(Uses->second.rbegin(), Uses->second.rend(), WeakUseTy(E, true));
181  if (ThisUse == Uses->second.rend())
182    return;
183
184  ThisUse->markSafe();
185}
186
187FunctionScopeInfo::~FunctionScopeInfo() { }
188BlockScopeInfo::~BlockScopeInfo() { }
189LambdaScopeInfo::~LambdaScopeInfo() { }
190