1 //===- Scope.h - Scope interface --------------------------------*- C++ -*-===//
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 defines the Scope interface.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_SEMA_SCOPE_H
14 #define LLVM_CLANG_SEMA_SCOPE_H
15 
16 #include "clang/AST/Decl.h"
17 #include "clang/Basic/Diagnostic.h"
18 #include "llvm/ADT/PointerIntPair.h"
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/iterator_range.h"
22 #include <cassert>
23 #include <optional>
24 
25 namespace llvm {
26 
27 class raw_ostream;
28 
29 } // namespace llvm
30 
31 namespace clang {
32 
33 class Decl;
34 class DeclContext;
35 class UsingDirectiveDecl;
36 class VarDecl;
37 
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
40 /// declaration.
41 class Scope {
42 public:
43   /// ScopeFlags - These are bitfields that are or'd together when creating a
44   /// scope, which defines the sorts of things the scope contains.
45   enum ScopeFlags {
46     // A bitfield value representing no scopes.
47     NoScope = 0,
48 
49     /// This indicates that the scope corresponds to a function, which
50     /// means that labels are set here.
51     FnScope = 0x01,
52 
53     /// This is a while, do, switch, for, etc that can have break
54     /// statements embedded into it.
55     BreakScope = 0x02,
56 
57     /// This is a while, do, for, which can have continue statements
58     /// embedded into it.
59     ContinueScope = 0x04,
60 
61     /// This is a scope that can contain a declaration.  Some scopes
62     /// just contain loop constructs but don't contain decls.
63     DeclScope = 0x08,
64 
65     /// The controlling scope in a if/switch/while/for statement.
66     ControlScope = 0x10,
67 
68     /// The scope of a struct/union/class definition.
69     ClassScope = 0x20,
70 
71     /// This is a scope that corresponds to a block/closure object.
72     /// Blocks serve as top-level scopes for some objects like labels, they
73     /// also prevent things like break and continue.  BlockScopes always have
74     /// the FnScope and DeclScope flags set as well.
75     BlockScope = 0x40,
76 
77     /// This is a scope that corresponds to the
78     /// template parameters of a C++ template. Template parameter
79     /// scope starts at the 'template' keyword and ends when the
80     /// template declaration ends.
81     TemplateParamScope = 0x80,
82 
83     /// This is a scope that corresponds to the
84     /// parameters within a function prototype.
85     FunctionPrototypeScope = 0x100,
86 
87     /// This is a scope that corresponds to the parameters within
88     /// a function prototype for a function declaration (as opposed to any
89     /// other kind of function declarator). Always has FunctionPrototypeScope
90     /// set as well.
91     FunctionDeclarationScope = 0x200,
92 
93     /// This is a scope that corresponds to the Objective-C
94     /// \@catch statement.
95     AtCatchScope = 0x400,
96 
97     /// This scope corresponds to an Objective-C method body.
98     /// It always has FnScope and DeclScope set as well.
99     ObjCMethodScope = 0x800,
100 
101     /// This is a scope that corresponds to a switch statement.
102     SwitchScope = 0x1000,
103 
104     /// This is the scope of a C++ try statement.
105     TryScope = 0x2000,
106 
107     /// This is the scope for a function-level C++ try or catch scope.
108     FnTryCatchScope = 0x4000,
109 
110     /// This is the scope of OpenMP executable directive.
111     OpenMPDirectiveScope = 0x8000,
112 
113     /// This is the scope of some OpenMP loop directive.
114     OpenMPLoopDirectiveScope = 0x10000,
115 
116     /// This is the scope of some OpenMP simd directive.
117     /// For example, it is used for 'omp simd', 'omp for simd'.
118     /// This flag is propagated to children scopes.
119     OpenMPSimdDirectiveScope = 0x20000,
120 
121     /// This scope corresponds to an enum.
122     EnumScope = 0x40000,
123 
124     /// This scope corresponds to an SEH try.
125     SEHTryScope = 0x80000,
126 
127     /// This scope corresponds to an SEH except.
128     SEHExceptScope = 0x100000,
129 
130     /// We are currently in the filter expression of an SEH except block.
131     SEHFilterScope = 0x200000,
132 
133     /// This is a compound statement scope.
134     CompoundStmtScope = 0x400000,
135 
136     /// We are between inheritance colon and the real class/struct definition
137     /// scope.
138     ClassInheritanceScope = 0x800000,
139 
140     /// This is the scope of a C++ catch statement.
141     CatchScope = 0x1000000,
142 
143     /// This is a scope in which a condition variable is currently being
144     /// parsed. If such a scope is a ContinueScope, it's invalid to jump to the
145     /// continue block from here.
146     ConditionVarScope = 0x2000000,
147 
148     /// This is a scope of some OpenMP directive with
149     /// order clause which specifies concurrent
150     OpenMPOrderClauseScope = 0x4000000,
151     /// This is the scope for a lambda, after the lambda introducer.
152     /// Lambdas need two FunctionPrototypeScope scopes (because there is a
153     /// template scope in between), the outer scope does not increase the
154     /// depth of recursion.
155     LambdaScope = 0x8000000,
156     /// This is the scope of an OpenACC Compute Construct, which restricts
157     /// jumping into/out of it.
158     OpenACCComputeConstructScope = 0x10000000,
159   };
160 
161 private:
162   /// The parent scope for this scope.  This is null for the translation-unit
163   /// scope.
164   Scope *AnyParent;
165 
166   /// Flags - This contains a set of ScopeFlags, which indicates how the scope
167   /// interrelates with other control flow statements.
168   unsigned Flags;
169 
170   /// Depth - This is the depth of this scope.  The translation-unit scope has
171   /// depth 0.
172   unsigned short Depth;
173 
174   /// Declarations with static linkage are mangled with the number of
175   /// scopes seen as a component.
176   unsigned short MSLastManglingNumber;
177 
178   unsigned short MSCurManglingNumber;
179 
180   /// PrototypeDepth - This is the number of function prototype scopes
181   /// enclosing this scope, including this scope.
182   unsigned short PrototypeDepth;
183 
184   /// PrototypeIndex - This is the number of parameters currently
185   /// declared in this scope.
186   unsigned short PrototypeIndex;
187 
188   /// FnParent - If this scope has a parent scope that is a function body, this
189   /// pointer is non-null and points to it.  This is used for label processing.
190   Scope *FnParent;
191   Scope *MSLastManglingParent;
192 
193   /// BreakParent/ContinueParent - This is a direct link to the innermost
194   /// BreakScope/ContinueScope which contains the contents of this scope
195   /// for control flow purposes (and might be this scope itself), or null
196   /// if there is no such scope.
197   Scope *BreakParent, *ContinueParent;
198 
199   /// BlockParent - This is a direct link to the immediately containing
200   /// BlockScope if this scope is not one, or null if there is none.
201   Scope *BlockParent;
202 
203   /// TemplateParamParent - This is a direct link to the
204   /// immediately containing template parameter scope. In the
205   /// case of nested templates, template parameter scopes can have
206   /// other template parameter scopes as parents.
207   Scope *TemplateParamParent;
208 
209   /// DeclScopeParent - This is a direct link to the immediately containing
210   /// DeclScope, i.e. scope which can contain declarations.
211   Scope *DeclParent;
212 
213   /// DeclsInScope - This keeps track of all declarations in this scope.  When
214   /// the declaration is added to the scope, it is set as the current
215   /// declaration for the identifier in the IdentifierTable.  When the scope is
216   /// popped, these declarations are removed from the IdentifierTable's notion
217   /// of current declaration.  It is up to the current Action implementation to
218   /// implement these semantics.
219   using DeclSetTy = llvm::SmallPtrSet<Decl *, 32>;
220   DeclSetTy DeclsInScope;
221 
222   /// The DeclContext with which this scope is associated. For
223   /// example, the entity of a class scope is the class itself, the
224   /// entity of a function scope is a function, etc.
225   DeclContext *Entity;
226 
227   using UsingDirectivesTy = SmallVector<UsingDirectiveDecl *, 2>;
228   UsingDirectivesTy UsingDirectives;
229 
230   /// Used to determine if errors occurred in this scope.
231   DiagnosticErrorTrap ErrorTrap;
232 
233   /// A single NRVO candidate variable in this scope.
234   /// There are three possible values:
235   ///  1) pointer to VarDecl that denotes NRVO candidate itself.
236   ///  2) nullptr value means that NRVO is not allowed in this scope
237   ///     (e.g. return a function parameter).
238   ///  3) std::nullopt value means that there is no NRVO candidate in this scope
239   ///     (i.e. there are no return statements in this scope).
240   std::optional<VarDecl *> NRVO;
241 
242   /// Represents return slots for NRVO candidates in the current scope.
243   /// If a variable is present in this set, it means that a return slot is
244   /// available for this variable in the current scope.
245   llvm::SmallPtrSet<VarDecl *, 8> ReturnSlots;
246 
247   void setFlags(Scope *Parent, unsigned F);
248 
249 public:
Scope(Scope * Parent,unsigned ScopeFlags,DiagnosticsEngine & Diag)250   Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
251       : ErrorTrap(Diag) {
252     Init(Parent, ScopeFlags);
253   }
254 
255   /// getFlags - Return the flags for this scope.
getFlags()256   unsigned getFlags() const { return Flags; }
257 
setFlags(unsigned F)258   void setFlags(unsigned F) { setFlags(getParent(), F); }
259 
260   /// isBlockScope - Return true if this scope correspond to a closure.
isBlockScope()261   bool isBlockScope() const { return Flags & BlockScope; }
262 
263   /// getParent - Return the scope that this is nested in.
getParent()264   const Scope *getParent() const { return AnyParent; }
getParent()265   Scope *getParent() { return AnyParent; }
266 
267   /// getFnParent - Return the closest scope that is a function body.
getFnParent()268   const Scope *getFnParent() const { return FnParent; }
getFnParent()269   Scope *getFnParent() { return FnParent; }
270 
getMSLastManglingParent()271   const Scope *getMSLastManglingParent() const {
272     return MSLastManglingParent;
273   }
getMSLastManglingParent()274   Scope *getMSLastManglingParent() { return MSLastManglingParent; }
275 
276   /// getContinueParent - Return the closest scope that a continue statement
277   /// would be affected by.
getContinueParent()278   Scope *getContinueParent() {
279     return ContinueParent;
280   }
281 
getContinueParent()282   const Scope *getContinueParent() const {
283     return const_cast<Scope*>(this)->getContinueParent();
284   }
285 
286   // Set whether we're in the scope of a condition variable, where 'continue'
287   // is disallowed despite being a continue scope.
setIsConditionVarScope(bool InConditionVarScope)288   void setIsConditionVarScope(bool InConditionVarScope) {
289     Flags = (Flags & ~ConditionVarScope) |
290             (InConditionVarScope ? ConditionVarScope : 0);
291   }
292 
isConditionVarScope()293   bool isConditionVarScope() const {
294     return Flags & ConditionVarScope;
295   }
296 
297   /// getBreakParent - Return the closest scope that a break statement
298   /// would be affected by.
getBreakParent()299   Scope *getBreakParent() {
300     return BreakParent;
301   }
getBreakParent()302   const Scope *getBreakParent() const {
303     return const_cast<Scope*>(this)->getBreakParent();
304   }
305 
getBlockParent()306   Scope *getBlockParent() { return BlockParent; }
getBlockParent()307   const Scope *getBlockParent() const { return BlockParent; }
308 
getTemplateParamParent()309   Scope *getTemplateParamParent() { return TemplateParamParent; }
getTemplateParamParent()310   const Scope *getTemplateParamParent() const { return TemplateParamParent; }
311 
getDeclParent()312   Scope *getDeclParent() { return DeclParent; }
getDeclParent()313   const Scope *getDeclParent() const { return DeclParent; }
314 
315   /// Returns the depth of this scope. The translation-unit has scope depth 0.
getDepth()316   unsigned getDepth() const { return Depth; }
317 
318   /// Returns the number of function prototype scopes in this scope
319   /// chain.
getFunctionPrototypeDepth()320   unsigned getFunctionPrototypeDepth() const {
321     return PrototypeDepth;
322   }
323 
324   /// Return the number of parameters declared in this function
325   /// prototype, increasing it by one for the next call.
getNextFunctionPrototypeIndex()326   unsigned getNextFunctionPrototypeIndex() {
327     assert(isFunctionPrototypeScope());
328     return PrototypeIndex++;
329   }
330 
331   using decl_range = llvm::iterator_range<DeclSetTy::iterator>;
332 
decls()333   decl_range decls() const {
334     return decl_range(DeclsInScope.begin(), DeclsInScope.end());
335   }
336 
decl_empty()337   bool decl_empty() const { return DeclsInScope.empty(); }
338 
AddDecl(Decl * D)339   void AddDecl(Decl *D) {
340     if (auto *VD = dyn_cast<VarDecl>(D))
341       if (!isa<ParmVarDecl>(VD))
342         ReturnSlots.insert(VD);
343 
344     DeclsInScope.insert(D);
345   }
346 
RemoveDecl(Decl * D)347   void RemoveDecl(Decl *D) { DeclsInScope.erase(D); }
348 
incrementMSManglingNumber()349   void incrementMSManglingNumber() {
350     if (Scope *MSLMP = getMSLastManglingParent()) {
351       MSLMP->MSLastManglingNumber += 1;
352       MSCurManglingNumber += 1;
353     }
354   }
355 
decrementMSManglingNumber()356   void decrementMSManglingNumber() {
357     if (Scope *MSLMP = getMSLastManglingParent()) {
358       MSLMP->MSLastManglingNumber -= 1;
359       MSCurManglingNumber -= 1;
360     }
361   }
362 
getMSLastManglingNumber()363   unsigned getMSLastManglingNumber() const {
364     if (const Scope *MSLMP = getMSLastManglingParent())
365       return MSLMP->MSLastManglingNumber;
366     return 1;
367   }
368 
getMSCurManglingNumber()369   unsigned getMSCurManglingNumber() const {
370     return MSCurManglingNumber;
371   }
372 
373   /// isDeclScope - Return true if this is the scope that the specified decl is
374   /// declared in.
isDeclScope(const Decl * D)375   bool isDeclScope(const Decl *D) const { return DeclsInScope.contains(D); }
376 
377   /// Get the entity corresponding to this scope.
getEntity()378   DeclContext *getEntity() const {
379     return isTemplateParamScope() ? nullptr : Entity;
380   }
381 
382   /// Get the DeclContext in which to continue unqualified lookup after a
383   /// lookup in this scope.
getLookupEntity()384   DeclContext *getLookupEntity() const { return Entity; }
385 
setEntity(DeclContext * E)386   void setEntity(DeclContext *E) {
387     assert(!isTemplateParamScope() &&
388            "entity associated with template param scope");
389     Entity = E;
390   }
setLookupEntity(DeclContext * E)391   void setLookupEntity(DeclContext *E) { Entity = E; }
392 
393   /// Determine whether any unrecoverable errors have occurred within this
394   /// scope. Note that this may return false even if the scope contains invalid
395   /// declarations or statements, if the errors for those invalid constructs
396   /// were suppressed because some prior invalid construct was referenced.
hasUnrecoverableErrorOccurred()397   bool hasUnrecoverableErrorOccurred() const {
398     return ErrorTrap.hasUnrecoverableErrorOccurred();
399   }
400 
401   /// isFunctionScope() - Return true if this scope is a function scope.
isFunctionScope()402   bool isFunctionScope() const { return getFlags() & Scope::FnScope; }
403 
404   /// isClassScope - Return true if this scope is a class/struct/union scope.
isClassScope()405   bool isClassScope() const { return getFlags() & Scope::ClassScope; }
406 
407   /// Determines whether this scope is between inheritance colon and the real
408   /// class/struct definition.
isClassInheritanceScope()409   bool isClassInheritanceScope() const {
410     return getFlags() & Scope::ClassInheritanceScope;
411   }
412 
413   /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
414   /// method scope or is inside one.
isInCXXInlineMethodScope()415   bool isInCXXInlineMethodScope() const {
416     if (const Scope *FnS = getFnParent()) {
417       assert(FnS->getParent() && "TUScope not created?");
418       return FnS->getParent()->isClassScope();
419     }
420     return false;
421   }
422 
423   /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
424   /// Objective-C method body.  Note that this method is not constant time.
isInObjcMethodScope()425   bool isInObjcMethodScope() const {
426     for (const Scope *S = this; S; S = S->getParent()) {
427       // If this scope is an objc method scope, then we succeed.
428       if (S->getFlags() & ObjCMethodScope)
429         return true;
430     }
431     return false;
432   }
433 
434   /// isInObjcMethodOuterScope - Return true if this scope is an
435   /// Objective-C method outer most body.
isInObjcMethodOuterScope()436   bool isInObjcMethodOuterScope() const {
437     if (const Scope *S = this) {
438       // If this scope is an objc method scope, then we succeed.
439       if (S->getFlags() & ObjCMethodScope)
440         return true;
441     }
442     return false;
443   }
444 
445   /// isTemplateParamScope - Return true if this scope is a C++
446   /// template parameter scope.
isTemplateParamScope()447   bool isTemplateParamScope() const {
448     return getFlags() & Scope::TemplateParamScope;
449   }
450 
451   /// isFunctionPrototypeScope - Return true if this scope is a
452   /// function prototype scope.
isFunctionPrototypeScope()453   bool isFunctionPrototypeScope() const {
454     return getFlags() & Scope::FunctionPrototypeScope;
455   }
456 
457   /// isFunctionDeclarationScope - Return true if this scope is a
458   /// function prototype scope.
isFunctionDeclarationScope()459   bool isFunctionDeclarationScope() const {
460     return getFlags() & Scope::FunctionDeclarationScope;
461   }
462 
463   /// isAtCatchScope - Return true if this scope is \@catch.
isAtCatchScope()464   bool isAtCatchScope() const {
465     return getFlags() & Scope::AtCatchScope;
466   }
467 
468   /// isCatchScope - Return true if this scope is a C++ catch statement.
isCatchScope()469   bool isCatchScope() const { return getFlags() & Scope::CatchScope; }
470 
471   /// isSwitchScope - Return true if this scope is a switch scope.
isSwitchScope()472   bool isSwitchScope() const {
473     for (const Scope *S = this; S; S = S->getParent()) {
474       if (S->getFlags() & Scope::SwitchScope)
475         return true;
476       else if (S->getFlags() & (Scope::FnScope | Scope::ClassScope |
477                                 Scope::BlockScope | Scope::TemplateParamScope |
478                                 Scope::FunctionPrototypeScope |
479                                 Scope::AtCatchScope | Scope::ObjCMethodScope))
480         return false;
481     }
482     return false;
483   }
484 
485   /// Return true if this scope is a loop.
isLoopScope()486   bool isLoopScope() const {
487     // 'switch' is the only loop that is not a 'break' scope as well, so we can
488     // just check BreakScope and not SwitchScope.
489     return (getFlags() & Scope::BreakScope) &&
490            !(getFlags() & Scope::SwitchScope);
491   }
492 
493   /// Determines whether this scope is the OpenMP directive scope
isOpenMPDirectiveScope()494   bool isOpenMPDirectiveScope() const {
495     return (getFlags() & Scope::OpenMPDirectiveScope);
496   }
497 
498   /// Determine whether this scope is some OpenMP loop directive scope
499   /// (for example, 'omp for', 'omp simd').
isOpenMPLoopDirectiveScope()500   bool isOpenMPLoopDirectiveScope() const {
501     if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
502       assert(isOpenMPDirectiveScope() &&
503              "OpenMP loop directive scope is not a directive scope");
504       return true;
505     }
506     return false;
507   }
508 
509   /// Determine whether this scope is (or is nested into) some OpenMP
510   /// loop simd directive scope (for example, 'omp simd', 'omp for simd').
isOpenMPSimdDirectiveScope()511   bool isOpenMPSimdDirectiveScope() const {
512     return getFlags() & Scope::OpenMPSimdDirectiveScope;
513   }
514 
515   /// Determine whether this scope is a loop having OpenMP loop
516   /// directive attached.
isOpenMPLoopScope()517   bool isOpenMPLoopScope() const {
518     const Scope *P = getParent();
519     return P && P->isOpenMPLoopDirectiveScope();
520   }
521 
522   /// Determine whether this scope is some OpenMP directive with
523   /// order clause which specifies concurrent scope.
isOpenMPOrderClauseScope()524   bool isOpenMPOrderClauseScope() const {
525     return getFlags() & Scope::OpenMPOrderClauseScope;
526   }
527 
528   /// Determine whether this scope is the statement associated with an OpenACC
529   /// Compute construct directive.
isOpenACCComputeConstructScope()530   bool isOpenACCComputeConstructScope() const {
531     return getFlags() & Scope::OpenACCComputeConstructScope;
532   }
533 
534   /// Determine if this scope (or its parents) are a compute construct. If the
535   /// argument is provided, the search will stop at any of the specified scopes.
536   /// Otherwise, it will stop only at the normal 'no longer search' scopes.
537   bool isInOpenACCComputeConstructScope(ScopeFlags Flags = NoScope) const {
538     for (const Scope *S = this; S; S = S->getParent()) {
539       if (S->isOpenACCComputeConstructScope())
540         return true;
541 
542       if (S->getFlags() & Flags)
543         return false;
544 
545       else if (S->getFlags() &
546                (Scope::FnScope | Scope::ClassScope | Scope::BlockScope |
547                 Scope::TemplateParamScope | Scope::FunctionPrototypeScope |
548                 Scope::AtCatchScope | Scope::ObjCMethodScope))
549         return false;
550     }
551     return false;
552   }
553 
554   /// Determine whether this scope is a while/do/for statement, which can have
555   /// continue statements embedded into it.
isContinueScope()556   bool isContinueScope() const {
557     return getFlags() & ScopeFlags::ContinueScope;
558   }
559 
560   /// Determine whether this scope is a C++ 'try' block.
isTryScope()561   bool isTryScope() const { return getFlags() & Scope::TryScope; }
562 
563   /// Determine whether this scope is a function-level C++ try or catch scope.
isFnTryCatchScope()564   bool isFnTryCatchScope() const {
565     return getFlags() & ScopeFlags::FnTryCatchScope;
566   }
567 
568   /// Determine whether this scope is a SEH '__try' block.
isSEHTryScope()569   bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
570 
571   /// Determine whether this scope is a SEH '__except' block.
isSEHExceptScope()572   bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; }
573 
574   /// Determine whether this scope is a compound statement scope.
isCompoundStmtScope()575   bool isCompoundStmtScope() const {
576     return getFlags() & Scope::CompoundStmtScope;
577   }
578 
579   /// Determine whether this scope is a controlling scope in a
580   /// if/switch/while/for statement.
isControlScope()581   bool isControlScope() const { return getFlags() & Scope::ControlScope; }
582 
583   /// Returns if rhs has a higher scope depth than this.
584   ///
585   /// The caller is responsible for calling this only if one of the two scopes
586   /// is an ancestor of the other.
Contains(const Scope & rhs)587   bool Contains(const Scope& rhs) const { return Depth < rhs.Depth; }
588 
589   /// containedInPrototypeScope - Return true if this or a parent scope
590   /// is a FunctionPrototypeScope.
591   bool containedInPrototypeScope() const;
592 
PushUsingDirective(UsingDirectiveDecl * UDir)593   void PushUsingDirective(UsingDirectiveDecl *UDir) {
594     UsingDirectives.push_back(UDir);
595   }
596 
597   using using_directives_range =
598       llvm::iterator_range<UsingDirectivesTy::iterator>;
599 
using_directives()600   using_directives_range using_directives() {
601     return using_directives_range(UsingDirectives.begin(),
602                                   UsingDirectives.end());
603   }
604 
605   void updateNRVOCandidate(VarDecl *VD);
606 
607   void applyNRVO();
608 
609   /// Init - This is used by the parser to implement scope caching.
610   void Init(Scope *parent, unsigned flags);
611 
612   /// Sets up the specified scope flags and adjusts the scope state
613   /// variables accordingly.
614   void AddFlags(unsigned Flags);
615 
616   void dumpImpl(raw_ostream &OS) const;
617   void dump() const;
618 };
619 
620 } // namespace clang
621 
622 #endif // LLVM_CLANG_SEMA_SCOPE_H
623