clang API Documentation
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() { }