ScopeInfo.cpp 8.1 KB

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