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