xref: /aosp_15_r20/external/clang/lib/Sema/ScopeInfo.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- ScopeInfo.cpp - Information about a semantic context -------------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file implements FunctionScopeInfo and its subclasses, which contain
11*67e74705SXin Li // information about a single function, block, lambda, or method body.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li 
15*67e74705SXin Li #include "clang/Sema/ScopeInfo.h"
16*67e74705SXin Li #include "clang/AST/Decl.h"
17*67e74705SXin Li #include "clang/AST/DeclCXX.h"
18*67e74705SXin Li #include "clang/AST/DeclObjC.h"
19*67e74705SXin Li #include "clang/AST/Expr.h"
20*67e74705SXin Li #include "clang/AST/ExprCXX.h"
21*67e74705SXin Li #include "clang/AST/ExprObjC.h"
22*67e74705SXin Li 
23*67e74705SXin Li using namespace clang;
24*67e74705SXin Li using namespace sema;
25*67e74705SXin Li 
Clear()26*67e74705SXin Li void FunctionScopeInfo::Clear() {
27*67e74705SXin Li   HasBranchProtectedScope = false;
28*67e74705SXin Li   HasBranchIntoScope = false;
29*67e74705SXin Li   HasIndirectGoto = false;
30*67e74705SXin Li   HasDroppedStmt = false;
31*67e74705SXin Li   HasOMPDeclareReductionCombiner = false;
32*67e74705SXin Li   ObjCShouldCallSuper = false;
33*67e74705SXin Li   ObjCIsDesignatedInit = false;
34*67e74705SXin Li   ObjCWarnForNoDesignatedInitChain = false;
35*67e74705SXin Li   ObjCIsSecondaryInit = false;
36*67e74705SXin Li   ObjCWarnForNoInitDelegation = false;
37*67e74705SXin Li   FirstReturnLoc = SourceLocation();
38*67e74705SXin Li   FirstCXXTryLoc = SourceLocation();
39*67e74705SXin Li   FirstSEHTryLoc = SourceLocation();
40*67e74705SXin Li 
41*67e74705SXin Li   SwitchStack.clear();
42*67e74705SXin Li   Returns.clear();
43*67e74705SXin Li   CoroutinePromise = nullptr;
44*67e74705SXin Li   CoroutineStmts.clear();
45*67e74705SXin Li   ErrorTrap.reset();
46*67e74705SXin Li   PossiblyUnreachableDiags.clear();
47*67e74705SXin Li   WeakObjectUses.clear();
48*67e74705SXin Li   ModifiedNonNullParams.clear();
49*67e74705SXin Li }
50*67e74705SXin Li 
getBestPropertyDecl(const ObjCPropertyRefExpr * PropE)51*67e74705SXin Li static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
52*67e74705SXin Li   if (PropE->isExplicitProperty())
53*67e74705SXin Li     return PropE->getExplicitProperty();
54*67e74705SXin Li 
55*67e74705SXin Li   return PropE->getImplicitPropertyGetter();
56*67e74705SXin Li }
57*67e74705SXin Li 
58*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy
getBaseInfo(const Expr * E)59*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {
60*67e74705SXin Li   E = E->IgnoreParenCasts();
61*67e74705SXin Li 
62*67e74705SXin Li   const NamedDecl *D = nullptr;
63*67e74705SXin Li   bool IsExact = false;
64*67e74705SXin Li 
65*67e74705SXin Li   switch (E->getStmtClass()) {
66*67e74705SXin Li   case Stmt::DeclRefExprClass:
67*67e74705SXin Li     D = cast<DeclRefExpr>(E)->getDecl();
68*67e74705SXin Li     IsExact = isa<VarDecl>(D);
69*67e74705SXin Li     break;
70*67e74705SXin Li   case Stmt::MemberExprClass: {
71*67e74705SXin Li     const MemberExpr *ME = cast<MemberExpr>(E);
72*67e74705SXin Li     D = ME->getMemberDecl();
73*67e74705SXin Li     IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts());
74*67e74705SXin Li     break;
75*67e74705SXin Li   }
76*67e74705SXin Li   case Stmt::ObjCIvarRefExprClass: {
77*67e74705SXin Li     const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E);
78*67e74705SXin Li     D = IE->getDecl();
79*67e74705SXin Li     IsExact = IE->getBase()->isObjCSelfExpr();
80*67e74705SXin Li     break;
81*67e74705SXin Li   }
82*67e74705SXin Li   case Stmt::PseudoObjectExprClass: {
83*67e74705SXin Li     const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E);
84*67e74705SXin Li     const ObjCPropertyRefExpr *BaseProp =
85*67e74705SXin Li       dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
86*67e74705SXin Li     if (BaseProp) {
87*67e74705SXin Li       D = getBestPropertyDecl(BaseProp);
88*67e74705SXin Li 
89*67e74705SXin Li       if (BaseProp->isObjectReceiver()) {
90*67e74705SXin Li         const Expr *DoubleBase = BaseProp->getBase();
91*67e74705SXin Li         if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase))
92*67e74705SXin Li           DoubleBase = OVE->getSourceExpr();
93*67e74705SXin Li 
94*67e74705SXin Li         IsExact = DoubleBase->isObjCSelfExpr();
95*67e74705SXin Li       }
96*67e74705SXin Li     }
97*67e74705SXin Li     break;
98*67e74705SXin Li   }
99*67e74705SXin Li   default:
100*67e74705SXin Li     break;
101*67e74705SXin Li   }
102*67e74705SXin Li 
103*67e74705SXin Li   return BaseInfoTy(D, IsExact);
104*67e74705SXin Li }
105*67e74705SXin Li 
isVLATypeCaptured(const VariableArrayType * VAT) const106*67e74705SXin Li bool CapturingScopeInfo::isVLATypeCaptured(const VariableArrayType *VAT) const {
107*67e74705SXin Li   RecordDecl *RD = nullptr;
108*67e74705SXin Li   if (auto *LSI = dyn_cast<LambdaScopeInfo>(this))
109*67e74705SXin Li     RD = LSI->Lambda;
110*67e74705SXin Li   else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(this))
111*67e74705SXin Li     RD = CRSI->TheRecordDecl;
112*67e74705SXin Li 
113*67e74705SXin Li   if (RD)
114*67e74705SXin Li     for (auto *FD : RD->fields()) {
115*67e74705SXin Li       if (FD->hasCapturedVLAType() && FD->getCapturedVLAType() == VAT)
116*67e74705SXin Li         return true;
117*67e74705SXin Li     }
118*67e74705SXin Li   return false;
119*67e74705SXin Li }
120*67e74705SXin Li 
WeakObjectProfileTy(const ObjCPropertyRefExpr * PropE)121*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
122*67e74705SXin Li                                           const ObjCPropertyRefExpr *PropE)
123*67e74705SXin Li     : Base(nullptr, true), Property(getBestPropertyDecl(PropE)) {
124*67e74705SXin Li 
125*67e74705SXin Li   if (PropE->isObjectReceiver()) {
126*67e74705SXin Li     const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase());
127*67e74705SXin Li     const Expr *E = OVE->getSourceExpr();
128*67e74705SXin Li     Base = getBaseInfo(E);
129*67e74705SXin Li   } else if (PropE->isClassReceiver()) {
130*67e74705SXin Li     Base.setPointer(PropE->getClassReceiver());
131*67e74705SXin Li   } else {
132*67e74705SXin Li     assert(PropE->isSuperReceiver());
133*67e74705SXin Li   }
134*67e74705SXin Li }
135*67e74705SXin Li 
WeakObjectProfileTy(const Expr * BaseE,const ObjCPropertyDecl * Prop)136*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,
137*67e74705SXin Li                                                 const ObjCPropertyDecl *Prop)
138*67e74705SXin Li     : Base(nullptr, true), Property(Prop) {
139*67e74705SXin Li   if (BaseE)
140*67e74705SXin Li     Base = getBaseInfo(BaseE);
141*67e74705SXin Li   // else, this is a message accessing a property on super.
142*67e74705SXin Li }
143*67e74705SXin Li 
WeakObjectProfileTy(const DeclRefExpr * DRE)144*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
145*67e74705SXin Li                                                       const DeclRefExpr *DRE)
146*67e74705SXin Li   : Base(nullptr, true), Property(DRE->getDecl()) {
147*67e74705SXin Li   assert(isa<VarDecl>(Property));
148*67e74705SXin Li }
149*67e74705SXin Li 
WeakObjectProfileTy(const ObjCIvarRefExpr * IvarE)150*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
151*67e74705SXin Li                                                   const ObjCIvarRefExpr *IvarE)
152*67e74705SXin Li   : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) {
153*67e74705SXin Li }
154*67e74705SXin Li 
recordUseOfWeak(const ObjCMessageExpr * Msg,const ObjCPropertyDecl * Prop)155*67e74705SXin Li void FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg,
156*67e74705SXin Li                                         const ObjCPropertyDecl *Prop) {
157*67e74705SXin Li   assert(Msg && Prop);
158*67e74705SXin Li   WeakUseVector &Uses =
159*67e74705SXin Li     WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)];
160*67e74705SXin Li   Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0));
161*67e74705SXin Li }
162*67e74705SXin Li 
markSafeWeakUse(const Expr * E)163*67e74705SXin Li void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
164*67e74705SXin Li   E = E->IgnoreParenCasts();
165*67e74705SXin Li 
166*67e74705SXin Li   if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
167*67e74705SXin Li     markSafeWeakUse(POE->getSyntacticForm());
168*67e74705SXin Li     return;
169*67e74705SXin Li   }
170*67e74705SXin Li 
171*67e74705SXin Li   if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) {
172*67e74705SXin Li     markSafeWeakUse(Cond->getTrueExpr());
173*67e74705SXin Li     markSafeWeakUse(Cond->getFalseExpr());
174*67e74705SXin Li     return;
175*67e74705SXin Li   }
176*67e74705SXin Li 
177*67e74705SXin Li   if (const BinaryConditionalOperator *Cond =
178*67e74705SXin Li         dyn_cast<BinaryConditionalOperator>(E)) {
179*67e74705SXin Li     markSafeWeakUse(Cond->getCommon());
180*67e74705SXin Li     markSafeWeakUse(Cond->getFalseExpr());
181*67e74705SXin Li     return;
182*67e74705SXin Li   }
183*67e74705SXin Li 
184*67e74705SXin Li   // Has this weak object been seen before?
185*67e74705SXin Li   FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
186*67e74705SXin Li   if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
187*67e74705SXin Li     if (!RefExpr->isObjectReceiver())
188*67e74705SXin Li       return;
189*67e74705SXin Li     if (isa<OpaqueValueExpr>(RefExpr->getBase()))
190*67e74705SXin Li      Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
191*67e74705SXin Li     else {
192*67e74705SXin Li       markSafeWeakUse(RefExpr->getBase());
193*67e74705SXin Li       return;
194*67e74705SXin Li     }
195*67e74705SXin Li   }
196*67e74705SXin Li   else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
197*67e74705SXin Li     Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
198*67e74705SXin Li   else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
199*67e74705SXin Li     Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
200*67e74705SXin Li   else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
201*67e74705SXin Li     Uses = WeakObjectUses.end();
202*67e74705SXin Li     if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
203*67e74705SXin Li       if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
204*67e74705SXin Li         Uses =
205*67e74705SXin Li           WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(),
206*67e74705SXin Li                                                   Prop));
207*67e74705SXin Li       }
208*67e74705SXin Li     }
209*67e74705SXin Li   }
210*67e74705SXin Li   else
211*67e74705SXin Li     return;
212*67e74705SXin Li 
213*67e74705SXin Li   if (Uses == WeakObjectUses.end())
214*67e74705SXin Li     return;
215*67e74705SXin Li 
216*67e74705SXin Li   // Has there been a read from the object using this Expr?
217*67e74705SXin Li   FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse =
218*67e74705SXin Li       llvm::find(llvm::reverse(Uses->second), WeakUseTy(E, true));
219*67e74705SXin Li   if (ThisUse == Uses->second.rend())
220*67e74705SXin Li     return;
221*67e74705SXin Li 
222*67e74705SXin Li   ThisUse->markSafe();
223*67e74705SXin Li }
224*67e74705SXin Li 
getPotentialVariableCapture(unsigned Idx,VarDecl * & VD,Expr * & E) const225*67e74705SXin Li void LambdaScopeInfo::getPotentialVariableCapture(unsigned Idx, VarDecl *&VD,
226*67e74705SXin Li                                                   Expr *&E) const {
227*67e74705SXin Li   assert(Idx < getNumPotentialVariableCaptures() &&
228*67e74705SXin Li          "Index of potential capture must be within 0 to less than the "
229*67e74705SXin Li          "number of captures!");
230*67e74705SXin Li   E = PotentiallyCapturingExprs[Idx];
231*67e74705SXin Li   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
232*67e74705SXin Li     VD = dyn_cast<VarDecl>(DRE->getFoundDecl());
233*67e74705SXin Li   else if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
234*67e74705SXin Li     VD = dyn_cast<VarDecl>(ME->getMemberDecl());
235*67e74705SXin Li   else
236*67e74705SXin Li     llvm_unreachable("Only DeclRefExprs or MemberExprs should be added for "
237*67e74705SXin Li     "potential captures");
238*67e74705SXin Li   assert(VD);
239*67e74705SXin Li }
240*67e74705SXin Li 
~FunctionScopeInfo()241*67e74705SXin Li FunctionScopeInfo::~FunctionScopeInfo() { }
~BlockScopeInfo()242*67e74705SXin Li BlockScopeInfo::~BlockScopeInfo() { }
~CapturedRegionScopeInfo()243*67e74705SXin Li CapturedRegionScopeInfo::~CapturedRegionScopeInfo() { }
244