ScopeInfo.cpp 8.0 KB

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