brintos

brintos / llvm-project-archived public Read only

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