1 //===- Scope.h - Scope interface --------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the Scope interface.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_SEMA_SCOPE_H
15 #define LLVM_CLANG_SEMA_SCOPE_H
17 #include "clang/AST/Decl.h"
18 #include "clang/Basic/Diagnostic.h"
19 #include "llvm/ADT/PointerIntPair.h"
20 #include "llvm/ADT/SmallPtrSet.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/iterator_range.h"
35 class UsingDirectiveDecl;
38 /// Scope - A scope is a transient data structure that is used while parsing the
39 /// program. It assists with resolving identifiers to the appropriate
43 /// ScopeFlags - These are bitfields that are or'd together when creating a
44 /// scope, which defines the sorts of things the scope contains.
46 /// This indicates that the scope corresponds to a function, which
47 /// means that labels are set here.
50 /// This is a while, do, switch, for, etc that can have break
51 /// statements embedded into it.
54 /// This is a while, do, for, which can have continue statements
58 /// This is a scope that can contain a declaration. Some scopes
59 /// just contain loop constructs but don't contain decls.
62 /// The controlling scope in a if/switch/while/for statement.
65 /// The scope of a struct/union/class definition.
68 /// This is a scope that corresponds to a block/closure object.
69 /// Blocks serve as top-level scopes for some objects like labels, they
70 /// also prevent things like break and continue. BlockScopes always have
71 /// the FnScope and DeclScope flags set as well.
74 /// This is a scope that corresponds to the
75 /// template parameters of a C++ template. Template parameter
76 /// scope starts at the 'template' keyword and ends when the
77 /// template declaration ends.
78 TemplateParamScope = 0x80,
80 /// This is a scope that corresponds to the
81 /// parameters within a function prototype.
82 FunctionPrototypeScope = 0x100,
84 /// This is a scope that corresponds to the parameters within
85 /// a function prototype for a function declaration (as opposed to any
86 /// other kind of function declarator). Always has FunctionPrototypeScope
88 FunctionDeclarationScope = 0x200,
90 /// This is a scope that corresponds to the Objective-C
91 /// \@catch statement.
94 /// This scope corresponds to an Objective-C method body.
95 /// It always has FnScope and DeclScope set as well.
96 ObjCMethodScope = 0x800,
98 /// This is a scope that corresponds to a switch statement.
101 /// This is the scope of a C++ try statement.
104 /// This is the scope for a function-level C++ try or catch scope.
105 FnTryCatchScope = 0x4000,
107 /// This is the scope of OpenMP executable directive.
108 OpenMPDirectiveScope = 0x8000,
110 /// This is the scope of some OpenMP loop directive.
111 OpenMPLoopDirectiveScope = 0x10000,
113 /// This is the scope of some OpenMP simd directive.
114 /// For example, it is used for 'omp simd', 'omp for simd'.
115 /// This flag is propagated to children scopes.
116 OpenMPSimdDirectiveScope = 0x20000,
118 /// This scope corresponds to an enum.
121 /// This scope corresponds to an SEH try.
122 SEHTryScope = 0x80000,
124 /// This scope corresponds to an SEH except.
125 SEHExceptScope = 0x100000,
127 /// We are currently in the filter expression of an SEH except block.
128 SEHFilterScope = 0x200000,
130 /// This is a compound statement scope.
131 CompoundStmtScope = 0x400000,
133 /// We are between inheritance colon and the real class/struct definition scope.
134 ClassInheritanceScope = 0x800000,
138 /// The parent scope for this scope. This is null for the translation-unit
142 /// Flags - This contains a set of ScopeFlags, which indicates how the scope
143 /// interrelates with other control flow statements.
146 /// Depth - This is the depth of this scope. The translation-unit scope has
148 unsigned short Depth;
150 /// Declarations with static linkage are mangled with the number of
151 /// scopes seen as a component.
152 unsigned short MSLastManglingNumber;
154 unsigned short MSCurManglingNumber;
156 /// PrototypeDepth - This is the number of function prototype scopes
157 /// enclosing this scope, including this scope.
158 unsigned short PrototypeDepth;
160 /// PrototypeIndex - This is the number of parameters currently
161 /// declared in this scope.
162 unsigned short PrototypeIndex;
164 /// FnParent - If this scope has a parent scope that is a function body, this
165 /// pointer is non-null and points to it. This is used for label processing.
167 Scope *MSLastManglingParent;
169 /// BreakParent/ContinueParent - This is a direct link to the innermost
170 /// BreakScope/ContinueScope which contains the contents of this scope
171 /// for control flow purposes (and might be this scope itself), or null
172 /// if there is no such scope.
173 Scope *BreakParent, *ContinueParent;
175 /// BlockParent - This is a direct link to the immediately containing
176 /// BlockScope if this scope is not one, or null if there is none.
179 /// TemplateParamParent - This is a direct link to the
180 /// immediately containing template parameter scope. In the
181 /// case of nested templates, template parameter scopes can have
182 /// other template parameter scopes as parents.
183 Scope *TemplateParamParent;
185 /// DeclsInScope - This keeps track of all declarations in this scope. When
186 /// the declaration is added to the scope, it is set as the current
187 /// declaration for the identifier in the IdentifierTable. When the scope is
188 /// popped, these declarations are removed from the IdentifierTable's notion
189 /// of current declaration. It is up to the current Action implementation to
190 /// implement these semantics.
191 using DeclSetTy = llvm::SmallPtrSet<Decl *, 32>;
192 DeclSetTy DeclsInScope;
194 /// The DeclContext with which this scope is associated. For
195 /// example, the entity of a class scope is the class itself, the
196 /// entity of a function scope is a function, etc.
199 using UsingDirectivesTy = SmallVector<UsingDirectiveDecl *, 2>;
200 UsingDirectivesTy UsingDirectives;
202 /// Used to determine if errors occurred in this scope.
203 DiagnosticErrorTrap ErrorTrap;
205 /// A lattice consisting of undefined, a single NRVO candidate variable in
206 /// this scope, or over-defined. The bit is true when over-defined.
207 llvm::PointerIntPair<VarDecl *, 1, bool> NRVO;
209 void setFlags(Scope *Parent, unsigned F);
212 Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
214 Init(Parent, ScopeFlags);
217 /// getFlags - Return the flags for this scope.
218 unsigned getFlags() const { return Flags; }
220 void setFlags(unsigned F) { setFlags(getParent(), F); }
222 /// isBlockScope - Return true if this scope correspond to a closure.
223 bool isBlockScope() const { return Flags & BlockScope; }
225 /// getParent - Return the scope that this is nested in.
226 const Scope *getParent() const { return AnyParent; }
227 Scope *getParent() { return AnyParent; }
229 /// getFnParent - Return the closest scope that is a function body.
230 const Scope *getFnParent() const { return FnParent; }
231 Scope *getFnParent() { return FnParent; }
233 const Scope *getMSLastManglingParent() const {
234 return MSLastManglingParent;
236 Scope *getMSLastManglingParent() { return MSLastManglingParent; }
238 /// getContinueParent - Return the closest scope that a continue statement
239 /// would be affected by.
240 Scope *getContinueParent() {
241 return ContinueParent;
244 const Scope *getContinueParent() const {
245 return const_cast<Scope*>(this)->getContinueParent();
248 /// getBreakParent - Return the closest scope that a break statement
249 /// would be affected by.
250 Scope *getBreakParent() {
253 const Scope *getBreakParent() const {
254 return const_cast<Scope*>(this)->getBreakParent();
257 Scope *getBlockParent() { return BlockParent; }
258 const Scope *getBlockParent() const { return BlockParent; }
260 Scope *getTemplateParamParent() { return TemplateParamParent; }
261 const Scope *getTemplateParamParent() const { return TemplateParamParent; }
263 /// Returns the depth of this scope. The translation-unit has scope depth 0.
264 unsigned getDepth() const { return Depth; }
266 /// Returns the number of function prototype scopes in this scope
268 unsigned getFunctionPrototypeDepth() const {
269 return PrototypeDepth;
272 /// Return the number of parameters declared in this function
273 /// prototype, increasing it by one for the next call.
274 unsigned getNextFunctionPrototypeIndex() {
275 assert(isFunctionPrototypeScope());
276 return PrototypeIndex++;
279 using decl_range = llvm::iterator_range<DeclSetTy::iterator>;
281 decl_range decls() const {
282 return decl_range(DeclsInScope.begin(), DeclsInScope.end());
285 bool decl_empty() const { return DeclsInScope.empty(); }
287 void AddDecl(Decl *D) {
288 DeclsInScope.insert(D);
291 void RemoveDecl(Decl *D) {
292 DeclsInScope.erase(D);
295 void incrementMSManglingNumber() {
296 if (Scope *MSLMP = getMSLastManglingParent()) {
297 MSLMP->MSLastManglingNumber += 1;
298 MSCurManglingNumber += 1;
302 void decrementMSManglingNumber() {
303 if (Scope *MSLMP = getMSLastManglingParent()) {
304 MSLMP->MSLastManglingNumber -= 1;
305 MSCurManglingNumber -= 1;
309 unsigned getMSLastManglingNumber() const {
310 if (const Scope *MSLMP = getMSLastManglingParent())
311 return MSLMP->MSLastManglingNumber;
315 unsigned getMSCurManglingNumber() const {
316 return MSCurManglingNumber;
319 /// isDeclScope - Return true if this is the scope that the specified decl is
321 bool isDeclScope(Decl *D) {
322 return DeclsInScope.count(D) != 0;
325 DeclContext *getEntity() const { return Entity; }
326 void setEntity(DeclContext *E) { Entity = E; }
328 bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); }
330 bool hasUnrecoverableErrorOccurred() const {
331 return ErrorTrap.hasUnrecoverableErrorOccurred();
334 /// isFunctionScope() - Return true if this scope is a function scope.
335 bool isFunctionScope() const { return (getFlags() & Scope::FnScope); }
337 /// isClassScope - Return true if this scope is a class/struct/union scope.
338 bool isClassScope() const {
339 return (getFlags() & Scope::ClassScope);
342 /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
343 /// method scope or is inside one.
344 bool isInCXXInlineMethodScope() const {
345 if (const Scope *FnS = getFnParent()) {
346 assert(FnS->getParent() && "TUScope not created?");
347 return FnS->getParent()->isClassScope();
352 /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
353 /// Objective-C method body. Note that this method is not constant time.
354 bool isInObjcMethodScope() const {
355 for (const Scope *S = this; S; S = S->getParent()) {
356 // If this scope is an objc method scope, then we succeed.
357 if (S->getFlags() & ObjCMethodScope)
363 /// isInObjcMethodOuterScope - Return true if this scope is an
364 /// Objective-C method outer most body.
365 bool isInObjcMethodOuterScope() const {
366 if (const Scope *S = this) {
367 // If this scope is an objc method scope, then we succeed.
368 if (S->getFlags() & ObjCMethodScope)
374 /// isTemplateParamScope - Return true if this scope is a C++
375 /// template parameter scope.
376 bool isTemplateParamScope() const {
377 return getFlags() & Scope::TemplateParamScope;
380 /// isFunctionPrototypeScope - Return true if this scope is a
381 /// function prototype scope.
382 bool isFunctionPrototypeScope() const {
383 return getFlags() & Scope::FunctionPrototypeScope;
386 /// isAtCatchScope - Return true if this scope is \@catch.
387 bool isAtCatchScope() const {
388 return getFlags() & Scope::AtCatchScope;
391 /// isSwitchScope - Return true if this scope is a switch scope.
392 bool isSwitchScope() const {
393 for (const Scope *S = this; S; S = S->getParent()) {
394 if (S->getFlags() & Scope::SwitchScope)
396 else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
397 Scope::BlockScope | Scope::TemplateParamScope |
398 Scope::FunctionPrototypeScope |
399 Scope::AtCatchScope | Scope::ObjCMethodScope))
405 /// Determines whether this scope is the OpenMP directive scope
406 bool isOpenMPDirectiveScope() const {
407 return (getFlags() & Scope::OpenMPDirectiveScope);
410 /// Determine whether this scope is some OpenMP loop directive scope
411 /// (for example, 'omp for', 'omp simd').
412 bool isOpenMPLoopDirectiveScope() const {
413 if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
414 assert(isOpenMPDirectiveScope() &&
415 "OpenMP loop directive scope is not a directive scope");
421 /// Determine whether this scope is (or is nested into) some OpenMP
422 /// loop simd directive scope (for example, 'omp simd', 'omp for simd').
423 bool isOpenMPSimdDirectiveScope() const {
424 return getFlags() & Scope::OpenMPSimdDirectiveScope;
427 /// Determine whether this scope is a loop having OpenMP loop
428 /// directive attached.
429 bool isOpenMPLoopScope() const {
430 const Scope *P = getParent();
431 return P && P->isOpenMPLoopDirectiveScope();
434 /// Determine whether this scope is a C++ 'try' block.
435 bool isTryScope() const { return getFlags() & Scope::TryScope; }
437 /// Determine whether this scope is a SEH '__try' block.
438 bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
440 /// Determine whether this scope is a SEH '__except' block.
441 bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; }
443 /// Determine whether this scope is a compound statement scope.
444 bool isCompoundStmtScope() const {
445 return getFlags() & Scope::CompoundStmtScope;
448 /// Returns if rhs has a higher scope depth than this.
450 /// The caller is responsible for calling this only if one of the two scopes
451 /// is an ancestor of the other.
452 bool Contains(const Scope& rhs) const { return Depth < rhs.Depth; }
454 /// containedInPrototypeScope - Return true if this or a parent scope
455 /// is a FunctionPrototypeScope.
456 bool containedInPrototypeScope() const;
458 void PushUsingDirective(UsingDirectiveDecl *UDir) {
459 UsingDirectives.push_back(UDir);
462 using using_directives_range =
463 llvm::iterator_range<UsingDirectivesTy::iterator>;
465 using_directives_range using_directives() {
466 return using_directives_range(UsingDirectives.begin(),
467 UsingDirectives.end());
470 void addNRVOCandidate(VarDecl *VD) {
473 if (NRVO.getPointer() == nullptr) {
477 if (NRVO.getPointer() != VD)
483 NRVO.setPointer(nullptr);
486 void mergeNRVOIntoParent();
488 /// Init - This is used by the parser to implement scope caching.
489 void Init(Scope *parent, unsigned flags);
491 /// Sets up the specified scope flags and adjusts the scope state
492 /// variables accordingly.
493 void AddFlags(unsigned Flags);
495 void dumpImpl(raw_ostream &OS) const;
501 #endif // LLVM_CLANG_SEMA_SCOPE_H