Path: blob/main/contrib/llvm-project/clang/lib/Sema/ScopeInfo.cpp
35233 views
//===--- ScopeInfo.cpp - Information about a semantic context -------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements FunctionScopeInfo and its subclasses, which contain9// information about a single function, block, lambda, or method body.10//11//===----------------------------------------------------------------------===//1213#include "clang/Sema/ScopeInfo.h"14#include "clang/AST/Decl.h"15#include "clang/AST/DeclCXX.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"2021using namespace clang;22using namespace sema;2324void FunctionScopeInfo::Clear() {25HasBranchProtectedScope = false;26HasBranchIntoScope = false;27HasIndirectGoto = false;28HasDroppedStmt = false;29HasOMPDeclareReductionCombiner = false;30HasFallthroughStmt = false;31UsesFPIntrin = false;32HasPotentialAvailabilityViolations = false;33ObjCShouldCallSuper = false;34ObjCIsDesignatedInit = false;35ObjCWarnForNoDesignatedInitChain = false;36ObjCIsSecondaryInit = false;37ObjCWarnForNoInitDelegation = false;38FirstReturnLoc = SourceLocation();39FirstCXXOrObjCTryLoc = SourceLocation();40FirstSEHTryLoc = SourceLocation();41FirstVLALoc = SourceLocation();42FoundImmediateEscalatingExpression = false;4344// Coroutine state45FirstCoroutineStmtLoc = SourceLocation();46CoroutinePromise = nullptr;47CoroutineParameterMoves.clear();48NeedsCoroutineSuspends = true;49CoroutineSuspends.first = nullptr;50CoroutineSuspends.second = nullptr;5152SwitchStack.clear();53Returns.clear();54ErrorTrap.reset();55PossiblyUnreachableDiags.clear();56WeakObjectUses.clear();57ModifiedNonNullParams.clear();58Blocks.clear();59ByrefBlockVars.clear();60AddrLabels.clear();61}6263static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {64if (PropE->isExplicitProperty())65return PropE->getExplicitProperty();6667return PropE->getImplicitPropertyGetter();68}6970FunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy71FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {72E = E->IgnoreParenCasts();7374const NamedDecl *D = nullptr;75bool IsExact = false;7677switch (E->getStmtClass()) {78case Stmt::DeclRefExprClass:79D = cast<DeclRefExpr>(E)->getDecl();80IsExact = isa<VarDecl>(D);81break;82case Stmt::MemberExprClass: {83const MemberExpr *ME = cast<MemberExpr>(E);84D = ME->getMemberDecl();85IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts());86break;87}88case Stmt::ObjCIvarRefExprClass: {89const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E);90D = IE->getDecl();91IsExact = IE->getBase()->isObjCSelfExpr();92break;93}94case Stmt::PseudoObjectExprClass: {95const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E);96const ObjCPropertyRefExpr *BaseProp =97dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());98if (BaseProp) {99D = getBestPropertyDecl(BaseProp);100101if (BaseProp->isObjectReceiver()) {102const Expr *DoubleBase = BaseProp->getBase();103if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase))104DoubleBase = OVE->getSourceExpr();105106IsExact = DoubleBase->isObjCSelfExpr();107}108}109break;110}111default:112break;113}114115return BaseInfoTy(D, IsExact);116}117118FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(119const ObjCPropertyRefExpr *PropE)120: Base(nullptr, true), Property(getBestPropertyDecl(PropE)) {121122if (PropE->isObjectReceiver()) {123const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase());124const Expr *E = OVE->getSourceExpr();125Base = getBaseInfo(E);126} else if (PropE->isClassReceiver()) {127Base.setPointer(PropE->getClassReceiver());128} else {129assert(PropE->isSuperReceiver());130}131}132133FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,134const ObjCPropertyDecl *Prop)135: Base(nullptr, true), Property(Prop) {136if (BaseE)137Base = getBaseInfo(BaseE);138// else, this is a message accessing a property on super.139}140141FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(142const DeclRefExpr *DRE)143: Base(nullptr, true), Property(DRE->getDecl()) {144assert(isa<VarDecl>(Property));145}146147FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(148const ObjCIvarRefExpr *IvarE)149: Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) {150}151152void FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg,153const ObjCPropertyDecl *Prop) {154assert(Msg && Prop);155WeakUseVector &Uses =156WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)];157Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0));158}159160void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {161E = E->IgnoreParenCasts();162163if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {164markSafeWeakUse(POE->getSyntacticForm());165return;166}167168if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) {169markSafeWeakUse(Cond->getTrueExpr());170markSafeWeakUse(Cond->getFalseExpr());171return;172}173174if (const BinaryConditionalOperator *Cond =175dyn_cast<BinaryConditionalOperator>(E)) {176markSafeWeakUse(Cond->getCommon());177markSafeWeakUse(Cond->getFalseExpr());178return;179}180181// Has this weak object been seen before?182FunctionScopeInfo::WeakObjectUseMap::iterator Uses = WeakObjectUses.end();183if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {184if (!RefExpr->isObjectReceiver())185return;186if (isa<OpaqueValueExpr>(RefExpr->getBase()))187Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));188else {189markSafeWeakUse(RefExpr->getBase());190return;191}192}193else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))194Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));195else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {196if (isa<VarDecl>(DRE->getDecl()))197Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));198} else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {199if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {200if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {201Uses =202WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(),203Prop));204}205}206}207else208return;209210if (Uses == WeakObjectUses.end())211return;212213// Has there been a read from the object using this Expr?214FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse =215llvm::find(llvm::reverse(Uses->second), WeakUseTy(E, true));216if (ThisUse == Uses->second.rend())217return;218219ThisUse->markSafe();220}221222bool Capture::isInitCapture() const {223// Note that a nested capture of an init-capture is not itself an224// init-capture.225return !isNested() && isVariableCapture() && getVariable()->isInitCapture();226}227228bool CapturingScopeInfo::isVLATypeCaptured(const VariableArrayType *VAT) const {229for (auto &Cap : Captures)230if (Cap.isVLATypeCapture() && Cap.getCapturedVLAType() == VAT)231return true;232return false;233}234235void LambdaScopeInfo::visitPotentialCaptures(236llvm::function_ref<void(ValueDecl *, Expr *)> Callback) const {237for (Expr *E : PotentiallyCapturingExprs) {238if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {239Callback(cast<ValueDecl>(DRE->getFoundDecl()), E);240} else if (auto *ME = dyn_cast<MemberExpr>(E)) {241Callback(cast<ValueDecl>(ME->getMemberDecl()), E);242} else if (auto *FP = dyn_cast<FunctionParmPackExpr>(E)) {243for (ValueDecl *VD : *FP)244Callback(VD, E);245} else {246llvm_unreachable("unexpected expression in potential captures list");247}248}249}250251bool LambdaScopeInfo::lambdaCaptureShouldBeConst() const {252if (ExplicitObjectParameter)253return ExplicitObjectParameter->getType()254.getNonReferenceType()255.isConstQualified();256return !Mutable;257}258259FunctionScopeInfo::~FunctionScopeInfo() { }260BlockScopeInfo::~BlockScopeInfo() { }261CapturedRegionScopeInfo::~CapturedRegionScopeInfo() { }262263264