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