 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
100.0% |
12 / 12 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
100.0% |
12 / 12 |
| |
|
Line Coverage: |
95.9% |
70 / 73 |
| |
 |
|
 |
1 : //===--- Scope.h - Scope interface ------------------------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file defines the Scope interface.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_CLANG_PARSE_SCOPE_H
15 : #define LLVM_CLANG_PARSE_SCOPE_H
16 :
17 : #include "clang/Parse/Action.h"
18 : #include "llvm/ADT/SmallPtrSet.h"
19 :
20 : namespace clang {
21 :
22 : /// Scope - A scope is a transient data structure that is used while parsing the
23 : /// program. It assists with resolving identifiers to the appropriate
24 : /// declaration.
25 : ///
26 6536: class Scope {
27 : public:
28 : /// ScopeFlags - These are bitfields that are or'd together when creating a
29 : /// scope, which defines the sorts of things the scope contains.
30 : enum ScopeFlags {
31 : /// FnScope - This indicates that the scope corresponds to a function, which
32 : /// means that labels are set here.
33 : FnScope = 0x01,
34 :
35 : /// BreakScope - This is a while,do,switch,for, etc that can have break
36 : /// stmts embedded into it.
37 : BreakScope = 0x02,
38 :
39 : /// ContinueScope - This is a while,do,for, which can have continue
40 : /// stmt embedded into it.
41 : ContinueScope = 0x04,
42 :
43 : /// DeclScope - This is a scope that can contain a declaration. Some scopes
44 : /// just contain loop constructs but don't contain decls.
45 : DeclScope = 0x08,
46 :
47 : /// ControlScope - The controlling scope in a if/switch/while/for statement.
48 : ControlScope = 0x10,
49 :
50 : /// ClassScope - The scope of a struct/union/class definition.
51 : ClassScope = 0x20,
52 :
53 : /// BlockScope - This is a scope that corresponds to a block object.
54 : /// Blocks serve as top-level scopes for some objects like labels, they
55 : /// also prevent things like break and continue. BlockScopes have the
56 : /// other flags set as well.
57 : BlockScope = 0x40,
58 :
59 : /// TemplateParamScope - This is a scope that corresponds to the
60 : /// template parameters of a C++ template. Template parameter
61 : /// scope starts at the 'template' keyword and ends when the
62 : /// template declaration ends.
63 : TemplateParamScope = 0x80,
64 :
65 : /// FunctionPrototypeScope - This is a scope that corresponds to the
66 : /// parameters within a function prototype.
67 : FunctionPrototypeScope = 0x100,
68 :
69 : /// AtCatchScope - This is a scope that corresponds to the Objective-C
70 : /// @catch statement.
71 : AtCatchScope = 0x200
72 : };
73 : private:
74 : /// The parent scope for this scope. This is null for the translation-unit
75 : /// scope.
76 : Scope *AnyParent;
77 :
78 : /// Depth - This is the depth of this scope. The translation-unit scope has
79 : /// depth 0.
80 : unsigned Depth : 16;
81 :
82 : /// Flags - This contains a set of ScopeFlags, which indicates how the scope
83 : /// interrelates with other control flow statements.
84 : unsigned Flags : 10;
85 :
86 : /// WithinElse - Whether this scope is part of the "else" branch in
87 : /// its parent ControlScope.
88 : bool WithinElse : 1;
89 :
90 : /// FnParent - If this scope has a parent scope that is a function body, this
91 : /// pointer is non-null and points to it. This is used for label processing.
92 : Scope *FnParent;
93 :
94 : /// BreakParent/ContinueParent - This is a direct link to the immediately
95 : /// preceeding BreakParent/ContinueParent if this scope is not one, or null if
96 : /// there is no containing break/continue scope.
97 : Scope *BreakParent, *ContinueParent;
98 :
99 : /// ControlParent - This is a direct link to the immediately
100 : /// preceeding ControlParent if this scope is not one, or null if
101 : /// there is no containing control scope.
102 : Scope *ControlParent;
103 :
104 : /// BlockParent - This is a direct link to the immediately containing
105 : /// BlockScope if this scope is not one, or null if there is none.
106 : Scope *BlockParent;
107 :
108 : /// TemplateParamParent - This is a direct link to the
109 : /// immediately containing template parameter scope. In the
110 : /// case of nested templates, template parameter scopes can have
111 : /// other template parameter scopes as parents.
112 : Scope *TemplateParamParent;
113 :
114 : /// DeclsInScope - This keeps track of all declarations in this scope. When
115 : /// the declaration is added to the scope, it is set as the current
116 : /// declaration for the identifier in the IdentifierTable. When the scope is
117 : /// popped, these declarations are removed from the IdentifierTable's notion
118 : /// of current declaration. It is up to the current Action implementation to
119 : /// implement these semantics.
120 : typedef llvm::SmallPtrSet<Action::DeclPtrTy, 32> DeclSetTy;
121 : DeclSetTy DeclsInScope;
122 :
123 : /// Entity - The entity with which this scope is associated. For
124 : /// example, the entity of a class scope is the class itself, the
125 : /// entity of a function scope is a function, etc. This field is
126 : /// maintained by the Action implementation.
127 : void *Entity;
128 :
129 : typedef llvm::SmallVector<Action::DeclPtrTy, 2> UsingDirectivesTy;
130 : UsingDirectivesTy UsingDirectives;
131 :
132 : public:
133 6536: Scope(Scope *Parent, unsigned ScopeFlags) {
134 6536: Init(Parent, ScopeFlags);
135 6536: }
136 :
137 : /// getFlags - Return the flags for this scope.
138 : ///
139 117387: unsigned getFlags() const { return Flags; }
140 :
141 : /// isBlockScope - Return true if this scope does not correspond to a
142 : /// closure.
143 285: bool isBlockScope() const { return Flags & BlockScope; }
144 :
145 : /// getParent - Return the scope that this is nested in.
146 : ///
147 63: const Scope *getParent() const { return AnyParent; }
148 199933: Scope *getParent() { return AnyParent; }
149 :
150 : /// getFnParent - Return the closest scope that is a function body.
151 : ///
152 : const Scope *getFnParent() const { return FnParent; }
153 10044: Scope *getFnParent() { return FnParent; }
154 :
155 : /// getContinueParent - Return the closest scope that a continue statement
156 : /// would be affected by. If the closest scope is a closure scope, we know
157 : /// that there is no loop *inside* the closure.
158 35: Scope *getContinueParent() {
29: branch 0 taken
6: branch 1 taken
28: branch 3 taken
1: branch 4 taken
28: branch 5 taken
7: branch 6 taken
159 35: if (ContinueParent && !ContinueParent->isBlockScope())
160 28: return ContinueParent;
161 7: return 0;
162 : }
163 :
164 : const Scope *getContinueParent() const {
165 : return const_cast<Scope*>(this)->getContinueParent();
166 : }
167 :
168 : /// getBreakParent - Return the closest scope that a break statement
169 : /// would be affected by. If the closest scope is a block scope, we know
170 : /// that there is no loop *inside* the block.
171 262: Scope *getBreakParent() {
256: branch 0 taken
6: branch 1 taken
253: branch 3 taken
3: branch 4 taken
253: branch 5 taken
9: branch 6 taken
172 262: if (BreakParent && !BreakParent->isBlockScope())
173 253: return BreakParent;
174 9: return 0;
175 : }
176 : const Scope *getBreakParent() const {
177 : return const_cast<Scope*>(this)->getBreakParent();
178 : }
179 :
180 105: Scope *getControlParent() { return ControlParent; }
181 : const Scope *getControlParent() const { return ControlParent; }
182 :
183 : Scope *getBlockParent() { return BlockParent; }
184 : const Scope *getBlockParent() const { return BlockParent; }
185 :
186 : Scope *getTemplateParamParent() { return TemplateParamParent; }
187 : const Scope *getTemplateParamParent() const { return TemplateParamParent; }
188 :
189 : typedef DeclSetTy::iterator decl_iterator;
190 23940: decl_iterator decl_begin() const { return DeclsInScope.begin(); }
191 23940: decl_iterator decl_end() const { return DeclsInScope.end(); }
192 56855: bool decl_empty() const { return DeclsInScope.empty(); }
193 :
194 77962: void AddDecl(Action::DeclPtrTy D) {
195 77962: DeclsInScope.insert(D);
196 77962: }
197 :
198 870: void RemoveDecl(Action::DeclPtrTy D) {
199 870: DeclsInScope.erase(D);
200 870: }
201 :
202 : /// isDeclScope - Return true if this is the scope that the specified decl is
203 : /// declared in.
204 54967: bool isDeclScope(Action::DeclPtrTy D) {
205 54967: return DeclsInScope.count(D) != 0;
206 : }
207 :
208 499404: void* getEntity() const { return Entity; }
209 18061: void setEntity(void *E) { Entity = E; }
210 :
211 : /// isClassScope - Return true if this scope is a class/struct/union scope.
212 6136: bool isClassScope() const {
213 6136: return (getFlags() & Scope::ClassScope);
214 : }
215 :
216 : /// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
217 : /// method scope or is inside one.
218 : bool isInCXXInlineMethodScope() const {
219 : if (const Scope *FnS = getFnParent()) {
220 : assert(FnS->getParent() && "TUScope not created?");
221 : return FnS->getParent()->isClassScope();
222 : }
223 : return false;
224 : }
225 :
226 : /// isTemplateParamScope - Return true if this scope is a C++
227 : /// template parameter scope.
228 3313: bool isTemplateParamScope() const {
229 3313: return getFlags() & Scope::TemplateParamScope;
230 : }
231 :
232 : /// isFunctionPrototypeScope - Return true if this scope is a
233 : /// function prototype scope.
234 4125: bool isFunctionPrototypeScope() const {
235 4125: return getFlags() & Scope::FunctionPrototypeScope;
236 : }
237 :
238 : /// isAtCatchScope - Return true if this scope is @catch.
239 14: bool isAtCatchScope() const {
240 14: return getFlags() & Scope::AtCatchScope;
241 : }
242 :
243 : /// isWithinElse - Whether we are within the "else" of the
244 : /// ControlParent (if any).
245 280: bool isWithinElse() const { return WithinElse; }
246 :
247 412: void setWithinElse(bool WE) { WithinElse = WE; }
248 :
249 : typedef UsingDirectivesTy::iterator udir_iterator;
250 : typedef UsingDirectivesTy::const_iterator const_udir_iterator;
251 :
252 0: void PushUsingDirective(Action::DeclPtrTy UDir) {
253 0: UsingDirectives.push_back(UDir);
254 0: }
255 :
256 12265: udir_iterator using_directives_begin() {
257 12265: return UsingDirectives.begin();
258 : }
259 :
260 12265: udir_iterator using_directives_end() {
261 12265: return UsingDirectives.end();
262 : }
263 :
264 : const_udir_iterator using_directives_begin() const {
265 : return UsingDirectives.begin();
266 : }
267 :
268 : const_udir_iterator using_directives_end() const {
269 : return UsingDirectives.end();
270 : }
271 :
272 : /// Init - This is used by the parser to implement scope caching.
273 : ///
274 35381: void Init(Scope *Parent, unsigned ScopeFlags) {
275 35381: AnyParent = Parent;
276 35381: Depth = AnyParent ? AnyParent->Depth+1 : 0;
277 35381: Flags = ScopeFlags;
278 35381: WithinElse = false;
279 :
280 35381: if (AnyParent) {
281 33130: FnParent = AnyParent->FnParent;
282 33130: BreakParent = AnyParent->BreakParent;
283 33130: ContinueParent = AnyParent->ContinueParent;
284 33130: ControlParent = AnyParent->ControlParent;
285 33130: BlockParent = AnyParent->BlockParent;
286 33130: TemplateParamParent = AnyParent->TemplateParamParent;
287 : } else {
288 2251: FnParent = BreakParent = ContinueParent = BlockParent = 0;
289 2251: ControlParent = 0;
290 2251: TemplateParamParent = 0;
291 : }
292 :
293 : // If this scope is a function or contains breaks/continues, remember it.
294 35381: if (Flags & FnScope) FnParent = this;
295 35381: if (Flags & BreakScope) BreakParent = this;
296 35381: if (Flags & ContinueScope) ContinueParent = this;
297 35381: if (Flags & ControlScope) ControlParent = this;
298 35381: if (Flags & BlockScope) BlockParent = this;
299 35381: if (Flags & TemplateParamScope) TemplateParamParent = this;
300 35381: DeclsInScope.clear();
301 35381: UsingDirectives.clear();
302 35381: Entity = 0;
303 35381: }
304 : };
305 :
306 : } // end namespace clang
307 :
308 : #endif
Generated: 2010-02-10 01:31 by zcov