Home | History | Annotate | Line # | Download | only in Sema
      1 //===--- ScopeInfo.cpp - Information about a semantic context -------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file implements FunctionScopeInfo and its subclasses, which contain
     10 // information about a single function, block, lambda, or method body.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "clang/Sema/ScopeInfo.h"
     15 #include "clang/AST/Decl.h"
     16 #include "clang/AST/DeclCXX.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 
     22 using namespace clang;
     23 using namespace sema;
     24 
     25 void FunctionScopeInfo::Clear() {
     26   HasBranchProtectedScope = false;
     27   HasBranchIntoScope = false;
     28   HasIndirectGoto = false;
     29   HasDroppedStmt = false;
     30   HasOMPDeclareReductionCombiner = false;
     31   HasFallthroughStmt = false;
     32   UsesFPIntrin = false;
     33   HasPotentialAvailabilityViolations = false;
     34   ObjCShouldCallSuper = false;
     35   ObjCIsDesignatedInit = false;
     36   ObjCWarnForNoDesignatedInitChain = false;
     37   ObjCIsSecondaryInit = false;
     38   ObjCWarnForNoInitDelegation = false;
     39   FirstReturnLoc = SourceLocation();
     40   FirstCXXTryLoc = SourceLocation();
     41   FirstSEHTryLoc = SourceLocation();
     42 
     43   // Coroutine state
     44   FirstCoroutineStmtLoc = SourceLocation();
     45   CoroutinePromise = nullptr;
     46   CoroutineParameterMoves.clear();
     47   NeedsCoroutineSuspends = true;
     48   CoroutineSuspends.first = nullptr;
     49   CoroutineSuspends.second = nullptr;
     50 
     51   SwitchStack.clear();
     52   Returns.clear();
     53   ErrorTrap.reset();
     54   PossiblyUnreachableDiags.clear();
     55   WeakObjectUses.clear();
     56   ModifiedNonNullParams.clear();
     57   Blocks.clear();
     58   ByrefBlockVars.clear();
     59 }
     60 
     61 static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
     62   if (PropE->isExplicitProperty())
     63     return PropE->getExplicitProperty();
     64 
     65   return PropE->getImplicitPropertyGetter();
     66 }
     67 
     68 FunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy
     69 FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {
     70   E = E->IgnoreParenCasts();
     71 
     72   const NamedDecl *D = nullptr;
     73   bool IsExact = false;
     74 
     75   switch (E->getStmtClass()) {
     76   case Stmt::DeclRefExprClass:
     77     D = cast<DeclRefExpr>(E)->getDecl();
     78     IsExact = isa<VarDecl>(D);
     79     break;
     80   case Stmt::MemberExprClass: {
     81     const MemberExpr *ME = cast<MemberExpr>(E);
     82     D = ME->getMemberDecl();
     83     IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts());
     84     break;
     85   }
     86   case Stmt::ObjCIvarRefExprClass: {
     87     const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E);
     88     D = IE->getDecl();
     89     IsExact = IE->getBase()->isObjCSelfExpr();
     90     break;
     91   }
     92   case Stmt::PseudoObjectExprClass: {
     93     const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E);
     94     const ObjCPropertyRefExpr *BaseProp =
     95       dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
     96     if (BaseProp) {
     97       D = getBestPropertyDecl(BaseProp);
     98 
     99       if (BaseProp->isObjectReceiver()) {
    100         const Expr *DoubleBase = BaseProp->getBase();
    101         if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase))
    102           DoubleBase = OVE->getSourceExpr();
    103 
    104         IsExact = DoubleBase->isObjCSelfExpr();
    105       }
    106     }
    107     break;
    108   }
    109   default:
    110     break;
    111   }
    112 
    113   return BaseInfoTy(D, IsExact);
    114 }
    115 
    116 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
    117                                           const ObjCPropertyRefExpr *PropE)
    118     : Base(nullptr, true), Property(getBestPropertyDecl(PropE)) {
    119 
    120   if (PropE->isObjectReceiver()) {
    121     const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase());
    122     const Expr *E = OVE->getSourceExpr();
    123     Base = getBaseInfo(E);
    124   } else if (PropE->isClassReceiver()) {
    125     Base.setPointer(PropE->getClassReceiver());
    126   } else {
    127     assert(PropE->isSuperReceiver());
    128   }
    129 }
    130 
    131 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,
    132                                                 const ObjCPropertyDecl *Prop)
    133     : Base(nullptr, true), Property(Prop) {
    134   if (BaseE)
    135     Base = getBaseInfo(BaseE);
    136   // else, this is a message accessing a property on super.
    137 }
    138 
    139 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
    140                                                       const DeclRefExpr *DRE)
    141   : Base(nullptr, true), Property(DRE->getDecl()) {
    142   assert(isa<VarDecl>(Property));
    143 }
    144 
    145 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
    146                                                   const ObjCIvarRefExpr *IvarE)
    147   : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) {
    148 }
    149 
    150 void FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg,
    151                                         const ObjCPropertyDecl *Prop) {
    152   assert(Msg && Prop);
    153   WeakUseVector &Uses =
    154     WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)];
    155   Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0));
    156 }
    157 
    158 void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
    159   E = E->IgnoreParenCasts();
    160 
    161   if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
    162     markSafeWeakUse(POE->getSyntacticForm());
    163     return;
    164   }
    165 
    166   if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) {
    167     markSafeWeakUse(Cond->getTrueExpr());
    168     markSafeWeakUse(Cond->getFalseExpr());
    169     return;
    170   }
    171 
    172   if (const BinaryConditionalOperator *Cond =
    173         dyn_cast<BinaryConditionalOperator>(E)) {
    174     markSafeWeakUse(Cond->getCommon());
    175     markSafeWeakUse(Cond->getFalseExpr());
    176     return;
    177   }
    178 
    179   // Has this weak object been seen before?
    180   FunctionScopeInfo::WeakObjectUseMap::iterator Uses = WeakObjectUses.end();
    181   if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
    182     if (!RefExpr->isObjectReceiver())
    183       return;
    184     if (isa<OpaqueValueExpr>(RefExpr->getBase()))
    185      Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
    186     else {
    187       markSafeWeakUse(RefExpr->getBase());
    188       return;
    189     }
    190   }
    191   else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
    192     Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
    193   else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
    194     if (isa<VarDecl>(DRE->getDecl()))
    195       Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
    196   } else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
    197     if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
    198       if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
    199         Uses =
    200           WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(),
    201                                                   Prop));
    202       }
    203     }
    204   }
    205   else
    206     return;
    207 
    208   if (Uses == WeakObjectUses.end())
    209     return;
    210 
    211   // Has there been a read from the object using this Expr?
    212   FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse =
    213       llvm::find(llvm::reverse(Uses->second), WeakUseTy(E, true));
    214   if (ThisUse == Uses->second.rend())
    215     return;
    216 
    217   ThisUse->markSafe();
    218 }
    219 
    220 bool Capture::isInitCapture() const {
    221   // Note that a nested capture of an init-capture is not itself an
    222   // init-capture.
    223   return !isNested() && isVariableCapture() && getVariable()->isInitCapture();
    224 }
    225 
    226 bool CapturingScopeInfo::isVLATypeCaptured(const VariableArrayType *VAT) const {
    227   for (auto &Cap : Captures)
    228     if (Cap.isVLATypeCapture() && Cap.getCapturedVLAType() == VAT)
    229       return true;
    230   return false;
    231 }
    232 
    233 void LambdaScopeInfo::visitPotentialCaptures(
    234     llvm::function_ref<void(VarDecl *, Expr *)> Callback) const {
    235   for (Expr *E : PotentiallyCapturingExprs) {
    236     if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
    237       Callback(cast<VarDecl>(DRE->getFoundDecl()), E);
    238     } else if (auto *ME = dyn_cast<MemberExpr>(E)) {
    239       Callback(cast<VarDecl>(ME->getMemberDecl()), E);
    240     } else if (auto *FP = dyn_cast<FunctionParmPackExpr>(E)) {
    241       for (VarDecl *VD : *FP)
    242         Callback(VD, E);
    243     } else {
    244       llvm_unreachable("unexpected expression in potential captures list");
    245     }
    246   }
    247 }
    248 
    249 FunctionScopeInfo::~FunctionScopeInfo() { }
    250 BlockScopeInfo::~BlockScopeInfo() { }
    251 CapturedRegionScopeInfo::~CapturedRegionScopeInfo() { }
    252