clang API Documentation

ScopeInfo.cpp
Go to the documentation of this file.
00001 //===--- ScopeInfo.cpp - Information about a semantic context -------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements FunctionScopeInfo and its subclasses, which contain
00011 // information about a single function, block, lambda, or method body.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "clang/Sema/ScopeInfo.h"
00016 #include "clang/AST/Decl.h"
00017 #include "clang/AST/DeclCXX.h"
00018 #include "clang/AST/DeclObjC.h"
00019 #include "clang/AST/Expr.h"
00020 #include "clang/AST/ExprCXX.h"
00021 #include "clang/AST/ExprObjC.h"
00022 
00023 using namespace clang;
00024 using namespace sema;
00025 
00026 void FunctionScopeInfo::Clear() {
00027   HasBranchProtectedScope = false;
00028   HasBranchIntoScope = false;
00029   HasIndirectGoto = false;
00030   HasDroppedStmt = false;
00031   ObjCShouldCallSuper = false;
00032   ObjCIsDesignatedInit = false;
00033   ObjCWarnForNoDesignatedInitChain = false;
00034   ObjCIsSecondaryInit = false;
00035   ObjCWarnForNoInitDelegation = false;
00036 
00037   SwitchStack.clear();
00038   Returns.clear();
00039   ErrorTrap.reset();
00040   PossiblyUnreachableDiags.clear();
00041   WeakObjectUses.clear();
00042 }
00043 
00044 static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
00045   if (PropE->isExplicitProperty())
00046     return PropE->getExplicitProperty();
00047 
00048   return PropE->getImplicitPropertyGetter();
00049 }
00050 
00051 FunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy
00052 FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {
00053   E = E->IgnoreParenCasts();
00054 
00055   const NamedDecl *D = nullptr;
00056   bool IsExact = false;
00057 
00058   switch (E->getStmtClass()) {
00059   case Stmt::DeclRefExprClass:
00060     D = cast<DeclRefExpr>(E)->getDecl();
00061     IsExact = isa<VarDecl>(D);
00062     break;
00063   case Stmt::MemberExprClass: {
00064     const MemberExpr *ME = cast<MemberExpr>(E);
00065     D = ME->getMemberDecl();
00066     IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts());
00067     break;
00068   }
00069   case Stmt::ObjCIvarRefExprClass: {
00070     const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E);
00071     D = IE->getDecl();
00072     IsExact = IE->getBase()->isObjCSelfExpr();
00073     break;
00074   }
00075   case Stmt::PseudoObjectExprClass: {
00076     const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E);
00077     const ObjCPropertyRefExpr *BaseProp =
00078       dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
00079     if (BaseProp) {
00080       D = getBestPropertyDecl(BaseProp);
00081 
00082       const Expr *DoubleBase = BaseProp->getBase();
00083       if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase))
00084         DoubleBase = OVE->getSourceExpr();
00085 
00086       IsExact = DoubleBase->isObjCSelfExpr();
00087     }
00088     break;
00089   }
00090   default:
00091     break;
00092   }
00093 
00094   return BaseInfoTy(D, IsExact);
00095 }
00096 
00097 bool CapturingScopeInfo::isVLATypeCaptured(const VariableArrayType *VAT) const {
00098   RecordDecl *RD = nullptr;
00099   if (auto *LSI = dyn_cast<LambdaScopeInfo>(this))
00100     RD = LSI->Lambda;
00101   else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(this))
00102     RD = CRSI->TheRecordDecl;
00103 
00104   if (RD)
00105     for (auto *FD : RD->fields()) {
00106       if (FD->hasCapturedVLAType() && FD->getCapturedVLAType() == VAT)
00107         return true;
00108     }
00109   return false;
00110 }
00111 
00112 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
00113                                           const ObjCPropertyRefExpr *PropE)
00114     : Base(nullptr, true), Property(getBestPropertyDecl(PropE)) {
00115 
00116   if (PropE->isObjectReceiver()) {
00117     const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase());
00118     const Expr *E = OVE->getSourceExpr();
00119     Base = getBaseInfo(E);
00120   } else if (PropE->isClassReceiver()) {
00121     Base.setPointer(PropE->getClassReceiver());
00122   } else {
00123     assert(PropE->isSuperReceiver());
00124   }
00125 }
00126 
00127 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,
00128                                                 const ObjCPropertyDecl *Prop)
00129     : Base(nullptr, true), Property(Prop) {
00130   if (BaseE)
00131     Base = getBaseInfo(BaseE);
00132   // else, this is a message accessing a property on super.
00133 }
00134 
00135 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
00136                                                       const DeclRefExpr *DRE)
00137   : Base(nullptr, true), Property(DRE->getDecl()) {
00138   assert(isa<VarDecl>(Property));
00139 }
00140 
00141 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
00142                                                   const ObjCIvarRefExpr *IvarE)
00143   : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) {
00144 }
00145 
00146 void FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg,
00147                                         const ObjCPropertyDecl *Prop) {
00148   assert(Msg && Prop);
00149   WeakUseVector &Uses =
00150     WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)];
00151   Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0));
00152 }
00153 
00154 void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
00155   E = E->IgnoreParenCasts();
00156 
00157   if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
00158     markSafeWeakUse(POE->getSyntacticForm());
00159     return;
00160   }
00161 
00162   if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) {
00163     markSafeWeakUse(Cond->getTrueExpr());
00164     markSafeWeakUse(Cond->getFalseExpr());
00165     return;
00166   }
00167 
00168   if (const BinaryConditionalOperator *Cond =
00169         dyn_cast<BinaryConditionalOperator>(E)) {
00170     markSafeWeakUse(Cond->getCommon());
00171     markSafeWeakUse(Cond->getFalseExpr());
00172     return;
00173   }
00174 
00175   // Has this weak object been seen before?
00176   FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
00177   if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
00178     if (isa<OpaqueValueExpr>(RefExpr->getBase()))
00179      Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
00180     else {
00181       markSafeWeakUse(RefExpr->getBase());
00182       return;
00183     }
00184   }
00185   else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
00186     Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
00187   else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
00188     Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
00189   else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
00190     Uses = WeakObjectUses.end();
00191     if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
00192       if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
00193         Uses =
00194           WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(),
00195                                                   Prop));
00196       }
00197     }
00198   }
00199   else
00200     return;
00201 
00202   if (Uses == WeakObjectUses.end())
00203     return;
00204 
00205   // Has there been a read from the object using this Expr?
00206   FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse =
00207     std::find(Uses->second.rbegin(), Uses->second.rend(), WeakUseTy(E, true));
00208   if (ThisUse == Uses->second.rend())
00209     return;
00210 
00211   ThisUse->markSafe();
00212 }
00213 
00214 void LambdaScopeInfo::getPotentialVariableCapture(unsigned Idx, VarDecl *&VD,
00215                                                   Expr *&E) const {
00216   assert(Idx < getNumPotentialVariableCaptures() &&
00217          "Index of potential capture must be within 0 to less than the "
00218          "number of captures!");
00219   E = PotentiallyCapturingExprs[Idx];
00220   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
00221     VD = dyn_cast<VarDecl>(DRE->getFoundDecl());
00222   else if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
00223     VD = dyn_cast<VarDecl>(ME->getMemberDecl());
00224   else
00225     llvm_unreachable("Only DeclRefExprs or MemberExprs should be added for "
00226     "potential captures");
00227   assert(VD);
00228 }
00229 
00230 FunctionScopeInfo::~FunctionScopeInfo() { }
00231 BlockScopeInfo::~BlockScopeInfo() { }
00232 LambdaScopeInfo::~LambdaScopeInfo() { }
00233 CapturedRegionScopeInfo::~CapturedRegionScopeInfo() { }