ScopeInfo.cpp 8.1 KB

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