1243791Sdim//===--- ScopeInfo.cpp - Information about a semantic context -------------===//
2243791Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6243791Sdim//
7243791Sdim//===----------------------------------------------------------------------===//
8243791Sdim//
9243791Sdim// This file implements FunctionScopeInfo and its subclasses, which contain
10243791Sdim// information about a single function, block, lambda, or method body.
11243791Sdim//
12243791Sdim//===----------------------------------------------------------------------===//
13243791Sdim
14243791Sdim#include "clang/Sema/ScopeInfo.h"
15243791Sdim#include "clang/AST/Decl.h"
16280031Sdim#include "clang/AST/DeclCXX.h"
17243791Sdim#include "clang/AST/DeclObjC.h"
18243791Sdim#include "clang/AST/Expr.h"
19243791Sdim#include "clang/AST/ExprCXX.h"
20243791Sdim#include "clang/AST/ExprObjC.h"
21243791Sdim
22243791Sdimusing namespace clang;
23243791Sdimusing namespace sema;
24243791Sdim
25243791Sdimvoid FunctionScopeInfo::Clear() {
26243791Sdim  HasBranchProtectedScope = false;
27243791Sdim  HasBranchIntoScope = false;
28243791Sdim  HasIndirectGoto = false;
29276479Sdim  HasDroppedStmt = false;
30309124Sdim  HasOMPDeclareReductionCombiner = false;
31314564Sdim  HasFallthroughStmt = false;
32314564Sdim  HasPotentialAvailabilityViolations = false;
33276479Sdim  ObjCShouldCallSuper = false;
34276479Sdim  ObjCIsDesignatedInit = false;
35276479Sdim  ObjCWarnForNoDesignatedInitChain = false;
36276479Sdim  ObjCIsSecondaryInit = false;
37276479Sdim  ObjCWarnForNoInitDelegation = false;
38296417Sdim  FirstReturnLoc = SourceLocation();
39288943Sdim  FirstCXXTryLoc = SourceLocation();
40288943Sdim  FirstSEHTryLoc = SourceLocation();
41243791Sdim
42321369Sdim  // Coroutine state
43321369Sdim  FirstCoroutineStmtLoc = SourceLocation();
44321369Sdim  CoroutinePromise = nullptr;
45341825Sdim  CoroutineParameterMoves.clear();
46321369Sdim  NeedsCoroutineSuspends = true;
47321369Sdim  CoroutineSuspends.first = nullptr;
48321369Sdim  CoroutineSuspends.second = nullptr;
49321369Sdim
50243791Sdim  SwitchStack.clear();
51243791Sdim  Returns.clear();
52243791Sdim  ErrorTrap.reset();
53243791Sdim  PossiblyUnreachableDiags.clear();
54243791Sdim  WeakObjectUses.clear();
55280031Sdim  ModifiedNonNullParams.clear();
56344779Sdim  Blocks.clear();
57344779Sdim  ByrefBlockVars.clear();
58243791Sdim}
59243791Sdim
60243791Sdimstatic const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
61243791Sdim  if (PropE->isExplicitProperty())
62243791Sdim    return PropE->getExplicitProperty();
63243791Sdim
64243791Sdim  return PropE->getImplicitPropertyGetter();
65243791Sdim}
66243791Sdim
67243791SdimFunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy
68243791SdimFunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {
69243791Sdim  E = E->IgnoreParenCasts();
70243791Sdim
71276479Sdim  const NamedDecl *D = nullptr;
72243791Sdim  bool IsExact = false;
73243791Sdim
74243791Sdim  switch (E->getStmtClass()) {
75243791Sdim  case Stmt::DeclRefExprClass:
76243791Sdim    D = cast<DeclRefExpr>(E)->getDecl();
77243791Sdim    IsExact = isa<VarDecl>(D);
78243791Sdim    break;
79243791Sdim  case Stmt::MemberExprClass: {
80243791Sdim    const MemberExpr *ME = cast<MemberExpr>(E);
81243791Sdim    D = ME->getMemberDecl();
82243791Sdim    IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts());
83243791Sdim    break;
84243791Sdim  }
85243791Sdim  case Stmt::ObjCIvarRefExprClass: {
86243791Sdim    const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E);
87243791Sdim    D = IE->getDecl();
88243791Sdim    IsExact = IE->getBase()->isObjCSelfExpr();
89243791Sdim    break;
90243791Sdim  }
91243791Sdim  case Stmt::PseudoObjectExprClass: {
92243791Sdim    const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E);
93243791Sdim    const ObjCPropertyRefExpr *BaseProp =
94243791Sdim      dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
95243791Sdim    if (BaseProp) {
96243791Sdim      D = getBestPropertyDecl(BaseProp);
97243791Sdim
98309124Sdim      if (BaseProp->isObjectReceiver()) {
99309124Sdim        const Expr *DoubleBase = BaseProp->getBase();
100309124Sdim        if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase))
101309124Sdim          DoubleBase = OVE->getSourceExpr();
102243791Sdim
103309124Sdim        IsExact = DoubleBase->isObjCSelfExpr();
104309124Sdim      }
105243791Sdim    }
106243791Sdim    break;
107243791Sdim  }
108243791Sdim  default:
109243791Sdim    break;
110243791Sdim  }
111243791Sdim
112243791Sdim  return BaseInfoTy(D, IsExact);
113243791Sdim}
114243791Sdim
115243791SdimFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
116243791Sdim                                          const ObjCPropertyRefExpr *PropE)
117276479Sdim    : Base(nullptr, true), Property(getBestPropertyDecl(PropE)) {
118243791Sdim
119243791Sdim  if (PropE->isObjectReceiver()) {
120243791Sdim    const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase());
121243791Sdim    const Expr *E = OVE->getSourceExpr();
122243791Sdim    Base = getBaseInfo(E);
123243791Sdim  } else if (PropE->isClassReceiver()) {
124243791Sdim    Base.setPointer(PropE->getClassReceiver());
125243791Sdim  } else {
126243791Sdim    assert(PropE->isSuperReceiver());
127243791Sdim  }
128243791Sdim}
129243791Sdim
130243791SdimFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,
131243791Sdim                                                const ObjCPropertyDecl *Prop)
132276479Sdim    : Base(nullptr, true), Property(Prop) {
133243791Sdim  if (BaseE)
134243791Sdim    Base = getBaseInfo(BaseE);
135243791Sdim  // else, this is a message accessing a property on super.
136243791Sdim}
137243791Sdim
138243791SdimFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
139243791Sdim                                                      const DeclRefExpr *DRE)
140276479Sdim  : Base(nullptr, true), Property(DRE->getDecl()) {
141243791Sdim  assert(isa<VarDecl>(Property));
142243791Sdim}
143243791Sdim
144243791SdimFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
145243791Sdim                                                  const ObjCIvarRefExpr *IvarE)
146243791Sdim  : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) {
147243791Sdim}
148243791Sdim
149243791Sdimvoid FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg,
150243791Sdim                                        const ObjCPropertyDecl *Prop) {
151243791Sdim  assert(Msg && Prop);
152243791Sdim  WeakUseVector &Uses =
153243791Sdim    WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)];
154243791Sdim  Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0));
155243791Sdim}
156243791Sdim
157243791Sdimvoid FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
158243791Sdim  E = E->IgnoreParenCasts();
159243791Sdim
160243791Sdim  if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
161243791Sdim    markSafeWeakUse(POE->getSyntacticForm());
162243791Sdim    return;
163243791Sdim  }
164243791Sdim
165243791Sdim  if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) {
166243791Sdim    markSafeWeakUse(Cond->getTrueExpr());
167243791Sdim    markSafeWeakUse(Cond->getFalseExpr());
168243791Sdim    return;
169243791Sdim  }
170243791Sdim
171243791Sdim  if (const BinaryConditionalOperator *Cond =
172243791Sdim        dyn_cast<BinaryConditionalOperator>(E)) {
173243791Sdim    markSafeWeakUse(Cond->getCommon());
174243791Sdim    markSafeWeakUse(Cond->getFalseExpr());
175243791Sdim    return;
176243791Sdim  }
177243791Sdim
178243791Sdim  // Has this weak object been seen before?
179321369Sdim  FunctionScopeInfo::WeakObjectUseMap::iterator Uses = WeakObjectUses.end();
180276479Sdim  if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
181280031Sdim    if (!RefExpr->isObjectReceiver())
182280031Sdim      return;
183276479Sdim    if (isa<OpaqueValueExpr>(RefExpr->getBase()))
184276479Sdim     Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
185276479Sdim    else {
186276479Sdim      markSafeWeakUse(RefExpr->getBase());
187276479Sdim      return;
188276479Sdim    }
189276479Sdim  }
190243791Sdim  else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
191243791Sdim    Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
192321369Sdim  else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
193321369Sdim    if (isa<VarDecl>(DRE->getDecl()))
194321369Sdim      Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
195321369Sdim  } else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
196243791Sdim    if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
197243791Sdim      if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
198243791Sdim        Uses =
199243791Sdim          WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(),
200243791Sdim                                                  Prop));
201243791Sdim      }
202243791Sdim    }
203243791Sdim  }
204243791Sdim  else
205243791Sdim    return;
206243791Sdim
207243791Sdim  if (Uses == WeakObjectUses.end())
208243791Sdim    return;
209243791Sdim
210243791Sdim  // Has there been a read from the object using this Expr?
211243791Sdim  FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse =
212309124Sdim      llvm::find(llvm::reverse(Uses->second), WeakUseTy(E, true));
213243791Sdim  if (ThisUse == Uses->second.rend())
214243791Sdim    return;
215243791Sdim
216243791Sdim  ThisUse->markSafe();
217243791Sdim}
218243791Sdim
219353358Sdimbool Capture::isInitCapture() const {
220353358Sdim  // Note that a nested capture of an init-capture is not itself an
221353358Sdim  // init-capture.
222353358Sdim  return !isNested() && isVariableCapture() && getVariable()->isInitCapture();
223261991Sdim}
224261991Sdim
225353358Sdimbool CapturingScopeInfo::isVLATypeCaptured(const VariableArrayType *VAT) const {
226353358Sdim  for (auto &Cap : Captures)
227353358Sdim    if (Cap.isVLATypeCapture() && Cap.getCapturedVLAType() == VAT)
228353358Sdim      return true;
229353358Sdim  return false;
230353358Sdim}
231353358Sdim
232353358Sdimvoid LambdaScopeInfo::visitPotentialCaptures(
233353358Sdim    llvm::function_ref<void(VarDecl *, Expr *)> Callback) const {
234353358Sdim  for (Expr *E : PotentiallyCapturingExprs) {
235353358Sdim    if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
236353358Sdim      Callback(cast<VarDecl>(DRE->getFoundDecl()), E);
237353358Sdim    } else if (auto *ME = dyn_cast<MemberExpr>(E)) {
238353358Sdim      Callback(cast<VarDecl>(ME->getMemberDecl()), E);
239353358Sdim    } else if (auto *FP = dyn_cast<FunctionParmPackExpr>(E)) {
240353358Sdim      for (VarDecl *VD : *FP)
241353358Sdim        Callback(VD, E);
242353358Sdim    } else {
243353358Sdim      llvm_unreachable("unexpected expression in potential captures list");
244353358Sdim    }
245353358Sdim  }
246353358Sdim}
247353358Sdim
248243791SdimFunctionScopeInfo::~FunctionScopeInfo() { }
249243791SdimBlockScopeInfo::~BlockScopeInfo() { }
250251662SdimCapturedRegionScopeInfo::~CapturedRegionScopeInfo() { }
251