 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
34.8% |
8 / 23 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
56.5% |
13 / 23 |
| |
|
Line Coverage: |
95.6% |
436 / 456 |
| |
 |
|
 |
 |
|
 |
|
| Programs: |
164 |
|
Runs |
341860 |
| |
 |
|
 |
1 : //===--- Stmt.h - Classes for representing statements -----------*- 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 Stmt interface and subclasses.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_CLANG_AST_STMT_H
15 : #define LLVM_CLANG_AST_STMT_H
16 :
17 : #include "llvm/Support/Casting.h"
18 : #include "llvm/Support/raw_ostream.h"
19 : #include "clang/Basic/SourceLocation.h"
20 : #include "clang/AST/PrettyPrinter.h"
21 : #include "clang/AST/StmtIterator.h"
22 : #include "clang/AST/DeclGroup.h"
23 : #include "clang/AST/FullExpr.h"
24 : #include "llvm/ADT/SmallVector.h"
25 : #include "clang/AST/ASTContext.h"
26 : #include <string>
27 : using llvm::dyn_cast_or_null;
28 :
29 : namespace llvm {
30 : class FoldingSetNodeID;
31 : }
32 :
33 : namespace clang {
34 : class ASTContext;
35 : class Expr;
36 : class Decl;
37 : class ParmVarDecl;
38 : class QualType;
39 : class IdentifierInfo;
40 : class SourceManager;
41 : class StringLiteral;
42 : class SwitchStmt;
43 :
44 : //===----------------------------------------------------------------------===//
45 : // ExprIterator - Iterators for iterating over Stmt* arrays that contain
46 : // only Expr*. This is needed because AST nodes use Stmt* arrays to store
47 : // references to children (to be compatible with StmtIterator).
48 : //===----------------------------------------------------------------------===//
49 :
50 : class Stmt;
51 : class Expr;
52 :
53 : class ExprIterator {
54 : Stmt** I;
55 : public:
56 11704: ExprIterator(Stmt** i) : I(i) {}
57 : ExprIterator() : I(0) {}
58 5368: ExprIterator& operator++() { ++I; return *this; }
59 4: ExprIterator operator-(size_t i) { return I-i; }
60 136: ExprIterator operator+(size_t i) { return I+i; }
61 : Expr* operator[](size_t idx);
62 : // FIXME: Verify that this will correctly return a signed distance.
63 4070: signed operator-(const ExprIterator& R) const { return I - R.I; }
64 : Expr* operator*() const;
65 : Expr* operator->() const;
66 5791: bool operator==(const ExprIterator& R) const { return I == R.I; }
67 5346: bool operator!=(const ExprIterator& R) const { return I != R.I; }
68 : bool operator>(const ExprIterator& R) const { return I > R.I; }
69 136: bool operator>=(const ExprIterator& R) const { return I >= R.I; }
70 : };
71 :
72 : class ConstExprIterator {
73 : Stmt* const * I;
74 : public:
75 11582: ConstExprIterator(Stmt* const* i) : I(i) {}
76 : ConstExprIterator() : I(0) {}
77 5202: ConstExprIterator& operator++() { ++I; return *this; }
78 77: ConstExprIterator operator+(size_t i) { return I+i; }
79 : ConstExprIterator operator-(size_t i) { return I-i; }
80 : const Expr * operator[](size_t idx) const;
81 : signed operator-(const ConstExprIterator& R) const { return I - R.I; }
82 : const Expr * operator*() const;
83 : const Expr * operator->() const;
84 2543: bool operator==(const ConstExprIterator& R) const { return I == R.I; }
85 10848: bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
86 : bool operator>(const ConstExprIterator& R) const { return I > R.I; }
87 : bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
88 : };
89 :
90 : //===----------------------------------------------------------------------===//
91 : // AST classes for statements.
92 : //===----------------------------------------------------------------------===//
93 :
94 : /// Stmt - This represents one statement.
95 : ///
96 : class Stmt {
97 : public:
98 : enum StmtClass {
99 : NoStmtClass = 0,
100 : #define STMT(CLASS, PARENT) CLASS##Class,
101 : #define FIRST_STMT(CLASS) firstStmtConstant = CLASS##Class,
102 : #define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class,
103 : #define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class,
104 : #define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class
105 : #define ABSTRACT_EXPR(CLASS, PARENT)
106 : #include "clang/AST/StmtNodes.def"
107 : };
108 : private:
109 : /// \brief The statement class.
110 : const unsigned sClass : 8;
111 :
112 : /// \brief The reference count for this statement.
113 : unsigned RefCount : 24;
114 :
115 : // Make vanilla 'new' and 'delete' illegal for Stmts.
116 : protected:
117 : void* operator new(size_t bytes) throw() {
118 : assert(0 && "Stmts cannot be allocated with regular 'new'.");
119 : return 0;
120 : }
121 0: void operator delete(void* data) throw() {
122 0: assert(0 && "Stmts cannot be released with regular 'delete'.");
123 : }
124 :
125 : public:
126 : // Only allow allocation of Stmts using the allocator in ASTContext
127 : // or by doing a placement new.
128 : void* operator new(size_t bytes, ASTContext& C,
129 113509: unsigned alignment = 16) throw() {
130 113509: return ::operator new(bytes, C, alignment);
131 : }
132 :
133 : void* operator new(size_t bytes, ASTContext* C,
134 1576: unsigned alignment = 16) throw() {
135 1576: return ::operator new(bytes, *C, alignment);
136 : }
137 :
138 34147: void* operator new(size_t bytes, void* mem) throw() {
139 34147: return mem;
140 : }
141 :
142 : void operator delete(void*, ASTContext&, unsigned) throw() { }
143 : void operator delete(void*, ASTContext*, unsigned) throw() { }
144 : void operator delete(void*, std::size_t) throw() { }
145 : void operator delete(void*, void*) throw() { }
146 :
147 : public:
148 : /// \brief A placeholder type used to construct an empty shell of a
149 : /// type, that will be filled in later (e.g., by some
150 : /// de-serialization).
151 : struct EmptyShell { };
152 :
153 : protected:
154 : /// DestroyChildren - Invoked by destructors of subclasses of Stmt to
155 : /// recursively release child AST nodes.
156 : void DestroyChildren(ASTContext& Ctx);
157 :
158 : /// \brief Construct an empty statement.
159 110: explicit Stmt(StmtClass SC, EmptyShell) : sClass(SC), RefCount(1) {
0: branch 1 not taken
110: branch 2 taken
160 110: if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
161 110: }
162 :
163 : /// \brief Virtual method that performs the actual destruction of
164 : /// this statement.
165 : ///
166 : /// Subclasses should override this method (not Destroy()) to
167 : /// provide class-specific destruction.
168 : virtual void DoDestroy(ASTContext &Ctx);
169 :
170 : public:
171 176992: Stmt(StmtClass SC) : sClass(SC), RefCount(1) {
0: branch 1 not taken
176992: branch 2 taken
172 176992: if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
173 176992: }
0: branch 0 not taken
31667: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 6 not taken
0: branch 7 not taken
174 31667: virtual ~Stmt() {}
175 :
176 : #ifndef NDEBUG
177 : /// \brief True if this statement's refcount is in a valid state.
178 : /// Should be used only in assertions.
179 187711: bool isRetained() const {
180 187711: return (RefCount >= 1);
181 : }
182 : #endif
183 :
184 : /// \brief Destroy the current statement and its children.
185 4137: void Destroy(ASTContext &Ctx) {
4137: branch 1 taken
0: branch 1 not taken
186 4137: assert(RefCount >= 1);
3822: branch 0 taken
315: branch 1 taken
187 4137: if (--RefCount == 0)
188 3822: DoDestroy(Ctx);
189 4137: }
190 :
191 : /// \brief Increases the reference count for this statement.
192 : ///
193 : /// Invoke the Retain() operation when this statement or expression
194 : /// is being shared by another owner.
195 23315: Stmt *Retain() {
0: branch 1 not taken
0: branch 1 not taken
196 23315: assert(RefCount >= 1);
197 23315: ++RefCount;
198 23315: return this;
199 : }
200 :
201 3748513: StmtClass getStmtClass() const {
0: branch 0 not taken
3748513: branch 1 taken
202 3748513: assert(RefCount >= 1 && "Referencing already-destroyed statement!");
203 3748513: return (StmtClass)sClass;
204 : }
205 : const char *getStmtClassName() const;
206 :
207 : /// SourceLocation tokens are not useful in isolation - they are low level
208 : /// value objects created/interpreted by SourceManager. We assume AST
209 : /// clients will have a pointer to the respective SourceManager.
210 : virtual SourceRange getSourceRange() const = 0;
211 256027: SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
212 45635: SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
213 :
214 : // global temp stats (until we have a per-module visitor)
215 : static void addStmtClass(const StmtClass s);
216 : static bool CollectingStats(bool Enable = false);
217 : static void PrintStats();
218 :
219 : /// dump - This does a local dump of the specified AST fragment. It dumps the
220 : /// specified node and a few nodes underneath it, but not the whole subtree.
221 : /// This is useful in a debugger.
222 : void dump() const;
223 : void dump(SourceManager &SM) const;
224 :
225 : /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
226 : void dumpAll() const;
227 : void dumpAll(SourceManager &SM) const;
228 :
229 : /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
230 : /// back to its original source language syntax.
231 : void dumpPretty(ASTContext& Context) const;
232 : void printPretty(llvm::raw_ostream &OS, PrinterHelper *Helper,
233 : const PrintingPolicy &Policy,
234 143: unsigned Indentation = 0) const {
235 143: printPretty(OS, *(ASTContext*)0, Helper, Policy, Indentation);
236 143: }
237 : void printPretty(llvm::raw_ostream &OS, ASTContext &Context,
238 : PrinterHelper *Helper,
239 : const PrintingPolicy &Policy,
240 : unsigned Indentation = 0) const;
241 :
242 : /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
243 : /// works on systems with GraphViz (Mac OS X) or dot+gv installed.
244 : void viewAST() const;
245 :
246 : // Implement isa<T> support.
247 0: static bool classof(const Stmt *) { return true; }
248 :
249 : /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
250 : /// contain implicit control-flow in the order their subexpressions
251 : /// are evaluated. This predicate returns true if this statement has
252 : /// such implicit control-flow. Such statements are also specially handled
253 : /// within CFGs.
254 : bool hasImplicitControlFlow() const;
255 :
256 : /// Child Iterators: All subclasses must implement child_begin and child_end
257 : /// to permit easy iteration over the substatements/subexpessions of an
258 : /// AST node. This permits easy iteration over all nodes in the AST.
259 : typedef StmtIterator child_iterator;
260 : typedef ConstStmtIterator const_child_iterator;
261 :
262 : virtual child_iterator child_begin() = 0;
263 : virtual child_iterator child_end() = 0;
264 :
265 1253: const_child_iterator child_begin() const {
266 1253: return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
267 : }
268 :
269 1317: const_child_iterator child_end() const {
270 1317: return const_child_iterator(const_cast<Stmt*>(this)->child_end());
271 : }
272 :
273 : /// \brief Produce a unique representation of the given statement.
274 : ///
275 : /// \brief ID once the profiling operation is complete, will contain
276 : /// the unique representation of the given statement.
277 : ///
278 : /// \brief Context the AST context in which the statement resides
279 : ///
280 : /// \brief Canonical whether the profile should be based on the canonical
281 : /// representation of this statement (e.g., where non-type template
282 : /// parameters are identified by index/level rather than their
283 : /// declaration pointers) or the exact representation of the statement as
284 : /// written in the source.
285 : void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
286 : bool Canonical);
287 : };
288 :
289 : /// DeclStmt - Adaptor class for mixing declarations with statements and
290 : /// expressions. For example, CompoundStmt mixes statements, expressions
291 : /// and declarations (variables, types). Another example is ForStmt, where
292 : /// the first statement can be an expression or a declaration.
293 : ///
294 0: class DeclStmt : public Stmt {
295 : DeclGroupRef DG;
296 : SourceLocation StartLoc, EndLoc;
297 :
298 : protected:
299 : virtual void DoDestroy(ASTContext &Ctx);
300 :
301 : public:
302 : DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
303 7436: SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
304 7436: StartLoc(startLoc), EndLoc(endLoc) {}
305 :
306 : /// \brief Build an empty declaration statement.
307 21: explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { }
308 :
309 : /// isSingleDecl - This method returns true if this DeclStmt refers
310 : /// to a single Decl.
311 6313: bool isSingleDecl() const {
312 6313: return DG.isSingleDecl();
313 : }
314 :
315 2902: const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
316 3602: Decl *getSingleDecl() { return DG.getSingleDecl(); }
317 :
318 : const DeclGroupRef getDeclGroup() const { return DG; }
319 24: DeclGroupRef getDeclGroup() { return DG; }
320 21: void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
321 :
322 198: SourceLocation getStartLoc() const { return StartLoc; }
323 21: void setStartLoc(SourceLocation L) { StartLoc = L; }
324 198: SourceLocation getEndLoc() const { return EndLoc; }
325 21: void setEndLoc(SourceLocation L) { EndLoc = L; }
326 :
327 9348: SourceRange getSourceRange() const {
328 9348: return SourceRange(StartLoc, EndLoc);
329 : }
330 :
331 19672: static bool classof(const Stmt *T) {
332 19672: return T->getStmtClass() == DeclStmtClass;
333 : }
334 : static bool classof(const DeclStmt *) { return true; }
335 :
336 : // Iterators over subexpressions.
337 : virtual child_iterator child_begin();
338 : virtual child_iterator child_end();
339 :
340 : typedef DeclGroupRef::iterator decl_iterator;
341 : typedef DeclGroupRef::const_iterator const_decl_iterator;
342 :
343 15179: decl_iterator decl_begin() { return DG.begin(); }
344 12496: decl_iterator decl_end() { return DG.end(); }
345 1152: const_decl_iterator decl_begin() const { return DG.begin(); }
346 1152: const_decl_iterator decl_end() const { return DG.end(); }
347 : };
348 :
349 : /// NullStmt - This is the null statement ";": C99 6.8.3p3.
350 : ///
351 30: class NullStmt : public Stmt {
352 : SourceLocation SemiLoc;
353 : public:
354 272: NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
355 :
356 : /// \brief Build an empty null statement.
357 2: explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) { }
358 :
359 9: SourceLocation getSemiLoc() const { return SemiLoc; }
360 2: void setSemiLoc(SourceLocation L) { SemiLoc = L; }
361 :
362 11: virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
363 :
364 1364: static bool classof(const Stmt *T) {
365 1364: return T->getStmtClass() == NullStmtClass;
366 : }
367 : static bool classof(const NullStmt *) { return true; }
368 :
369 : // Iterators
370 : virtual child_iterator child_begin();
371 : virtual child_iterator child_end();
372 : };
373 :
374 : /// CompoundStmt - This represents a group of statements like { stmt stmt }.
375 : ///
376 39: class CompoundStmt : public Stmt {
377 : Stmt** Body;
378 : unsigned NumStmts;
379 : SourceLocation LBracLoc, RBracLoc;
380 : public:
381 : CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned numStmts,
382 11121: SourceLocation LB, SourceLocation RB)
383 11121: : Stmt(CompoundStmtClass), NumStmts(numStmts), LBracLoc(LB), RBracLoc(RB) {
384 11121: if (NumStmts == 0) {
385 2052: Body = 0;
386 2052: return;
387 : }
388 :
389 9069: Body = new (C) Stmt*[NumStmts];
390 9069: memcpy(Body, StmtStart, numStmts * sizeof(*Body));
391 : }
392 :
393 : // \brief Build an empty compound statement.
394 39: explicit CompoundStmt(EmptyShell Empty)
395 39: : Stmt(CompoundStmtClass, Empty), Body(0), NumStmts(0) { }
396 :
397 : void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts);
398 :
399 901: bool body_empty() const { return NumStmts == 0; }
400 63: unsigned size() const { return NumStmts; }
401 :
402 : typedef Stmt** body_iterator;
403 7125: body_iterator body_begin() { return Body; }
404 7125: body_iterator body_end() { return Body + NumStmts; }
405 236: Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; }
406 :
407 : typedef Stmt* const * const_body_iterator;
408 3176: const_body_iterator body_begin() const { return Body; }
409 2597: const_body_iterator body_end() const { return Body + NumStmts; }
410 39: const Stmt *body_back() const { return NumStmts ? Body[NumStmts-1] : 0; }
411 :
412 : typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
413 6434: reverse_body_iterator body_rbegin() {
414 6434: return reverse_body_iterator(body_end());
415 : }
416 6434: reverse_body_iterator body_rend() {
417 6434: return reverse_body_iterator(body_begin());
418 : }
419 :
420 : typedef std::reverse_iterator<const_body_iterator>
421 : const_reverse_body_iterator;
422 :
423 : const_reverse_body_iterator body_rbegin() const {
424 : return const_reverse_body_iterator(body_end());
425 : }
426 :
427 : const_reverse_body_iterator body_rend() const {
428 : return const_reverse_body_iterator(body_begin());
429 : }
430 :
431 11514: virtual SourceRange getSourceRange() const {
432 11514: return SourceRange(LBracLoc, RBracLoc);
433 : }
434 :
435 5289: SourceLocation getLBracLoc() const { return LBracLoc; }
436 39: void setLBracLoc(SourceLocation L) { LBracLoc = L; }
437 2932: SourceLocation getRBracLoc() const { return RBracLoc; }
438 39: void setRBracLoc(SourceLocation L) { RBracLoc = L; }
439 :
440 25261: static bool classof(const Stmt *T) {
441 25261: return T->getStmtClass() == CompoundStmtClass;
442 : }
443 : static bool classof(const CompoundStmt *) { return true; }
444 :
445 : // Iterators
446 : virtual child_iterator child_begin();
447 : virtual child_iterator child_end();
448 : };
449 :
450 : // SwitchCase is the base class for CaseStmt and DefaultStmt,
0: branch 6 not taken
451 17: class SwitchCase : public Stmt {
452 : protected:
453 : // A pointer to the following CaseStmt or DefaultStmt class,
454 : // used by SwitchStmt.
455 : SwitchCase *NextSwitchCase;
456 :
457 369: SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
458 :
459 : public:
460 : const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
461 :
462 745: SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
463 :
464 365: void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
465 :
466 : Stmt *getSubStmt() { return v_getSubStmt(); }
467 :
468 0: virtual SourceRange getSourceRange() const { return SourceRange(); }
469 :
470 555: static bool classof(const Stmt *T) {
471 : return T->getStmtClass() == CaseStmtClass ||
472 555: T->getStmtClass() == DefaultStmtClass;
473 : }
474 : static bool classof(const SwitchCase *) { return true; }
475 : protected:
476 : virtual Stmt* v_getSubStmt() = 0;
477 : };
478 :
479 14: class CaseStmt : public SwitchCase {
480 : enum { SUBSTMT, LHS, RHS, END_EXPR };
481 : Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for
482 : // GNU "case 1 ... 4" extension
483 : SourceLocation CaseLoc;
484 : SourceLocation EllipsisLoc;
485 : SourceLocation ColonLoc;
486 :
487 0: virtual Stmt* v_getSubStmt() { return getSubStmt(); }
488 : public:
489 : CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
490 309: SourceLocation ellipsisLoc, SourceLocation colonLoc)
491 309: : SwitchCase(CaseStmtClass) {
492 309: SubExprs[SUBSTMT] = 0;
493 309: SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
494 309: SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
495 309: CaseLoc = caseLoc;
496 309: EllipsisLoc = ellipsisLoc;
497 309: ColonLoc = colonLoc;
498 309: }
499 :
500 : /// \brief Build an empty switch case statement.
501 6: explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { }
502 :
503 29: SourceLocation getCaseLoc() const { return CaseLoc; }
504 6: void setCaseLoc(SourceLocation L) { CaseLoc = L; }
505 25: SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
506 6: void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
507 25: SourceLocation getColonLoc() const { return ColonLoc; }
508 6: void setColonLoc(SourceLocation L) { ColonLoc = L; }
509 :
510 740: Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
511 611: Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
512 369: Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
513 :
514 48: const Expr *getLHS() const {
515 48: return reinterpret_cast<const Expr*>(SubExprs[LHS]);
516 : }
517 84: const Expr *getRHS() const {
518 84: return reinterpret_cast<const Expr*>(SubExprs[RHS]);
519 : }
520 110: const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
521 :
522 315: void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
523 299: void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
524 46: void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
525 :
526 :
527 14: virtual SourceRange getSourceRange() const {
528 : // Handle deeply nested case statements with iteration instead of recursion.
529 14: const CaseStmt *CS = this;
530 20: while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
531 3: CS = CS2;
532 :
533 14: return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd());
534 : }
535 3228: static bool classof(const Stmt *T) {
536 3228: return T->getStmtClass() == CaseStmtClass;
537 : }
538 94: static bool classof(const CaseStmt *) { return true; }
539 :
540 : // Iterators
541 : virtual child_iterator child_begin();
542 : virtual child_iterator child_end();
543 : };
544 :
545 3: class DefaultStmt : public SwitchCase {
546 : Stmt* SubStmt;
547 : SourceLocation DefaultLoc;
548 : SourceLocation ColonLoc;
549 0: virtual Stmt* v_getSubStmt() { return getSubStmt(); }
550 : public:
551 52: DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
552 : SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL),
553 52: ColonLoc(CL) {}
554 :
555 : /// \brief Build an empty default statement.
556 2: explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { }
557 :
558 62: Stmt *getSubStmt() { return SubStmt; }
559 21: const Stmt *getSubStmt() const { return SubStmt; }
560 2: void setSubStmt(Stmt *S) { SubStmt = S; }
561 :
562 7: SourceLocation getDefaultLoc() const { return DefaultLoc; }
563 2: void setDefaultLoc(SourceLocation L) { DefaultLoc = L; }
564 5: SourceLocation getColonLoc() const { return ColonLoc; }
565 2: void setColonLoc(SourceLocation L) { ColonLoc = L; }
566 :
567 6: virtual SourceRange getSourceRange() const {
568 6: return SourceRange(DefaultLoc, SubStmt->getLocEnd());
569 : }
570 2984: static bool classof(const Stmt *T) {
571 2984: return T->getStmtClass() == DefaultStmtClass;
572 : }
573 : static bool classof(const DefaultStmt *) { return true; }
574 :
575 : // Iterators
576 : virtual child_iterator child_begin();
577 : virtual child_iterator child_end();
578 : };
579 :
580 2: class LabelStmt : public Stmt {
581 : IdentifierInfo *Label;
582 : Stmt *SubStmt;
583 : SourceLocation IdentLoc;
584 : public:
585 158: LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
586 : : Stmt(LabelStmtClass), Label(label),
587 158: SubStmt(substmt), IdentLoc(IL) {}
588 :
589 : // \brief Build an empty label statement.
590 4: explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
591 :
592 20: SourceLocation getIdentLoc() const { return IdentLoc; }
593 149: IdentifierInfo *getID() const { return Label; }
594 4: void setID(IdentifierInfo *II) { Label = II; }
595 : const char *getName() const;
596 330: Stmt *getSubStmt() { return SubStmt; }
597 31: const Stmt *getSubStmt() const { return SubStmt; }
598 98: void setIdentLoc(SourceLocation L) { IdentLoc = L; }
599 102: void setSubStmt(Stmt *SS) { SubStmt = SS; }
600 :
601 2: virtual SourceRange getSourceRange() const {
602 2: return SourceRange(IdentLoc, SubStmt->getLocEnd());
603 : }
604 3315: static bool classof(const Stmt *T) {
605 3315: return T->getStmtClass() == LabelStmtClass;
606 : }
607 : static bool classof(const LabelStmt *) { return true; }
608 :
609 : // Iterators
610 : virtual child_iterator child_begin();
611 : virtual child_iterator child_end();
612 : };
613 :
614 :
615 : /// IfStmt - This represents an if/then/else.
616 : ///
617 1: class IfStmt : public Stmt {
618 : enum { COND, THEN, ELSE, END_EXPR };
619 : Stmt* SubExprs[END_EXPR];
620 :
621 : /// \brief If non-NULL, the declaration in the "if" statement.
622 : VarDecl *Var;
623 :
624 : SourceLocation IfLoc;
625 : SourceLocation ElseLoc;
626 :
627 : public:
628 : IfStmt(SourceLocation IL, VarDecl *var, Expr *cond, Stmt *then,
629 1554: SourceLocation EL = SourceLocation(), Stmt *elsev = 0)
630 1554: : Stmt(IfStmtClass), Var(var), IfLoc(IL), ElseLoc(EL) {
631 1554: SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
632 1554: SubExprs[THEN] = then;
633 1554: SubExprs[ELSE] = elsev;
634 1554: }
635 :
636 : /// \brief Build an empty if/then/else statement
637 8: explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
638 :
639 : /// \brief Retrieve the variable declared in this "if" statement, if any.
640 : ///
641 : /// In the following example, "x" is the condition variable.
642 : /// \code
643 : /// if (int x = foo()) {
644 : /// printf("x is %d", x);
645 : /// }
646 : /// \endcode
647 1805: VarDecl *getConditionVariable() const { return Var; }
648 8: void setConditionVariable(VarDecl *V) { Var = V; }
649 :
650 578: const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
651 8: void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
652 224: const Stmt *getThen() const { return SubExprs[THEN]; }
653 8: void setThen(Stmt *S) { SubExprs[THEN] = S; }
654 433: const Stmt *getElse() const { return SubExprs[ELSE]; }
655 8: void setElse(Stmt *S) { SubExprs[ELSE] = S; }
656 :
657 9764: Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
658 1568: Stmt *getThen() { return SubExprs[THEN]; }
659 1566: Stmt *getElse() { return SubExprs[ELSE]; }
660 :
661 26: SourceLocation getIfLoc() const { return IfLoc; }
662 8: void setIfLoc(SourceLocation L) { IfLoc = L; }
663 26: SourceLocation getElseLoc() const { return ElseLoc; }
664 8: void setElseLoc(SourceLocation L) { ElseLoc = L; }
665 :
666 681: virtual SourceRange getSourceRange() const {
667 681: if (SubExprs[ELSE])
668 72: return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
669 : else
670 609: return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
671 : }
672 :
673 8588: static bool classof(const Stmt *T) {
674 8588: return T->getStmtClass() == IfStmtClass;
675 : }
676 : static bool classof(const IfStmt *) { return true; }
677 :
678 : // Iterators over subexpressions. The iterators will include iterating
679 : // over the initialization expression referenced by the condition variable.
680 : virtual child_iterator child_begin();
681 : virtual child_iterator child_end();
682 :
683 : protected:
684 : virtual void DoDestroy(ASTContext &Ctx);
685 : };
686 :
687 : /// SwitchStmt - This represents a 'switch' stmt.
688 : ///
689 14: class SwitchStmt : public Stmt {
690 : enum { COND, BODY, END_EXPR };
691 : Stmt* SubExprs[END_EXPR];
692 : VarDecl *Var;
693 : // This points to a linked list of case and default statements.
694 : SwitchCase *FirstCase;
695 : SourceLocation SwitchLoc;
696 :
697 : protected:
698 : virtual void DoDestroy(ASTContext &Ctx);
699 :
700 : public:
701 139: SwitchStmt(VarDecl *Var, Expr *cond)
702 139: : Stmt(SwitchStmtClass), Var(Var), FirstCase(0)
703 : {
704 139: SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
705 139: SubExprs[BODY] = NULL;
706 139: }
707 :
708 : /// \brief Build a empty switch statement.
709 4: explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
710 :
711 : /// \brief Retrieve the variable declared in this "switch" statement, if any.
712 : ///
713 : /// In the following example, "x" is the condition variable.
714 : /// \code
715 : /// switch (int x = foo()) {
716 : /// case 0: break;
717 : /// // ...
718 : /// }
719 : /// \endcode
720 106: VarDecl *getConditionVariable() const { return Var; }
721 4: void setConditionVariable(VarDecl *V) { Var = V; }
722 :
723 35: const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
724 35: const Stmt *getBody() const { return SubExprs[BODY]; }
725 : const SwitchCase *getSwitchCaseList() const { return FirstCase; }
726 :
727 546: Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
728 139: void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
729 114: Stmt *getBody() { return SubExprs[BODY]; }
730 4: void setBody(Stmt *S) { SubExprs[BODY] = S; }
731 147: SwitchCase *getSwitchCaseList() { return FirstCase; }
732 :
733 : /// \brief Set the case list for this switch statement.
734 : ///
735 : /// The caller is responsible for incrementing the retain counts on
736 : /// all of the SwitchCase statements in this list.
737 4: void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
738 :
739 9: SourceLocation getSwitchLoc() const { return SwitchLoc; }
740 4: void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
741 :
742 137: void setBody(Stmt *S, SourceLocation SL) {
743 137: SubExprs[BODY] = S;
744 137: SwitchLoc = SL;
745 137: }
746 361: void addSwitchCase(SwitchCase *SC) {
361: branch 1 taken
0: branch 2 not taken
747 361: assert(!SC->getNextSwitchCase() && "case/default already added to a switch");
748 361: SC->Retain();
749 361: SC->setNextSwitchCase(FirstCase);
750 361: FirstCase = SC;
751 361: }
752 13: virtual SourceRange getSourceRange() const {
753 13: return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
754 : }
755 5318: static bool classof(const Stmt *T) {
756 5318: return T->getStmtClass() == SwitchStmtClass;
757 : }
758 : static bool classof(const SwitchStmt *) { return true; }
759 :
760 : // Iterators
761 : virtual child_iterator child_begin();
762 : virtual child_iterator child_end();
763 : };
764 :
765 :
766 : /// WhileStmt - This represents a 'while' stmt.
767 : ///
768 0: class WhileStmt : public Stmt {
769 : enum { COND, BODY, END_EXPR };
770 : VarDecl *Var;
771 : Stmt* SubExprs[END_EXPR];
772 : SourceLocation WhileLoc;
773 : public:
774 165: WhileStmt(VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL)
775 165: : Stmt(WhileStmtClass), Var(Var)
776 : {
777 165: SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
778 165: SubExprs[BODY] = body;
779 165: WhileLoc = WL;
780 165: }
781 :
782 : /// \brief Build an empty while statement.
783 2: explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
784 :
785 : /// \brief Retrieve the variable declared in this "while" statement, if any.
786 : ///
787 : /// In the following example, "x" is the condition variable.
788 : /// \code
789 : /// while (int x = random()) {
790 : /// // ...
791 : /// }
792 : /// \endcode
793 206: VarDecl *getConditionVariable() const { return Var; }
794 2: void setConditionVariable(VarDecl *V) { Var = V; }
795 :
796 485: Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
797 63: const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
798 2: void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
799 244: Stmt *getBody() { return SubExprs[BODY]; }
800 63: const Stmt *getBody() const { return SubExprs[BODY]; }
801 2: void setBody(Stmt *S) { SubExprs[BODY] = S; }
802 :
803 5: SourceLocation getWhileLoc() const { return WhileLoc; }
804 2: void setWhileLoc(SourceLocation L) { WhileLoc = L; }
805 :
806 18: virtual SourceRange getSourceRange() const {
807 18: return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
808 : }
809 2482: static bool classof(const Stmt *T) {
810 2482: return T->getStmtClass() == WhileStmtClass;
811 : }
812 : static bool classof(const WhileStmt *) { return true; }
813 :
814 : // Iterators
815 : virtual child_iterator child_begin();
816 : virtual child_iterator child_end();
817 :
818 : protected:
819 : virtual void DoDestroy(ASTContext &Ctx);
820 : };
821 :
822 : /// DoStmt - This represents a 'do/while' stmt.
823 : ///
824 0: class DoStmt : public Stmt {
825 : enum { COND, BODY, END_EXPR };
826 : Stmt* SubExprs[END_EXPR];
827 : SourceLocation DoLoc;
828 : SourceLocation WhileLoc;
829 : SourceLocation RParenLoc; // Location of final ')' in do stmt condition.
830 :
831 : public:
832 : DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
833 71: SourceLocation RP)
834 71: : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
835 71: SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
836 71: SubExprs[BODY] = body;
837 71: }
838 :
839 : /// \brief Build an empty do-while statement.
840 1: explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { }
841 :
842 263: Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
843 15: const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
844 1: void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
845 106: Stmt *getBody() { return SubExprs[BODY]; }
846 15: const Stmt *getBody() const { return SubExprs[BODY]; }
847 1: void setBody(Stmt *S) { SubExprs[BODY] = S; }
848 :
849 3: SourceLocation getDoLoc() const { return DoLoc; }
850 1: void setDoLoc(SourceLocation L) { DoLoc = L; }
851 5: SourceLocation getWhileLoc() const { return WhileLoc; }
852 1: void setWhileLoc(SourceLocation L) { WhileLoc = L; }
853 :
854 3: SourceLocation getRParenLoc() const { return RParenLoc; }
855 1: void setRParenLoc(SourceLocation L) { RParenLoc = L; }
856 :
857 4: virtual SourceRange getSourceRange() const {
858 4: return SourceRange(DoLoc, RParenLoc);
859 : }
860 2253: static bool classof(const Stmt *T) {
861 2253: return T->getStmtClass() == DoStmtClass;
862 : }
863 : static bool classof(const DoStmt *) { return true; }
864 :
865 : // Iterators
866 : virtual child_iterator child_begin();
867 : virtual child_iterator child_end();
868 : };
869 :
870 :
871 : /// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of
872 : /// the init/cond/inc parts of the ForStmt will be null if they were not
873 : /// specified in the source.
874 : ///
875 0: class ForStmt : public Stmt {
876 : enum { INIT, COND, INC, BODY, END_EXPR };
877 : Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
878 : VarDecl *CondVar;
879 : SourceLocation ForLoc;
880 : SourceLocation LParenLoc, RParenLoc;
881 :
882 : public:
883 : ForStmt(Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc, Stmt *Body,
884 237: SourceLocation FL, SourceLocation LP, SourceLocation RP)
885 : : Stmt(ForStmtClass), CondVar(condVar), ForLoc(FL), LParenLoc(LP),
886 237: RParenLoc(RP)
887 : {
888 237: SubExprs[INIT] = Init;
889 237: SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
890 237: SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
891 237: SubExprs[BODY] = Body;
892 237: }
893 :
894 : /// \brief Build an empty for statement.
895 1: explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
896 :
897 182: Stmt *getInit() { return SubExprs[INIT]; }
898 :
899 : /// \brief Retrieve the variable declared in this "for" statement, if any.
900 : ///
901 : /// In the following example, "y" is the condition variable.
902 : /// \code
903 : /// for (int x = random(); int y = mangle(x); ++x) {
904 : /// // ...
905 : /// }
906 : /// \endcode
907 238: VarDecl *getConditionVariable() const { return CondVar; }
908 1: void setConditionVariable(VarDecl *V) { CondVar = V; }
909 :
910 1325: Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
911 168: Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
912 318: Stmt *getBody() { return SubExprs[BODY]; }
913 :
914 132: const Stmt *getInit() const { return SubExprs[INIT]; }
915 140: const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
916 209: const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
917 73: const Stmt *getBody() const { return SubExprs[BODY]; }
918 :
919 1: void setInit(Stmt *S) { SubExprs[INIT] = S; }
920 1: void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
921 1: void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
922 1: void setBody(Stmt *S) { SubExprs[BODY] = S; }
923 :
924 15: SourceLocation getForLoc() const { return ForLoc; }
925 1: void setForLoc(SourceLocation L) { ForLoc = L; }
926 15: SourceLocation getLParenLoc() const { return LParenLoc; }
927 1: void setLParenLoc(SourceLocation L) { LParenLoc = L; }
928 15: SourceLocation getRParenLoc() const { return RParenLoc; }
929 1: void setRParenLoc(SourceLocation L) { RParenLoc = L; }
930 :
931 38: virtual SourceRange getSourceRange() const {
932 38: return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
933 : }
934 3347: static bool classof(const Stmt *T) {
935 3347: return T->getStmtClass() == ForStmtClass;
936 : }
937 : static bool classof(const ForStmt *) { return true; }
938 :
939 : // Iterators
940 : virtual child_iterator child_begin();
941 : virtual child_iterator child_end();
942 :
943 : protected:
944 : virtual void DoDestroy(ASTContext &Ctx);
945 : };
946 :
947 : /// GotoStmt - This represents a direct goto.
948 : ///
949 3: class GotoStmt : public Stmt {
950 : LabelStmt *Label;
951 : SourceLocation GotoLoc;
952 : SourceLocation LabelLoc;
953 : public:
954 122: GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
955 122: : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
956 :
957 : /// \brief Build an empty goto statement.
958 2: explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
959 :
960 132: LabelStmt *getLabel() const { return Label; }
961 2: void setLabel(LabelStmt *S) { Label = S; }
962 :
963 72: SourceLocation getGotoLoc() const { return GotoLoc; }
964 2: void setGotoLoc(SourceLocation L) { GotoLoc = L; }
965 3: SourceLocation getLabelLoc() const { return LabelLoc; }
966 2: void setLabelLoc(SourceLocation L) { LabelLoc = L; }
967 :
968 17: virtual SourceRange getSourceRange() const {
969 17: return SourceRange(GotoLoc, LabelLoc);
970 : }
971 2754: static bool classof(const Stmt *T) {
972 2754: return T->getStmtClass() == GotoStmtClass;
973 : }
974 : static bool classof(const GotoStmt *) { return true; }
975 :
976 : // Iterators
977 : virtual child_iterator child_begin();
978 : virtual child_iterator child_end();
979 : };
980 :
981 : /// IndirectGotoStmt - This represents an indirect goto.
982 : ///
983 0: class IndirectGotoStmt : public Stmt {
984 : SourceLocation GotoLoc;
985 : SourceLocation StarLoc;
986 : Stmt *Target;
987 : public:
988 : IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
989 32: Expr *target)
990 : : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
991 32: Target((Stmt*)target) {}
992 :
993 : /// \brief Build an empty indirect goto statement.
994 1: explicit IndirectGotoStmt(EmptyShell Empty)
995 1: : Stmt(IndirectGotoStmtClass, Empty) { }
996 :
997 1: void setGotoLoc(SourceLocation L) { GotoLoc = L; }
998 4: SourceLocation getGotoLoc() const { return GotoLoc; }
999 1: void setStarLoc(SourceLocation L) { StarLoc = L; }
1000 3: SourceLocation getStarLoc() const { return StarLoc; }
1001 :
1002 : Expr *getTarget();
1003 : const Expr *getTarget() const;
1004 1: void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
1005 :
1006 4: virtual SourceRange getSourceRange() const {
1007 4: return SourceRange(GotoLoc, Target->getLocEnd());
1008 : }
1009 :
1010 2527: static bool classof(const Stmt *T) {
1011 2527: return T->getStmtClass() == IndirectGotoStmtClass;
1012 : }
1013 : static bool classof(const IndirectGotoStmt *) { return true; }
1014 :
1015 : // Iterators
1016 : virtual child_iterator child_begin();
1017 : virtual child_iterator child_end();
1018 : };
1019 :
1020 :
1021 : /// ContinueStmt - This represents a continue.
1022 : ///
1023 0: class ContinueStmt : public Stmt {
1024 : SourceLocation ContinueLoc;
1025 : public:
1026 28: ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
1027 :
1028 : /// \brief Build an empty continue statement.
1029 1: explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { }
1030 :
1031 1: SourceLocation getContinueLoc() const { return ContinueLoc; }
1032 1: void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
1033 :
1034 8: virtual SourceRange getSourceRange() const {
1035 8: return SourceRange(ContinueLoc);
1036 : }
1037 :
1038 986: static bool classof(const Stmt *T) {
1039 986: return T->getStmtClass() == ContinueStmtClass;
1040 : }
1041 : static bool classof(const ContinueStmt *) { return true; }
1042 :
1043 : // Iterators
1044 : virtual child_iterator child_begin();
1045 : virtual child_iterator child_end();
1046 : };
1047 :
1048 : /// BreakStmt - This represents a break.
1049 : ///
1050 5: class BreakStmt : public Stmt {
1051 : SourceLocation BreakLoc;
1052 : public:
1053 253: BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
1054 :
1055 : /// \brief Build an empty break statement.
1056 6: explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
1057 :
1058 6: SourceLocation getBreakLoc() const { return BreakLoc; }
1059 6: void setBreakLoc(SourceLocation L) { BreakLoc = L; }
1060 :
1061 39: virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
1062 :
1063 1197: static bool classof(const Stmt *T) {
1064 1197: return T->getStmtClass() == BreakStmtClass;
1065 : }
1066 : static bool classof(const BreakStmt *) { return true; }
1067 :
1068 : // Iterators
1069 : virtual child_iterator child_begin();
1070 : virtual child_iterator child_end();
1071 : };
1072 :
1073 :
1074 : /// ReturnStmt - This represents a return, optionally of an expression:
1075 : /// return;
1076 : /// return 4;
1077 : ///
1078 : /// Note that GCC allows return with no argument in a function declared to
1079 : /// return a value, and it allows returning a value in functions declared to
1080 : /// return void. We explicitly model this in the AST, which means you can't
1081 : /// depend on the return type of the function and the presence of an argument.
1082 : ///
1083 10: class ReturnStmt : public Stmt {
1084 : Stmt *RetExpr;
1085 : SourceLocation RetLoc;
1086 : public:
1087 4518: ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
1088 4518: RetExpr((Stmt*) E), RetLoc(RL) {}
1089 :
1090 : /// \brief Build an empty return expression.
1091 13: explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
1092 :
1093 : const Expr *getRetValue() const;
1094 : Expr *getRetValue();
1095 13: void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); }
1096 :
1097 149: SourceLocation getReturnLoc() const { return RetLoc; }
1098 13: void setReturnLoc(SourceLocation L) { RetLoc = L; }
1099 :
1100 : virtual SourceRange getSourceRange() const;
1101 :
1102 11023: static bool classof(const Stmt *T) {
1103 11023: return T->getStmtClass() == ReturnStmtClass;
1104 : }
1105 : static bool classof(const ReturnStmt *) { return true; }
1106 :
1107 : // Iterators
1108 : virtual child_iterator child_begin();
1109 : virtual child_iterator child_end();
1110 : };
1111 :
1112 : /// AsmStmt - This represents a GNU inline-assembly statement extension.
1113 : ///
1114 7: class AsmStmt : public Stmt {
1115 : SourceLocation AsmLoc, RParenLoc;
1116 : StringLiteral *AsmStr;
1117 :
1118 : bool IsSimple;
1119 : bool IsVolatile;
1120 : bool MSAsm;
1121 :
1122 : unsigned NumOutputs;
1123 : unsigned NumInputs;
1124 : unsigned NumClobbers;
1125 :
1126 : // FIXME: If we wanted to, we could allocate all of these in one big array.
1127 : IdentifierInfo **Names;
1128 : StringLiteral **Constraints;
1129 : Stmt **Exprs;
1130 : StringLiteral **Clobbers;
1131 :
1132 : protected:
1133 : virtual void DoDestroy(ASTContext &Ctx);
1134 :
1135 : public:
1136 : AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile,
1137 : bool msasm, unsigned numoutputs, unsigned numinputs,
1138 : IdentifierInfo **names, StringLiteral **constraints,
1139 : Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
1140 : StringLiteral **clobbers, SourceLocation rparenloc);
1141 :
1142 : /// \brief Build an empty inline-assembly statement.
1143 5: explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty),
1144 5: Names(0), Constraints(0), Exprs(0), Clobbers(0) { }
1145 :
1146 6: SourceLocation getAsmLoc() const { return AsmLoc; }
1147 5: void setAsmLoc(SourceLocation L) { AsmLoc = L; }
1148 6: SourceLocation getRParenLoc() const { return RParenLoc; }
1149 5: void setRParenLoc(SourceLocation L) { RParenLoc = L; }
1150 :
1151 42: bool isVolatile() const { return IsVolatile; }
1152 5: void setVolatile(bool V) { IsVolatile = V; }
1153 130: bool isSimple() const { return IsSimple; }
1154 5: void setSimple(bool V) { IsSimple = V; }
1155 7: bool isMSAsm() const { return MSAsm; }
1156 5: void setMSAsm(bool V) { MSAsm = V; }
1157 :
1158 : //===--- Asm String Analysis ---===//
1159 :
1160 248: const StringLiteral *getAsmString() const { return AsmStr; }
1161 7: StringLiteral *getAsmString() { return AsmStr; }
1162 5: void setAsmString(StringLiteral *E) { AsmStr = E; }
1163 :
1164 : /// AsmStringPiece - this is part of a decomposed asm string specification
1165 : /// (for use with the AnalyzeAsmString function below). An asm string is
1166 : /// considered to be a concatenation of these parts.
1167 422: class AsmStringPiece {
1168 : public:
1169 : enum Kind {
1170 : String, // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
1171 : Operand // Operand reference, with optional modifier %c4.
1172 : };
1173 : private:
1174 : Kind MyKind;
1175 : std::string Str;
1176 : unsigned OperandNo;
1177 : public:
1178 109: AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
1179 29: AsmStringPiece(unsigned OpNo, char Modifier)
1180 29: : MyKind(Operand), Str(), OperandNo(OpNo) {
1181 29: Str += Modifier;
1182 29: }
1183 :
1184 76: bool isString() const { return MyKind == String; }
1185 35: bool isOperand() const { return MyKind == Operand; }
1186 :
1187 32: const std::string &getString() const {
1188 32: assert(isString());
1189 32: return Str;
1190 : }
1191 :
1192 16: unsigned getOperandNo() const {
0: branch 1 not taken
0: branch 2 not taken
1193 16: assert(isOperand());
1194 16: return OperandNo;
1195 : }
1196 :
1197 : /// getModifier - Get the modifier for this operand, if present. This
1198 : /// returns '\0' if there was no modifier.
1199 13: char getModifier() const {
1200 13: assert(isOperand());
1201 13: return Str[0];
1202 : }
1203 : };
1204 :
1205 : /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
1206 : /// it into pieces. If the asm string is erroneous, emit errors and return
1207 : /// true, otherwise return false. This handles canonicalization and
1208 : /// translation of strings from GCC syntax to LLVM IR syntax, and handles
1209 : //// flattening of named references like %[foo] to Operand AsmStringPiece's.
1210 : unsigned AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece> &Pieces,
1211 : ASTContext &C, unsigned &DiagOffs) const;
1212 :
1213 :
1214 : //===--- Output operands ---===//
1215 :
1216 223: unsigned getNumOutputs() const { return NumOutputs; }
1217 :
1218 34: IdentifierInfo *getOutputIdentifier(unsigned i) const {
1219 34: return Names[i];
1220 : }
1221 :
1222 31: llvm::StringRef getOutputName(unsigned i) const {
1223 31: if (IdentifierInfo *II = getOutputIdentifier(i))
1224 9: return II->getName();
1225 :
1226 22: return llvm::StringRef();
1227 : }
1228 :
1229 : /// getOutputConstraint - Return the constraint string for the specified
1230 : /// output operand. All output constraints are known to be non-empty (either
1231 : /// '=' or '+').
1232 : llvm::StringRef getOutputConstraint(unsigned i) const;
1233 :
1234 58: const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
1235 58: return Constraints[i];
1236 : }
1237 3: StringLiteral *getOutputConstraintLiteral(unsigned i) {
1238 3: return Constraints[i];
1239 : }
1240 :
1241 : Expr *getOutputExpr(unsigned i);
1242 :
1243 34: const Expr *getOutputExpr(unsigned i) const {
1244 34: return const_cast<AsmStmt*>(this)->getOutputExpr(i);
1245 : }
1246 :
1247 : /// isOutputPlusConstraint - Return true if the specified output constraint
1248 : /// is a "+" constraint (which is both an input and an output) or false if it
1249 : /// is an "=" constraint (just an output).
1250 16: bool isOutputPlusConstraint(unsigned i) const {
1251 16: return getOutputConstraint(i)[0] == '+';
1252 : }
1253 :
1254 : /// getNumPlusOperands - Return the number of output operands that have a "+"
1255 : /// constraint.
1256 : unsigned getNumPlusOperands() const;
1257 :
1258 : //===--- Input operands ---===//
1259 :
1260 160: unsigned getNumInputs() const { return NumInputs; }
1261 :
1262 44: IdentifierInfo *getInputIdentifier(unsigned i) const {
1263 44: return Names[i + NumOutputs];
1264 : }
1265 :
1266 41: llvm::StringRef getInputName(unsigned i) const {
1267 41: if (IdentifierInfo *II = getInputIdentifier(i))
1268 22: return II->getName();
1269 :
1270 19: return llvm::StringRef();
1271 : }
1272 :
1273 : /// getInputConstraint - Return the specified input constraint. Unlike output
1274 : /// constraints, these can be empty.
1275 : llvm::StringRef getInputConstraint(unsigned i) const;
1276 :
1277 46: const StringLiteral *getInputConstraintLiteral(unsigned i) const {
1278 46: return Constraints[i + NumOutputs];
1279 : }
1280 3: StringLiteral *getInputConstraintLiteral(unsigned i) {
1281 3: return Constraints[i + NumOutputs];
1282 : }
1283 :
1284 : Expr *getInputExpr(unsigned i);
1285 :
1286 28: const Expr *getInputExpr(unsigned i) const {
1287 28: return const_cast<AsmStmt*>(this)->getInputExpr(i);
1288 : }
1289 :
1290 : void setOutputsAndInputsAndClobbers(ASTContext &C,
1291 : IdentifierInfo **Names,
1292 : StringLiteral **Constraints,
1293 : Stmt **Exprs,
1294 : unsigned NumOutputs,
1295 : unsigned NumInputs,
1296 : StringLiteral **Clobbers,
1297 : unsigned NumClobbers);
1298 :
1299 : //===--- Other ---===//
1300 :
1301 : /// getNamedOperand - Given a symbolic operand reference like %[foo],
1302 : /// translate this into a numeric value needed to reference the same operand.
1303 : /// This returns -1 if the operand name is invalid.
1304 : int getNamedOperand(llvm::StringRef SymbolicName) const;
1305 :
1306 50: unsigned getNumClobbers() const { return NumClobbers; }
1307 10: StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
1308 18: const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
1309 :
1310 4: virtual SourceRange getSourceRange() const {
1311 4: return SourceRange(AsmLoc, RParenLoc);
1312 : }
1313 :
1314 127: static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
1315 : static bool classof(const AsmStmt *) { return true; }
1316 :
1317 : // Input expr iterators.
1318 :
1319 : typedef ExprIterator inputs_iterator;
1320 : typedef ConstExprIterator const_inputs_iterator;
1321 :
1322 0: inputs_iterator begin_inputs() {
1323 0: return &Exprs[0] + NumOutputs;
1324 : }
1325 :
1326 0: inputs_iterator end_inputs() {
1327 0: return &Exprs[0] + NumOutputs + NumInputs;
1328 : }
1329 :
1330 : const_inputs_iterator begin_inputs() const {
1331 : return &Exprs[0] + NumOutputs;
1332 : }
1333 :
1334 : const_inputs_iterator end_inputs() const {
1335 : return &Exprs[0] + NumOutputs + NumInputs;
1336 : }
1337 :
1338 : // Output expr iterators.
1339 :
1340 : typedef ExprIterator outputs_iterator;
1341 : typedef ConstExprIterator const_outputs_iterator;
1342 :
1343 0: outputs_iterator begin_outputs() {
1344 0: return &Exprs[0];
1345 : }
1346 0: outputs_iterator end_outputs() {
1347 0: return &Exprs[0] + NumOutputs;
1348 : }
1349 :
1350 : const_outputs_iterator begin_outputs() const {
1351 : return &Exprs[0];
1352 : }
1353 : const_outputs_iterator end_outputs() const {
1354 : return &Exprs[0] + NumOutputs;
1355 : }
1356 :
1357 : // Child iterators
1358 :
1359 : virtual child_iterator child_begin();
1360 : virtual child_iterator child_end();
1361 : };
1362 :
1363 : } // end namespace clang
1364 :
1365 : #endif
Generated: 2010-02-10 01:31 by zcov