Scope.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- Scope.h - Scope interface --------------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines the Scope interface.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_CLANG_SEMA_SCOPE_H
  18. #define LLVM_CLANG_SEMA_SCOPE_H
  19. #include "clang/AST/Decl.h"
  20. #include "clang/Basic/Diagnostic.h"
  21. #include "llvm/ADT/PointerIntPair.h"
  22. #include "llvm/ADT/SmallPtrSet.h"
  23. #include "llvm/ADT/SmallVector.h"
  24. #include "llvm/ADT/iterator_range.h"
  25. #include <cassert>
  26. #include <optional>
  27. namespace llvm {
  28. class raw_ostream;
  29. } // namespace llvm
  30. namespace clang {
  31. class Decl;
  32. class DeclContext;
  33. class UsingDirectiveDecl;
  34. class VarDecl;
  35. /// Scope - A scope is a transient data structure that is used while parsing the
  36. /// program. It assists with resolving identifiers to the appropriate
  37. /// declaration.
  38. class Scope {
  39. public:
  40. /// ScopeFlags - These are bitfields that are or'd together when creating a
  41. /// scope, which defines the sorts of things the scope contains.
  42. enum ScopeFlags {
  43. /// This indicates that the scope corresponds to a function, which
  44. /// means that labels are set here.
  45. FnScope = 0x01,
  46. /// This is a while, do, switch, for, etc that can have break
  47. /// statements embedded into it.
  48. BreakScope = 0x02,
  49. /// This is a while, do, for, which can have continue statements
  50. /// embedded into it.
  51. ContinueScope = 0x04,
  52. /// This is a scope that can contain a declaration. Some scopes
  53. /// just contain loop constructs but don't contain decls.
  54. DeclScope = 0x08,
  55. /// The controlling scope in a if/switch/while/for statement.
  56. ControlScope = 0x10,
  57. /// The scope of a struct/union/class definition.
  58. ClassScope = 0x20,
  59. /// This is a scope that corresponds to a block/closure object.
  60. /// Blocks serve as top-level scopes for some objects like labels, they
  61. /// also prevent things like break and continue. BlockScopes always have
  62. /// the FnScope and DeclScope flags set as well.
  63. BlockScope = 0x40,
  64. /// This is a scope that corresponds to the
  65. /// template parameters of a C++ template. Template parameter
  66. /// scope starts at the 'template' keyword and ends when the
  67. /// template declaration ends.
  68. TemplateParamScope = 0x80,
  69. /// This is a scope that corresponds to the
  70. /// parameters within a function prototype.
  71. FunctionPrototypeScope = 0x100,
  72. /// This is a scope that corresponds to the parameters within
  73. /// a function prototype for a function declaration (as opposed to any
  74. /// other kind of function declarator). Always has FunctionPrototypeScope
  75. /// set as well.
  76. FunctionDeclarationScope = 0x200,
  77. /// This is a scope that corresponds to the Objective-C
  78. /// \@catch statement.
  79. AtCatchScope = 0x400,
  80. /// This scope corresponds to an Objective-C method body.
  81. /// It always has FnScope and DeclScope set as well.
  82. ObjCMethodScope = 0x800,
  83. /// This is a scope that corresponds to a switch statement.
  84. SwitchScope = 0x1000,
  85. /// This is the scope of a C++ try statement.
  86. TryScope = 0x2000,
  87. /// This is the scope for a function-level C++ try or catch scope.
  88. FnTryCatchScope = 0x4000,
  89. /// This is the scope of OpenMP executable directive.
  90. OpenMPDirectiveScope = 0x8000,
  91. /// This is the scope of some OpenMP loop directive.
  92. OpenMPLoopDirectiveScope = 0x10000,
  93. /// This is the scope of some OpenMP simd directive.
  94. /// For example, it is used for 'omp simd', 'omp for simd'.
  95. /// This flag is propagated to children scopes.
  96. OpenMPSimdDirectiveScope = 0x20000,
  97. /// This scope corresponds to an enum.
  98. EnumScope = 0x40000,
  99. /// This scope corresponds to an SEH try.
  100. SEHTryScope = 0x80000,
  101. /// This scope corresponds to an SEH except.
  102. SEHExceptScope = 0x100000,
  103. /// We are currently in the filter expression of an SEH except block.
  104. SEHFilterScope = 0x200000,
  105. /// This is a compound statement scope.
  106. CompoundStmtScope = 0x400000,
  107. /// We are between inheritance colon and the real class/struct definition
  108. /// scope.
  109. ClassInheritanceScope = 0x800000,
  110. /// This is the scope of a C++ catch statement.
  111. CatchScope = 0x1000000,
  112. /// This is a scope in which a condition variable is currently being
  113. /// parsed. If such a scope is a ContinueScope, it's invalid to jump to the
  114. /// continue block from here.
  115. ConditionVarScope = 0x2000000,
  116. /// This is a scope of some OpenMP directive with
  117. /// order clause which specifies concurrent
  118. OpenMPOrderClauseScope = 0x4000000,
  119. };
  120. private:
  121. /// The parent scope for this scope. This is null for the translation-unit
  122. /// scope.
  123. Scope *AnyParent;
  124. /// Flags - This contains a set of ScopeFlags, which indicates how the scope
  125. /// interrelates with other control flow statements.
  126. unsigned Flags;
  127. /// Depth - This is the depth of this scope. The translation-unit scope has
  128. /// depth 0.
  129. unsigned short Depth;
  130. /// Declarations with static linkage are mangled with the number of
  131. /// scopes seen as a component.
  132. unsigned short MSLastManglingNumber;
  133. unsigned short MSCurManglingNumber;
  134. /// PrototypeDepth - This is the number of function prototype scopes
  135. /// enclosing this scope, including this scope.
  136. unsigned short PrototypeDepth;
  137. /// PrototypeIndex - This is the number of parameters currently
  138. /// declared in this scope.
  139. unsigned short PrototypeIndex;
  140. /// FnParent - If this scope has a parent scope that is a function body, this
  141. /// pointer is non-null and points to it. This is used for label processing.
  142. Scope *FnParent;
  143. Scope *MSLastManglingParent;
  144. /// BreakParent/ContinueParent - This is a direct link to the innermost
  145. /// BreakScope/ContinueScope which contains the contents of this scope
  146. /// for control flow purposes (and might be this scope itself), or null
  147. /// if there is no such scope.
  148. Scope *BreakParent, *ContinueParent;
  149. /// BlockParent - This is a direct link to the immediately containing
  150. /// BlockScope if this scope is not one, or null if there is none.
  151. Scope *BlockParent;
  152. /// TemplateParamParent - This is a direct link to the
  153. /// immediately containing template parameter scope. In the
  154. /// case of nested templates, template parameter scopes can have
  155. /// other template parameter scopes as parents.
  156. Scope *TemplateParamParent;
  157. /// DeclsInScope - This keeps track of all declarations in this scope. When
  158. /// the declaration is added to the scope, it is set as the current
  159. /// declaration for the identifier in the IdentifierTable. When the scope is
  160. /// popped, these declarations are removed from the IdentifierTable's notion
  161. /// of current declaration. It is up to the current Action implementation to
  162. /// implement these semantics.
  163. using DeclSetTy = llvm::SmallPtrSet<Decl *, 32>;
  164. DeclSetTy DeclsInScope;
  165. /// The DeclContext with which this scope is associated. For
  166. /// example, the entity of a class scope is the class itself, the
  167. /// entity of a function scope is a function, etc.
  168. DeclContext *Entity;
  169. using UsingDirectivesTy = SmallVector<UsingDirectiveDecl *, 2>;
  170. UsingDirectivesTy UsingDirectives;
  171. /// Used to determine if errors occurred in this scope.
  172. DiagnosticErrorTrap ErrorTrap;
  173. /// A single NRVO candidate variable in this scope.
  174. /// There are three possible values:
  175. /// 1) pointer to VarDecl that denotes NRVO candidate itself.
  176. /// 2) nullptr value means that NRVO is not allowed in this scope
  177. /// (e.g. return a function parameter).
  178. /// 3) std::nullopt value means that there is no NRVO candidate in this scope
  179. /// (i.e. there are no return statements in this scope).
  180. std::optional<VarDecl *> NRVO;
  181. /// Represents return slots for NRVO candidates in the current scope.
  182. /// If a variable is present in this set, it means that a return slot is
  183. /// available for this variable in the current scope.
  184. llvm::SmallPtrSet<VarDecl *, 8> ReturnSlots;
  185. void setFlags(Scope *Parent, unsigned F);
  186. public:
  187. Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
  188. : ErrorTrap(Diag) {
  189. Init(Parent, ScopeFlags);
  190. }
  191. /// getFlags - Return the flags for this scope.
  192. unsigned getFlags() const { return Flags; }
  193. void setFlags(unsigned F) { setFlags(getParent(), F); }
  194. /// isBlockScope - Return true if this scope correspond to a closure.
  195. bool isBlockScope() const { return Flags & BlockScope; }
  196. /// getParent - Return the scope that this is nested in.
  197. const Scope *getParent() const { return AnyParent; }
  198. Scope *getParent() { return AnyParent; }
  199. /// getFnParent - Return the closest scope that is a function body.
  200. const Scope *getFnParent() const { return FnParent; }
  201. Scope *getFnParent() { return FnParent; }
  202. const Scope *getMSLastManglingParent() const {
  203. return MSLastManglingParent;
  204. }
  205. Scope *getMSLastManglingParent() { return MSLastManglingParent; }
  206. /// getContinueParent - Return the closest scope that a continue statement
  207. /// would be affected by.
  208. Scope *getContinueParent() {
  209. return ContinueParent;
  210. }
  211. const Scope *getContinueParent() const {
  212. return const_cast<Scope*>(this)->getContinueParent();
  213. }
  214. // Set whether we're in the scope of a condition variable, where 'continue'
  215. // is disallowed despite being a continue scope.
  216. void setIsConditionVarScope(bool InConditionVarScope) {
  217. Flags = (Flags & ~ConditionVarScope) |
  218. (InConditionVarScope ? ConditionVarScope : 0);
  219. }
  220. bool isConditionVarScope() const {
  221. return Flags & ConditionVarScope;
  222. }
  223. /// getBreakParent - Return the closest scope that a break statement
  224. /// would be affected by.
  225. Scope *getBreakParent() {
  226. return BreakParent;
  227. }
  228. const Scope *getBreakParent() const {
  229. return const_cast<Scope*>(this)->getBreakParent();
  230. }
  231. Scope *getBlockParent() { return BlockParent; }
  232. const Scope *getBlockParent() const { return BlockParent; }
  233. Scope *getTemplateParamParent() { return TemplateParamParent; }
  234. const Scope *getTemplateParamParent() const { return TemplateParamParent; }
  235. /// Returns the depth of this scope. The translation-unit has scope depth 0.
  236. unsigned getDepth() const { return Depth; }
  237. /// Returns the number of function prototype scopes in this scope
  238. /// chain.
  239. unsigned getFunctionPrototypeDepth() const {
  240. return PrototypeDepth;
  241. }
  242. /// Return the number of parameters declared in this function
  243. /// prototype, increasing it by one for the next call.
  244. unsigned getNextFunctionPrototypeIndex() {
  245. assert(isFunctionPrototypeScope());
  246. return PrototypeIndex++;
  247. }
  248. using decl_range = llvm::iterator_range<DeclSetTy::iterator>;
  249. decl_range decls() const {
  250. return decl_range(DeclsInScope.begin(), DeclsInScope.end());
  251. }
  252. bool decl_empty() const { return DeclsInScope.empty(); }
  253. void AddDecl(Decl *D) {
  254. if (auto *VD = dyn_cast<VarDecl>(D))
  255. if (!isa<ParmVarDecl>(VD))
  256. ReturnSlots.insert(VD);
  257. DeclsInScope.insert(D);
  258. }
  259. void RemoveDecl(Decl *D) { DeclsInScope.erase(D); }
  260. void incrementMSManglingNumber() {
  261. if (Scope *MSLMP = getMSLastManglingParent()) {
  262. MSLMP->MSLastManglingNumber += 1;
  263. MSCurManglingNumber += 1;
  264. }
  265. }
  266. void decrementMSManglingNumber() {
  267. if (Scope *MSLMP = getMSLastManglingParent()) {
  268. MSLMP->MSLastManglingNumber -= 1;
  269. MSCurManglingNumber -= 1;
  270. }
  271. }
  272. unsigned getMSLastManglingNumber() const {
  273. if (const Scope *MSLMP = getMSLastManglingParent())
  274. return MSLMP->MSLastManglingNumber;
  275. return 1;
  276. }
  277. unsigned getMSCurManglingNumber() const {
  278. return MSCurManglingNumber;
  279. }
  280. /// isDeclScope - Return true if this is the scope that the specified decl is
  281. /// declared in.
  282. bool isDeclScope(const Decl *D) const { return DeclsInScope.contains(D); }
  283. /// Get the entity corresponding to this scope.
  284. DeclContext *getEntity() const {
  285. return isTemplateParamScope() ? nullptr : Entity;
  286. }
  287. /// Get the DeclContext in which to continue unqualified lookup after a
  288. /// lookup in this scope.
  289. DeclContext *getLookupEntity() const { return Entity; }
  290. void setEntity(DeclContext *E) {
  291. assert(!isTemplateParamScope() &&
  292. "entity associated with template param scope");
  293. Entity = E;
  294. }
  295. void setLookupEntity(DeclContext *E) { Entity = E; }
  296. /// Determine whether any unrecoverable errors have occurred within this
  297. /// scope. Note that this may return false even if the scope contains invalid
  298. /// declarations or statements, if the errors for those invalid constructs
  299. /// were suppressed because some prior invalid construct was referenced.
  300. bool hasUnrecoverableErrorOccurred() const {
  301. return ErrorTrap.hasUnrecoverableErrorOccurred();
  302. }
  303. /// isFunctionScope() - Return true if this scope is a function scope.
  304. bool isFunctionScope() const { return getFlags() & Scope::FnScope; }
  305. /// isClassScope - Return true if this scope is a class/struct/union scope.
  306. bool isClassScope() const { return getFlags() & Scope::ClassScope; }
  307. /// Determines whether this scope is between inheritance colon and the real
  308. /// class/struct definition.
  309. bool isClassInheritanceScope() const {
  310. return getFlags() & Scope::ClassInheritanceScope;
  311. }
  312. /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
  313. /// method scope or is inside one.
  314. bool isInCXXInlineMethodScope() const {
  315. if (const Scope *FnS = getFnParent()) {
  316. assert(FnS->getParent() && "TUScope not created?");
  317. return FnS->getParent()->isClassScope();
  318. }
  319. return false;
  320. }
  321. /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
  322. /// Objective-C method body. Note that this method is not constant time.
  323. bool isInObjcMethodScope() const {
  324. for (const Scope *S = this; S; S = S->getParent()) {
  325. // If this scope is an objc method scope, then we succeed.
  326. if (S->getFlags() & ObjCMethodScope)
  327. return true;
  328. }
  329. return false;
  330. }
  331. /// isInObjcMethodOuterScope - Return true if this scope is an
  332. /// Objective-C method outer most body.
  333. bool isInObjcMethodOuterScope() const {
  334. if (const Scope *S = this) {
  335. // If this scope is an objc method scope, then we succeed.
  336. if (S->getFlags() & ObjCMethodScope)
  337. return true;
  338. }
  339. return false;
  340. }
  341. /// isTemplateParamScope - Return true if this scope is a C++
  342. /// template parameter scope.
  343. bool isTemplateParamScope() const {
  344. return getFlags() & Scope::TemplateParamScope;
  345. }
  346. /// isFunctionPrototypeScope - Return true if this scope is a
  347. /// function prototype scope.
  348. bool isFunctionPrototypeScope() const {
  349. return getFlags() & Scope::FunctionPrototypeScope;
  350. }
  351. /// isFunctionDeclarationScope - Return true if this scope is a
  352. /// function prototype scope.
  353. bool isFunctionDeclarationScope() const {
  354. return getFlags() & Scope::FunctionDeclarationScope;
  355. }
  356. /// isAtCatchScope - Return true if this scope is \@catch.
  357. bool isAtCatchScope() const {
  358. return getFlags() & Scope::AtCatchScope;
  359. }
  360. /// isCatchScope - Return true if this scope is a C++ catch statement.
  361. bool isCatchScope() const { return getFlags() & Scope::CatchScope; }
  362. /// isSwitchScope - Return true if this scope is a switch scope.
  363. bool isSwitchScope() const {
  364. for (const Scope *S = this; S; S = S->getParent()) {
  365. if (S->getFlags() & Scope::SwitchScope)
  366. return true;
  367. else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
  368. Scope::BlockScope | Scope::TemplateParamScope |
  369. Scope::FunctionPrototypeScope |
  370. Scope::AtCatchScope | Scope::ObjCMethodScope))
  371. return false;
  372. }
  373. return false;
  374. }
  375. /// Determines whether this scope is the OpenMP directive scope
  376. bool isOpenMPDirectiveScope() const {
  377. return (getFlags() & Scope::OpenMPDirectiveScope);
  378. }
  379. /// Determine whether this scope is some OpenMP loop directive scope
  380. /// (for example, 'omp for', 'omp simd').
  381. bool isOpenMPLoopDirectiveScope() const {
  382. if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
  383. assert(isOpenMPDirectiveScope() &&
  384. "OpenMP loop directive scope is not a directive scope");
  385. return true;
  386. }
  387. return false;
  388. }
  389. /// Determine whether this scope is (or is nested into) some OpenMP
  390. /// loop simd directive scope (for example, 'omp simd', 'omp for simd').
  391. bool isOpenMPSimdDirectiveScope() const {
  392. return getFlags() & Scope::OpenMPSimdDirectiveScope;
  393. }
  394. /// Determine whether this scope is a loop having OpenMP loop
  395. /// directive attached.
  396. bool isOpenMPLoopScope() const {
  397. const Scope *P = getParent();
  398. return P && P->isOpenMPLoopDirectiveScope();
  399. }
  400. /// Determine whether this scope is some OpenMP directive with
  401. /// order clause which specifies concurrent scope.
  402. bool isOpenMPOrderClauseScope() const {
  403. return getFlags() & Scope::OpenMPOrderClauseScope;
  404. }
  405. /// Determine whether this scope is a while/do/for statement, which can have
  406. /// continue statements embedded into it.
  407. bool isContinueScope() const {
  408. return getFlags() & ScopeFlags::ContinueScope;
  409. }
  410. /// Determine whether this scope is a C++ 'try' block.
  411. bool isTryScope() const { return getFlags() & Scope::TryScope; }
  412. /// Determine whether this scope is a function-level C++ try or catch scope.
  413. bool isFnTryCatchScope() const {
  414. return getFlags() & ScopeFlags::FnTryCatchScope;
  415. }
  416. /// Determine whether this scope is a SEH '__try' block.
  417. bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
  418. /// Determine whether this scope is a SEH '__except' block.
  419. bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; }
  420. /// Determine whether this scope is a compound statement scope.
  421. bool isCompoundStmtScope() const {
  422. return getFlags() & Scope::CompoundStmtScope;
  423. }
  424. /// Determine whether this scope is a controlling scope in a
  425. /// if/switch/while/for statement.
  426. bool isControlScope() const { return getFlags() & Scope::ControlScope; }
  427. /// Returns if rhs has a higher scope depth than this.
  428. ///
  429. /// The caller is responsible for calling this only if one of the two scopes
  430. /// is an ancestor of the other.
  431. bool Contains(const Scope& rhs) const { return Depth < rhs.Depth; }
  432. /// containedInPrototypeScope - Return true if this or a parent scope
  433. /// is a FunctionPrototypeScope.
  434. bool containedInPrototypeScope() const;
  435. void PushUsingDirective(UsingDirectiveDecl *UDir) {
  436. UsingDirectives.push_back(UDir);
  437. }
  438. using using_directives_range =
  439. llvm::iterator_range<UsingDirectivesTy::iterator>;
  440. using_directives_range using_directives() {
  441. return using_directives_range(UsingDirectives.begin(),
  442. UsingDirectives.end());
  443. }
  444. void updateNRVOCandidate(VarDecl *VD);
  445. void applyNRVO();
  446. /// Init - This is used by the parser to implement scope caching.
  447. void Init(Scope *parent, unsigned flags);
  448. /// Sets up the specified scope flags and adjusts the scope state
  449. /// variables accordingly.
  450. void AddFlags(unsigned Flags);
  451. void dumpImpl(raw_ostream &OS) const;
  452. void dump() const;
  453. };
  454. } // namespace clang
  455. #endif // LLVM_CLANG_SEMA_SCOPE_H
  456. #ifdef __GNUC__
  457. #pragma GCC diagnostic pop
  458. #endif