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 "clang/AST/DeclGroup.h"
18 #include "clang/AST/StmtIterator.h"
19 #include "clang/Basic/CapturedStmt.h"
20 #include "clang/Basic/IdentifierTable.h"
21 #include "clang/Basic/LLVM.h"
22 #include "clang/Basic/SourceLocation.h"
23 #include "llvm/ADT/ArrayRef.h"
24 #include "llvm/ADT/PointerIntPair.h"
25 #include "llvm/Support/Compiler.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include <string>
28
29 namespace llvm {
30 class FoldingSetNodeID;
31 }
32
33 namespace clang {
34 class ASTContext;
35 class Attr;
36 class CapturedDecl;
37 class Decl;
38 class Expr;
39 class IdentifierInfo;
40 class LabelDecl;
41 class ParmVarDecl;
42 class PrinterHelper;
43 struct PrintingPolicy;
44 class QualType;
45 class RecordDecl;
46 class SourceManager;
47 class StringLiteral;
48 class SwitchStmt;
49 class Token;
50 class VarDecl;
51
52 //===--------------------------------------------------------------------===//
53 // ExprIterator - Iterators for iterating over Stmt* arrays that contain
54 // only Expr*. This is needed because AST nodes use Stmt* arrays to store
55 // references to children (to be compatible with StmtIterator).
56 //===--------------------------------------------------------------------===//
57
58 class Stmt;
59 class Expr;
60
61 class ExprIterator {
62 Stmt** I;
63 public:
ExprIterator(Stmt ** i)64 ExprIterator(Stmt** i) : I(i) {}
ExprIterator()65 ExprIterator() : I(nullptr) {}
66 ExprIterator& operator++() { ++I; return *this; }
67 ExprIterator operator-(size_t i) { return I-i; }
68 ExprIterator operator+(size_t i) { return I+i; }
69 Expr* operator[](size_t idx);
70 // FIXME: Verify that this will correctly return a signed distance.
71 signed operator-(const ExprIterator& R) const { return I - R.I; }
72 Expr* operator*() const;
73 Expr* operator->() const;
74 bool operator==(const ExprIterator& R) const { return I == R.I; }
75 bool operator!=(const ExprIterator& R) const { return I != R.I; }
76 bool operator>(const ExprIterator& R) const { return I > R.I; }
77 bool operator>=(const ExprIterator& R) const { return I >= R.I; }
78 };
79
80 class ConstExprIterator {
81 const Stmt * const *I;
82 public:
ConstExprIterator(const Stmt * const * i)83 ConstExprIterator(const Stmt * const *i) : I(i) {}
ConstExprIterator()84 ConstExprIterator() : I(nullptr) {}
85 ConstExprIterator& operator++() { ++I; return *this; }
86 ConstExprIterator operator+(size_t i) const { return I+i; }
87 ConstExprIterator operator-(size_t i) const { return I-i; }
88 const Expr * operator[](size_t idx) const;
89 signed operator-(const ConstExprIterator& R) const { return I - R.I; }
90 const Expr * operator*() const;
91 const Expr * operator->() const;
92 bool operator==(const ConstExprIterator& R) const { return I == R.I; }
93 bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
94 bool operator>(const ConstExprIterator& R) const { return I > R.I; }
95 bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
96 };
97
98 //===----------------------------------------------------------------------===//
99 // AST classes for statements.
100 //===----------------------------------------------------------------------===//
101
102 /// Stmt - This represents one statement.
103 ///
LLVM_ALIGNAS(LLVM_PTR_SIZE)104 class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt {
105 public:
106 enum StmtClass {
107 NoStmtClass = 0,
108 #define STMT(CLASS, PARENT) CLASS##Class,
109 #define STMT_RANGE(BASE, FIRST, LAST) \
110 first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class,
111 #define LAST_STMT_RANGE(BASE, FIRST, LAST) \
112 first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
113 #define ABSTRACT_STMT(STMT)
114 #include "clang/AST/StmtNodes.inc"
115 };
116
117 // Make vanilla 'new' and 'delete' illegal for Stmts.
118 protected:
119 void* operator new(size_t bytes) throw() {
120 llvm_unreachable("Stmts cannot be allocated with regular 'new'.");
121 }
122 void operator delete(void* data) throw() {
123 llvm_unreachable("Stmts cannot be released with regular 'delete'.");
124 }
125
126 class StmtBitfields {
127 friend class Stmt;
128
129 /// \brief The statement class.
130 unsigned sClass : 8;
131 };
132 enum { NumStmtBits = 8 };
133
134 class CompoundStmtBitfields {
135 friend class CompoundStmt;
136 unsigned : NumStmtBits;
137
138 unsigned NumStmts : 32 - NumStmtBits;
139 };
140
141 class ExprBitfields {
142 friend class Expr;
143 friend class DeclRefExpr; // computeDependence
144 friend class InitListExpr; // ctor
145 friend class DesignatedInitExpr; // ctor
146 friend class BlockDeclRefExpr; // ctor
147 friend class ASTStmtReader; // deserialization
148 friend class CXXNewExpr; // ctor
149 friend class DependentScopeDeclRefExpr; // ctor
150 friend class CXXConstructExpr; // ctor
151 friend class CallExpr; // ctor
152 friend class OffsetOfExpr; // ctor
153 friend class ObjCMessageExpr; // ctor
154 friend class ObjCArrayLiteral; // ctor
155 friend class ObjCDictionaryLiteral; // ctor
156 friend class ShuffleVectorExpr; // ctor
157 friend class ParenListExpr; // ctor
158 friend class CXXUnresolvedConstructExpr; // ctor
159 friend class CXXDependentScopeMemberExpr; // ctor
160 friend class OverloadExpr; // ctor
161 friend class PseudoObjectExpr; // ctor
162 friend class AtomicExpr; // ctor
163 unsigned : NumStmtBits;
164
165 unsigned ValueKind : 2;
166 unsigned ObjectKind : 2;
167 unsigned TypeDependent : 1;
168 unsigned ValueDependent : 1;
169 unsigned InstantiationDependent : 1;
170 unsigned ContainsUnexpandedParameterPack : 1;
171 };
172 enum { NumExprBits = 16 };
173
174 class CharacterLiteralBitfields {
175 friend class CharacterLiteral;
176 unsigned : NumExprBits;
177
178 unsigned Kind : 2;
179 };
180
181 enum APFloatSemantics {
182 IEEEhalf,
183 IEEEsingle,
184 IEEEdouble,
185 x87DoubleExtended,
186 IEEEquad,
187 PPCDoubleDouble
188 };
189
190 class FloatingLiteralBitfields {
191 friend class FloatingLiteral;
192 unsigned : NumExprBits;
193
194 unsigned Semantics : 3; // Provides semantics for APFloat construction
195 unsigned IsExact : 1;
196 };
197
198 class UnaryExprOrTypeTraitExprBitfields {
199 friend class UnaryExprOrTypeTraitExpr;
200 unsigned : NumExprBits;
201
202 unsigned Kind : 2;
203 unsigned IsType : 1; // true if operand is a type, false if an expression.
204 };
205
206 class DeclRefExprBitfields {
207 friend class DeclRefExpr;
208 friend class ASTStmtReader; // deserialization
209 unsigned : NumExprBits;
210
211 unsigned HasQualifier : 1;
212 unsigned HasTemplateKWAndArgsInfo : 1;
213 unsigned HasFoundDecl : 1;
214 unsigned HadMultipleCandidates : 1;
215 unsigned RefersToEnclosingVariableOrCapture : 1;
216 };
217
218 class CastExprBitfields {
219 friend class CastExpr;
220 unsigned : NumExprBits;
221
222 unsigned Kind : 6;
223 unsigned BasePathSize : 32 - 6 - NumExprBits;
224 };
225
226 class CallExprBitfields {
227 friend class CallExpr;
228 unsigned : NumExprBits;
229
230 unsigned NumPreArgs : 1;
231 };
232
233 class ExprWithCleanupsBitfields {
234 friend class ExprWithCleanups;
235 friend class ASTStmtReader; // deserialization
236
237 unsigned : NumExprBits;
238
239 unsigned NumObjects : 32 - NumExprBits;
240 };
241
242 class PseudoObjectExprBitfields {
243 friend class PseudoObjectExpr;
244 friend class ASTStmtReader; // deserialization
245
246 unsigned : NumExprBits;
247
248 // These don't need to be particularly wide, because they're
249 // strictly limited by the forms of expressions we permit.
250 unsigned NumSubExprs : 8;
251 unsigned ResultIndex : 32 - 8 - NumExprBits;
252 };
253
254 class ObjCIndirectCopyRestoreExprBitfields {
255 friend class ObjCIndirectCopyRestoreExpr;
256 unsigned : NumExprBits;
257
258 unsigned ShouldCopy : 1;
259 };
260
261 class InitListExprBitfields {
262 friend class InitListExpr;
263
264 unsigned : NumExprBits;
265
266 /// Whether this initializer list originally had a GNU array-range
267 /// designator in it. This is a temporary marker used by CodeGen.
268 unsigned HadArrayRangeDesignator : 1;
269 };
270
271 class TypeTraitExprBitfields {
272 friend class TypeTraitExpr;
273 friend class ASTStmtReader;
274 friend class ASTStmtWriter;
275
276 unsigned : NumExprBits;
277
278 /// \brief The kind of type trait, which is a value of a TypeTrait enumerator.
279 unsigned Kind : 8;
280
281 /// \brief If this expression is not value-dependent, this indicates whether
282 /// the trait evaluated true or false.
283 unsigned Value : 1;
284
285 /// \brief The number of arguments to this type trait.
286 unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
287 };
288
289 union {
290 StmtBitfields StmtBits;
291 CompoundStmtBitfields CompoundStmtBits;
292 ExprBitfields ExprBits;
293 CharacterLiteralBitfields CharacterLiteralBits;
294 FloatingLiteralBitfields FloatingLiteralBits;
295 UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits;
296 DeclRefExprBitfields DeclRefExprBits;
297 CastExprBitfields CastExprBits;
298 CallExprBitfields CallExprBits;
299 ExprWithCleanupsBitfields ExprWithCleanupsBits;
300 PseudoObjectExprBitfields PseudoObjectExprBits;
301 ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
302 InitListExprBitfields InitListExprBits;
303 TypeTraitExprBitfields TypeTraitExprBits;
304 };
305
306 friend class ASTStmtReader;
307 friend class ASTStmtWriter;
308
309 public:
310 // Only allow allocation of Stmts using the allocator in ASTContext
311 // or by doing a placement new.
312 void* operator new(size_t bytes, const ASTContext& C,
313 unsigned alignment = 8);
314
315 void* operator new(size_t bytes, const ASTContext* C,
316 unsigned alignment = 8) {
317 return operator new(bytes, *C, alignment);
318 }
319
320 void* operator new(size_t bytes, void* mem) throw() {
321 return mem;
322 }
323
324 void operator delete(void*, const ASTContext&, unsigned) throw() { }
325 void operator delete(void*, const ASTContext*, unsigned) throw() { }
326 void operator delete(void*, size_t) throw() { }
327 void operator delete(void*, void*) throw() { }
328
329 public:
330 /// \brief A placeholder type used to construct an empty shell of a
331 /// type, that will be filled in later (e.g., by some
332 /// de-serialization).
333 struct EmptyShell { };
334
335 private:
336 /// \brief Whether statistic collection is enabled.
337 static bool StatisticsEnabled;
338
339 protected:
340 /// \brief Construct an empty statement.
341 explicit Stmt(StmtClass SC, EmptyShell) : Stmt(SC) {}
342
343 public:
344 Stmt(StmtClass SC) {
345 static_assert(sizeof(*this) % llvm::AlignOf<void *>::Alignment == 0,
346 "Insufficient alignment!");
347 StmtBits.sClass = SC;
348 if (StatisticsEnabled) Stmt::addStmtClass(SC);
349 }
350
351 StmtClass getStmtClass() const {
352 return static_cast<StmtClass>(StmtBits.sClass);
353 }
354 const char *getStmtClassName() const;
355
356 /// SourceLocation tokens are not useful in isolation - they are low level
357 /// value objects created/interpreted by SourceManager. We assume AST
358 /// clients will have a pointer to the respective SourceManager.
359 SourceRange getSourceRange() const LLVM_READONLY;
360 SourceLocation getLocStart() const LLVM_READONLY;
361 SourceLocation getLocEnd() const LLVM_READONLY;
362
363 // global temp stats (until we have a per-module visitor)
364 static void addStmtClass(const StmtClass s);
365 static void EnableStatistics();
366 static void PrintStats();
367
368 /// \brief Dumps the specified AST fragment and all subtrees to
369 /// \c llvm::errs().
370 void dump() const;
371 void dump(SourceManager &SM) const;
372 void dump(raw_ostream &OS, SourceManager &SM) const;
373 void dump(raw_ostream &OS) const;
374
375 /// dumpColor - same as dump(), but forces color highlighting.
376 void dumpColor() const;
377
378 /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
379 /// back to its original source language syntax.
380 void dumpPretty(const ASTContext &Context) const;
381 void printPretty(raw_ostream &OS, PrinterHelper *Helper,
382 const PrintingPolicy &Policy,
383 unsigned Indentation = 0) const;
384
385 /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
386 /// works on systems with GraphViz (Mac OS X) or dot+gv installed.
387 void viewAST() const;
388
389 /// Skip past any implicit AST nodes which might surround this
390 /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
391 Stmt *IgnoreImplicit();
392
393 /// \brief Skip no-op (attributed, compound) container stmts and skip captured
394 /// stmt at the top, if \a IgnoreCaptured is true.
395 Stmt *IgnoreContainers(bool IgnoreCaptured = false);
396
397 const Stmt *stripLabelLikeStatements() const;
398 Stmt *stripLabelLikeStatements() {
399 return const_cast<Stmt*>(
400 const_cast<const Stmt*>(this)->stripLabelLikeStatements());
401 }
402
403 /// Child Iterators: All subclasses must implement 'children'
404 /// to permit easy iteration over the substatements/subexpessions of an
405 /// AST node. This permits easy iteration over all nodes in the AST.
406 typedef StmtIterator child_iterator;
407 typedef ConstStmtIterator const_child_iterator;
408
409 typedef StmtRange child_range;
410 typedef ConstStmtRange const_child_range;
411
412 child_range children();
413 const_child_range children() const {
414 return const_cast<Stmt*>(this)->children();
415 }
416
417 child_iterator child_begin() { return children().first; }
418 child_iterator child_end() { return children().second; }
419
420 const_child_iterator child_begin() const { return children().first; }
421 const_child_iterator child_end() const { return children().second; }
422
423 /// \brief Produce a unique representation of the given statement.
424 ///
425 /// \param ID once the profiling operation is complete, will contain
426 /// the unique representation of the given statement.
427 ///
428 /// \param Context the AST context in which the statement resides
429 ///
430 /// \param Canonical whether the profile should be based on the canonical
431 /// representation of this statement (e.g., where non-type template
432 /// parameters are identified by index/level rather than their
433 /// declaration pointers) or the exact representation of the statement as
434 /// written in the source.
435 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
436 bool Canonical) const;
437 };
438
439 /// DeclStmt - Adaptor class for mixing declarations with statements and
440 /// expressions. For example, CompoundStmt mixes statements, expressions
441 /// and declarations (variables, types). Another example is ForStmt, where
442 /// the first statement can be an expression or a declaration.
443 ///
444 class DeclStmt : public Stmt {
445 DeclGroupRef DG;
446 SourceLocation StartLoc, EndLoc;
447
448 public:
DeclStmt(DeclGroupRef dg,SourceLocation startLoc,SourceLocation endLoc)449 DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
450 SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
451 StartLoc(startLoc), EndLoc(endLoc) {}
452
453 /// \brief Build an empty declaration statement.
DeclStmt(EmptyShell Empty)454 explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { }
455
456 /// isSingleDecl - This method returns true if this DeclStmt refers
457 /// to a single Decl.
isSingleDecl()458 bool isSingleDecl() const {
459 return DG.isSingleDecl();
460 }
461
getSingleDecl()462 const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
getSingleDecl()463 Decl *getSingleDecl() { return DG.getSingleDecl(); }
464
getDeclGroup()465 const DeclGroupRef getDeclGroup() const { return DG; }
getDeclGroup()466 DeclGroupRef getDeclGroup() { return DG; }
setDeclGroup(DeclGroupRef DGR)467 void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
468
getStartLoc()469 SourceLocation getStartLoc() const { return StartLoc; }
setStartLoc(SourceLocation L)470 void setStartLoc(SourceLocation L) { StartLoc = L; }
getEndLoc()471 SourceLocation getEndLoc() const { return EndLoc; }
setEndLoc(SourceLocation L)472 void setEndLoc(SourceLocation L) { EndLoc = L; }
473
getLocStart()474 SourceLocation getLocStart() const LLVM_READONLY { return StartLoc; }
getLocEnd()475 SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
476
classof(const Stmt * T)477 static bool classof(const Stmt *T) {
478 return T->getStmtClass() == DeclStmtClass;
479 }
480
481 // Iterators over subexpressions.
children()482 child_range children() {
483 return child_range(child_iterator(DG.begin(), DG.end()),
484 child_iterator(DG.end(), DG.end()));
485 }
486
487 typedef DeclGroupRef::iterator decl_iterator;
488 typedef DeclGroupRef::const_iterator const_decl_iterator;
489 typedef llvm::iterator_range<decl_iterator> decl_range;
490 typedef llvm::iterator_range<const_decl_iterator> decl_const_range;
491
decls()492 decl_range decls() { return decl_range(decl_begin(), decl_end()); }
decls()493 decl_const_range decls() const {
494 return decl_const_range(decl_begin(), decl_end());
495 }
decl_begin()496 decl_iterator decl_begin() { return DG.begin(); }
decl_end()497 decl_iterator decl_end() { return DG.end(); }
decl_begin()498 const_decl_iterator decl_begin() const { return DG.begin(); }
decl_end()499 const_decl_iterator decl_end() const { return DG.end(); }
500
501 typedef std::reverse_iterator<decl_iterator> reverse_decl_iterator;
decl_rbegin()502 reverse_decl_iterator decl_rbegin() {
503 return reverse_decl_iterator(decl_end());
504 }
decl_rend()505 reverse_decl_iterator decl_rend() {
506 return reverse_decl_iterator(decl_begin());
507 }
508 };
509
510 /// NullStmt - This is the null statement ";": C99 6.8.3p3.
511 ///
512 class NullStmt : public Stmt {
513 SourceLocation SemiLoc;
514
515 /// \brief True if the null statement was preceded by an empty macro, e.g:
516 /// @code
517 /// #define CALL(x)
518 /// CALL(0);
519 /// @endcode
520 bool HasLeadingEmptyMacro;
521 public:
522 NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
Stmt(NullStmtClass)523 : Stmt(NullStmtClass), SemiLoc(L),
524 HasLeadingEmptyMacro(hasLeadingEmptyMacro) {}
525
526 /// \brief Build an empty null statement.
NullStmt(EmptyShell Empty)527 explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty),
528 HasLeadingEmptyMacro(false) { }
529
getSemiLoc()530 SourceLocation getSemiLoc() const { return SemiLoc; }
setSemiLoc(SourceLocation L)531 void setSemiLoc(SourceLocation L) { SemiLoc = L; }
532
hasLeadingEmptyMacro()533 bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; }
534
getLocStart()535 SourceLocation getLocStart() const LLVM_READONLY { return SemiLoc; }
getLocEnd()536 SourceLocation getLocEnd() const LLVM_READONLY { return SemiLoc; }
537
classof(const Stmt * T)538 static bool classof(const Stmt *T) {
539 return T->getStmtClass() == NullStmtClass;
540 }
541
children()542 child_range children() { return child_range(); }
543
544 friend class ASTStmtReader;
545 friend class ASTStmtWriter;
546 };
547
548 /// CompoundStmt - This represents a group of statements like { stmt stmt }.
549 ///
550 class CompoundStmt : public Stmt {
551 Stmt** Body;
552 SourceLocation LBraceLoc, RBraceLoc;
553
554 friend class ASTStmtReader;
555
556 public:
557 CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
558 SourceLocation LB, SourceLocation RB);
559
560 // \brief Build an empty compound statement with a location.
CompoundStmt(SourceLocation Loc)561 explicit CompoundStmt(SourceLocation Loc)
562 : Stmt(CompoundStmtClass), Body(nullptr), LBraceLoc(Loc), RBraceLoc(Loc) {
563 CompoundStmtBits.NumStmts = 0;
564 }
565
566 // \brief Build an empty compound statement.
CompoundStmt(EmptyShell Empty)567 explicit CompoundStmt(EmptyShell Empty)
568 : Stmt(CompoundStmtClass, Empty), Body(nullptr) {
569 CompoundStmtBits.NumStmts = 0;
570 }
571
572 void setStmts(const ASTContext &C, Stmt **Stmts, unsigned NumStmts);
573
body_empty()574 bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
size()575 unsigned size() const { return CompoundStmtBits.NumStmts; }
576
577 typedef Stmt** body_iterator;
578 typedef llvm::iterator_range<body_iterator> body_range;
579
body()580 body_range body() { return body_range(body_begin(), body_end()); }
body_begin()581 body_iterator body_begin() { return Body; }
body_end()582 body_iterator body_end() { return Body + size(); }
body_front()583 Stmt *body_front() { return !body_empty() ? Body[0] : nullptr; }
body_back()584 Stmt *body_back() { return !body_empty() ? Body[size()-1] : nullptr; }
585
setLastStmt(Stmt * S)586 void setLastStmt(Stmt *S) {
587 assert(!body_empty() && "setLastStmt");
588 Body[size()-1] = S;
589 }
590
591 typedef Stmt* const * const_body_iterator;
592 typedef llvm::iterator_range<const_body_iterator> body_const_range;
593
body()594 body_const_range body() const {
595 return body_const_range(body_begin(), body_end());
596 }
body_begin()597 const_body_iterator body_begin() const { return Body; }
body_end()598 const_body_iterator body_end() const { return Body + size(); }
body_front()599 const Stmt *body_front() const {
600 return !body_empty() ? Body[0] : nullptr;
601 }
body_back()602 const Stmt *body_back() const {
603 return !body_empty() ? Body[size() - 1] : nullptr;
604 }
605
606 typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
body_rbegin()607 reverse_body_iterator body_rbegin() {
608 return reverse_body_iterator(body_end());
609 }
body_rend()610 reverse_body_iterator body_rend() {
611 return reverse_body_iterator(body_begin());
612 }
613
614 typedef std::reverse_iterator<const_body_iterator>
615 const_reverse_body_iterator;
616
body_rbegin()617 const_reverse_body_iterator body_rbegin() const {
618 return const_reverse_body_iterator(body_end());
619 }
620
body_rend()621 const_reverse_body_iterator body_rend() const {
622 return const_reverse_body_iterator(body_begin());
623 }
624
getLocStart()625 SourceLocation getLocStart() const LLVM_READONLY { return LBraceLoc; }
getLocEnd()626 SourceLocation getLocEnd() const LLVM_READONLY { return RBraceLoc; }
627
getLBracLoc()628 SourceLocation getLBracLoc() const { return LBraceLoc; }
getRBracLoc()629 SourceLocation getRBracLoc() const { return RBraceLoc; }
630
classof(const Stmt * T)631 static bool classof(const Stmt *T) {
632 return T->getStmtClass() == CompoundStmtClass;
633 }
634
635 // Iterators
children()636 child_range children() {
637 return child_range(Body, Body + CompoundStmtBits.NumStmts);
638 }
639
children()640 const_child_range children() const {
641 return child_range(Body, Body + CompoundStmtBits.NumStmts);
642 }
643 };
644
645 // SwitchCase is the base class for CaseStmt and DefaultStmt,
646 class SwitchCase : public Stmt {
647 protected:
648 // A pointer to the following CaseStmt or DefaultStmt class,
649 // used by SwitchStmt.
650 SwitchCase *NextSwitchCase;
651 SourceLocation KeywordLoc;
652 SourceLocation ColonLoc;
653
SwitchCase(StmtClass SC,SourceLocation KWLoc,SourceLocation ColonLoc)654 SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
655 : Stmt(SC), NextSwitchCase(nullptr), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {
656 }
657
SwitchCase(StmtClass SC,EmptyShell)658 SwitchCase(StmtClass SC, EmptyShell)
659 : Stmt(SC), NextSwitchCase(nullptr) {}
660
661 public:
getNextSwitchCase()662 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
663
getNextSwitchCase()664 SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
665
setNextSwitchCase(SwitchCase * SC)666 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
667
getKeywordLoc()668 SourceLocation getKeywordLoc() const { return KeywordLoc; }
setKeywordLoc(SourceLocation L)669 void setKeywordLoc(SourceLocation L) { KeywordLoc = L; }
getColonLoc()670 SourceLocation getColonLoc() const { return ColonLoc; }
setColonLoc(SourceLocation L)671 void setColonLoc(SourceLocation L) { ColonLoc = L; }
672
673 Stmt *getSubStmt();
getSubStmt()674 const Stmt *getSubStmt() const {
675 return const_cast<SwitchCase*>(this)->getSubStmt();
676 }
677
getLocStart()678 SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
679 SourceLocation getLocEnd() const LLVM_READONLY;
680
classof(const Stmt * T)681 static bool classof(const Stmt *T) {
682 return T->getStmtClass() == CaseStmtClass ||
683 T->getStmtClass() == DefaultStmtClass;
684 }
685 };
686
687 class CaseStmt : public SwitchCase {
688 SourceLocation EllipsisLoc;
689 enum { LHS, RHS, SUBSTMT, END_EXPR };
690 Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for
691 // GNU "case 1 ... 4" extension
692 public:
CaseStmt(Expr * lhs,Expr * rhs,SourceLocation caseLoc,SourceLocation ellipsisLoc,SourceLocation colonLoc)693 CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
694 SourceLocation ellipsisLoc, SourceLocation colonLoc)
695 : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
696 SubExprs[SUBSTMT] = nullptr;
697 SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
698 SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
699 EllipsisLoc = ellipsisLoc;
700 }
701
702 /// \brief Build an empty switch case statement.
CaseStmt(EmptyShell Empty)703 explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) { }
704
getCaseLoc()705 SourceLocation getCaseLoc() const { return KeywordLoc; }
setCaseLoc(SourceLocation L)706 void setCaseLoc(SourceLocation L) { KeywordLoc = L; }
getEllipsisLoc()707 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
setEllipsisLoc(SourceLocation L)708 void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
getColonLoc()709 SourceLocation getColonLoc() const { return ColonLoc; }
setColonLoc(SourceLocation L)710 void setColonLoc(SourceLocation L) { ColonLoc = L; }
711
getLHS()712 Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
getRHS()713 Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
getSubStmt()714 Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
715
getLHS()716 const Expr *getLHS() const {
717 return reinterpret_cast<const Expr*>(SubExprs[LHS]);
718 }
getRHS()719 const Expr *getRHS() const {
720 return reinterpret_cast<const Expr*>(SubExprs[RHS]);
721 }
getSubStmt()722 const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
723
setSubStmt(Stmt * S)724 void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
setLHS(Expr * Val)725 void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
setRHS(Expr * Val)726 void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
727
getLocStart()728 SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
getLocEnd()729 SourceLocation getLocEnd() const LLVM_READONLY {
730 // Handle deeply nested case statements with iteration instead of recursion.
731 const CaseStmt *CS = this;
732 while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
733 CS = CS2;
734
735 return CS->getSubStmt()->getLocEnd();
736 }
737
classof(const Stmt * T)738 static bool classof(const Stmt *T) {
739 return T->getStmtClass() == CaseStmtClass;
740 }
741
742 // Iterators
children()743 child_range children() {
744 return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
745 }
746 };
747
748 class DefaultStmt : public SwitchCase {
749 Stmt* SubStmt;
750 public:
DefaultStmt(SourceLocation DL,SourceLocation CL,Stmt * substmt)751 DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
752 SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
753
754 /// \brief Build an empty default statement.
DefaultStmt(EmptyShell Empty)755 explicit DefaultStmt(EmptyShell Empty)
756 : SwitchCase(DefaultStmtClass, Empty) { }
757
getSubStmt()758 Stmt *getSubStmt() { return SubStmt; }
getSubStmt()759 const Stmt *getSubStmt() const { return SubStmt; }
setSubStmt(Stmt * S)760 void setSubStmt(Stmt *S) { SubStmt = S; }
761
getDefaultLoc()762 SourceLocation getDefaultLoc() const { return KeywordLoc; }
setDefaultLoc(SourceLocation L)763 void setDefaultLoc(SourceLocation L) { KeywordLoc = L; }
getColonLoc()764 SourceLocation getColonLoc() const { return ColonLoc; }
setColonLoc(SourceLocation L)765 void setColonLoc(SourceLocation L) { ColonLoc = L; }
766
getLocStart()767 SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
getLocEnd()768 SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
769
classof(const Stmt * T)770 static bool classof(const Stmt *T) {
771 return T->getStmtClass() == DefaultStmtClass;
772 }
773
774 // Iterators
children()775 child_range children() { return child_range(&SubStmt, &SubStmt+1); }
776 };
777
getLocEnd()778 inline SourceLocation SwitchCase::getLocEnd() const {
779 if (const CaseStmt *CS = dyn_cast<CaseStmt>(this))
780 return CS->getLocEnd();
781 return cast<DefaultStmt>(this)->getLocEnd();
782 }
783
784 /// LabelStmt - Represents a label, which has a substatement. For example:
785 /// foo: return;
786 ///
787 class LabelStmt : public Stmt {
788 SourceLocation IdentLoc;
789 LabelDecl *TheDecl;
790 Stmt *SubStmt;
791
792 public:
LabelStmt(SourceLocation IL,LabelDecl * D,Stmt * substmt)793 LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
794 : Stmt(LabelStmtClass), IdentLoc(IL), TheDecl(D), SubStmt(substmt) {
795 static_assert(sizeof(LabelStmt) ==
796 2 * sizeof(SourceLocation) + 2 * sizeof(void *),
797 "LabelStmt too big");
798 }
799
800 // \brief Build an empty label statement.
LabelStmt(EmptyShell Empty)801 explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
802
getIdentLoc()803 SourceLocation getIdentLoc() const { return IdentLoc; }
getDecl()804 LabelDecl *getDecl() const { return TheDecl; }
setDecl(LabelDecl * D)805 void setDecl(LabelDecl *D) { TheDecl = D; }
806 const char *getName() const;
getSubStmt()807 Stmt *getSubStmt() { return SubStmt; }
getSubStmt()808 const Stmt *getSubStmt() const { return SubStmt; }
setIdentLoc(SourceLocation L)809 void setIdentLoc(SourceLocation L) { IdentLoc = L; }
setSubStmt(Stmt * SS)810 void setSubStmt(Stmt *SS) { SubStmt = SS; }
811
getLocStart()812 SourceLocation getLocStart() const LLVM_READONLY { return IdentLoc; }
getLocEnd()813 SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
814
children()815 child_range children() { return child_range(&SubStmt, &SubStmt+1); }
816
classof(const Stmt * T)817 static bool classof(const Stmt *T) {
818 return T->getStmtClass() == LabelStmtClass;
819 }
820 };
821
822
823 /// \brief Represents an attribute applied to a statement.
824 ///
825 /// Represents an attribute applied to a statement. For example:
826 /// [[omp::for(...)]] for (...) { ... }
827 ///
828 class AttributedStmt : public Stmt {
829 Stmt *SubStmt;
830 SourceLocation AttrLoc;
831 unsigned NumAttrs;
832
833 friend class ASTStmtReader;
834
AttributedStmt(SourceLocation Loc,ArrayRef<const Attr * > Attrs,Stmt * SubStmt)835 AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt)
836 : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc),
837 NumAttrs(Attrs.size()) {
838 memcpy(getAttrArrayPtr(), Attrs.data(), Attrs.size() * sizeof(Attr *));
839 }
840
AttributedStmt(EmptyShell Empty,unsigned NumAttrs)841 explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
842 : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) {
843 memset(getAttrArrayPtr(), 0, NumAttrs * sizeof(Attr *));
844 }
845
getAttrArrayPtr()846 Attr *const *getAttrArrayPtr() const {
847 return reinterpret_cast<Attr *const *>(this + 1);
848 }
getAttrArrayPtr()849 Attr **getAttrArrayPtr() { return reinterpret_cast<Attr **>(this + 1); }
850
851 public:
852 static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
853 ArrayRef<const Attr*> Attrs, Stmt *SubStmt);
854 // \brief Build an empty attributed statement.
855 static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);
856
getAttrLoc()857 SourceLocation getAttrLoc() const { return AttrLoc; }
getAttrs()858 ArrayRef<const Attr*> getAttrs() const {
859 return llvm::makeArrayRef(getAttrArrayPtr(), NumAttrs);
860 }
getSubStmt()861 Stmt *getSubStmt() { return SubStmt; }
getSubStmt()862 const Stmt *getSubStmt() const { return SubStmt; }
863
getLocStart()864 SourceLocation getLocStart() const LLVM_READONLY { return AttrLoc; }
getLocEnd()865 SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
866
children()867 child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
868
classof(const Stmt * T)869 static bool classof(const Stmt *T) {
870 return T->getStmtClass() == AttributedStmtClass;
871 }
872 };
873
874
875 /// IfStmt - This represents an if/then/else.
876 ///
877 class IfStmt : public Stmt {
878 enum { VAR, COND, THEN, ELSE, END_EXPR };
879 Stmt* SubExprs[END_EXPR];
880
881 SourceLocation IfLoc;
882 SourceLocation ElseLoc;
883
884 public:
885 IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
886 Stmt *then, SourceLocation EL = SourceLocation(),
887 Stmt *elsev = nullptr);
888
889 /// \brief Build an empty if/then/else statement
IfStmt(EmptyShell Empty)890 explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
891
892 /// \brief Retrieve the variable declared in this "if" statement, if any.
893 ///
894 /// In the following example, "x" is the condition variable.
895 /// \code
896 /// if (int x = foo()) {
897 /// printf("x is %d", x);
898 /// }
899 /// \endcode
900 VarDecl *getConditionVariable() const;
901 void setConditionVariable(const ASTContext &C, VarDecl *V);
902
903 /// If this IfStmt has a condition variable, return the faux DeclStmt
904 /// associated with the creation of that condition variable.
getConditionVariableDeclStmt()905 const DeclStmt *getConditionVariableDeclStmt() const {
906 return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
907 }
908
getCond()909 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
setCond(Expr * E)910 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
getThen()911 const Stmt *getThen() const { return SubExprs[THEN]; }
setThen(Stmt * S)912 void setThen(Stmt *S) { SubExprs[THEN] = S; }
getElse()913 const Stmt *getElse() const { return SubExprs[ELSE]; }
setElse(Stmt * S)914 void setElse(Stmt *S) { SubExprs[ELSE] = S; }
915
getCond()916 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
getThen()917 Stmt *getThen() { return SubExprs[THEN]; }
getElse()918 Stmt *getElse() { return SubExprs[ELSE]; }
919
getIfLoc()920 SourceLocation getIfLoc() const { return IfLoc; }
setIfLoc(SourceLocation L)921 void setIfLoc(SourceLocation L) { IfLoc = L; }
getElseLoc()922 SourceLocation getElseLoc() const { return ElseLoc; }
setElseLoc(SourceLocation L)923 void setElseLoc(SourceLocation L) { ElseLoc = L; }
924
getLocStart()925 SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; }
getLocEnd()926 SourceLocation getLocEnd() const LLVM_READONLY {
927 if (SubExprs[ELSE])
928 return SubExprs[ELSE]->getLocEnd();
929 else
930 return SubExprs[THEN]->getLocEnd();
931 }
932
933 // Iterators over subexpressions. The iterators will include iterating
934 // over the initialization expression referenced by the condition variable.
children()935 child_range children() {
936 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
937 }
938
classof(const Stmt * T)939 static bool classof(const Stmt *T) {
940 return T->getStmtClass() == IfStmtClass;
941 }
942 };
943
944 /// SwitchStmt - This represents a 'switch' stmt.
945 ///
946 class SwitchStmt : public Stmt {
947 SourceLocation SwitchLoc;
948 enum { VAR, COND, BODY, END_EXPR };
949 Stmt* SubExprs[END_EXPR];
950 // This points to a linked list of case and default statements and, if the
951 // SwitchStmt is a switch on an enum value, records whether all the enum
952 // values were covered by CaseStmts. The coverage information value is meant
953 // to be a hint for possible clients.
954 llvm::PointerIntPair<SwitchCase *, 1, bool> FirstCase;
955
956 public:
957 SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond);
958
959 /// \brief Build a empty switch statement.
SwitchStmt(EmptyShell Empty)960 explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
961
962 /// \brief Retrieve the variable declared in this "switch" statement, if any.
963 ///
964 /// In the following example, "x" is the condition variable.
965 /// \code
966 /// switch (int x = foo()) {
967 /// case 0: break;
968 /// // ...
969 /// }
970 /// \endcode
971 VarDecl *getConditionVariable() const;
972 void setConditionVariable(const ASTContext &C, VarDecl *V);
973
974 /// If this SwitchStmt has a condition variable, return the faux DeclStmt
975 /// associated with the creation of that condition variable.
getConditionVariableDeclStmt()976 const DeclStmt *getConditionVariableDeclStmt() const {
977 return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
978 }
979
getCond()980 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
getBody()981 const Stmt *getBody() const { return SubExprs[BODY]; }
getSwitchCaseList()982 const SwitchCase *getSwitchCaseList() const { return FirstCase.getPointer(); }
983
getCond()984 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
setCond(Expr * E)985 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
getBody()986 Stmt *getBody() { return SubExprs[BODY]; }
setBody(Stmt * S)987 void setBody(Stmt *S) { SubExprs[BODY] = S; }
getSwitchCaseList()988 SwitchCase *getSwitchCaseList() { return FirstCase.getPointer(); }
989
990 /// \brief Set the case list for this switch statement.
setSwitchCaseList(SwitchCase * SC)991 void setSwitchCaseList(SwitchCase *SC) { FirstCase.setPointer(SC); }
992
getSwitchLoc()993 SourceLocation getSwitchLoc() const { return SwitchLoc; }
setSwitchLoc(SourceLocation L)994 void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
995
setBody(Stmt * S,SourceLocation SL)996 void setBody(Stmt *S, SourceLocation SL) {
997 SubExprs[BODY] = S;
998 SwitchLoc = SL;
999 }
addSwitchCase(SwitchCase * SC)1000 void addSwitchCase(SwitchCase *SC) {
1001 assert(!SC->getNextSwitchCase()
1002 && "case/default already added to a switch");
1003 SC->setNextSwitchCase(FirstCase.getPointer());
1004 FirstCase.setPointer(SC);
1005 }
1006
1007 /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
1008 /// switch over an enum value then all cases have been explicitly covered.
setAllEnumCasesCovered()1009 void setAllEnumCasesCovered() { FirstCase.setInt(true); }
1010
1011 /// Returns true if the SwitchStmt is a switch of an enum value and all cases
1012 /// have been explicitly covered.
isAllEnumCasesCovered()1013 bool isAllEnumCasesCovered() const { return FirstCase.getInt(); }
1014
getLocStart()1015 SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; }
getLocEnd()1016 SourceLocation getLocEnd() const LLVM_READONLY {
1017 return SubExprs[BODY] ? SubExprs[BODY]->getLocEnd() : SubExprs[COND]->getLocEnd();
1018 }
1019
1020 // Iterators
children()1021 child_range children() {
1022 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
1023 }
1024
classof(const Stmt * T)1025 static bool classof(const Stmt *T) {
1026 return T->getStmtClass() == SwitchStmtClass;
1027 }
1028 };
1029
1030
1031 /// WhileStmt - This represents a 'while' stmt.
1032 ///
1033 class WhileStmt : public Stmt {
1034 SourceLocation WhileLoc;
1035 enum { VAR, COND, BODY, END_EXPR };
1036 Stmt* SubExprs[END_EXPR];
1037 public:
1038 WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
1039 SourceLocation WL);
1040
1041 /// \brief Build an empty while statement.
WhileStmt(EmptyShell Empty)1042 explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
1043
1044 /// \brief Retrieve the variable declared in this "while" statement, if any.
1045 ///
1046 /// In the following example, "x" is the condition variable.
1047 /// \code
1048 /// while (int x = random()) {
1049 /// // ...
1050 /// }
1051 /// \endcode
1052 VarDecl *getConditionVariable() const;
1053 void setConditionVariable(const ASTContext &C, VarDecl *V);
1054
1055 /// If this WhileStmt has a condition variable, return the faux DeclStmt
1056 /// associated with the creation of that condition variable.
getConditionVariableDeclStmt()1057 const DeclStmt *getConditionVariableDeclStmt() const {
1058 return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
1059 }
1060
getCond()1061 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
getCond()1062 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
setCond(Expr * E)1063 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
getBody()1064 Stmt *getBody() { return SubExprs[BODY]; }
getBody()1065 const Stmt *getBody() const { return SubExprs[BODY]; }
setBody(Stmt * S)1066 void setBody(Stmt *S) { SubExprs[BODY] = S; }
1067
getWhileLoc()1068 SourceLocation getWhileLoc() const { return WhileLoc; }
setWhileLoc(SourceLocation L)1069 void setWhileLoc(SourceLocation L) { WhileLoc = L; }
1070
getLocStart()1071 SourceLocation getLocStart() const LLVM_READONLY { return WhileLoc; }
getLocEnd()1072 SourceLocation getLocEnd() const LLVM_READONLY {
1073 return SubExprs[BODY]->getLocEnd();
1074 }
1075
classof(const Stmt * T)1076 static bool classof(const Stmt *T) {
1077 return T->getStmtClass() == WhileStmtClass;
1078 }
1079
1080 // Iterators
children()1081 child_range children() {
1082 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
1083 }
1084 };
1085
1086 /// DoStmt - This represents a 'do/while' stmt.
1087 ///
1088 class DoStmt : public Stmt {
1089 SourceLocation DoLoc;
1090 enum { BODY, COND, END_EXPR };
1091 Stmt* SubExprs[END_EXPR];
1092 SourceLocation WhileLoc;
1093 SourceLocation RParenLoc; // Location of final ')' in do stmt condition.
1094
1095 public:
DoStmt(Stmt * body,Expr * cond,SourceLocation DL,SourceLocation WL,SourceLocation RP)1096 DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
1097 SourceLocation RP)
1098 : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
1099 SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
1100 SubExprs[BODY] = body;
1101 }
1102
1103 /// \brief Build an empty do-while statement.
DoStmt(EmptyShell Empty)1104 explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { }
1105
getCond()1106 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
getCond()1107 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
setCond(Expr * E)1108 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
getBody()1109 Stmt *getBody() { return SubExprs[BODY]; }
getBody()1110 const Stmt *getBody() const { return SubExprs[BODY]; }
setBody(Stmt * S)1111 void setBody(Stmt *S) { SubExprs[BODY] = S; }
1112
getDoLoc()1113 SourceLocation getDoLoc() const { return DoLoc; }
setDoLoc(SourceLocation L)1114 void setDoLoc(SourceLocation L) { DoLoc = L; }
getWhileLoc()1115 SourceLocation getWhileLoc() const { return WhileLoc; }
setWhileLoc(SourceLocation L)1116 void setWhileLoc(SourceLocation L) { WhileLoc = L; }
1117
getRParenLoc()1118 SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)1119 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
1120
getLocStart()1121 SourceLocation getLocStart() const LLVM_READONLY { return DoLoc; }
getLocEnd()1122 SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
1123
classof(const Stmt * T)1124 static bool classof(const Stmt *T) {
1125 return T->getStmtClass() == DoStmtClass;
1126 }
1127
1128 // Iterators
children()1129 child_range children() {
1130 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
1131 }
1132 };
1133
1134
1135 /// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of
1136 /// the init/cond/inc parts of the ForStmt will be null if they were not
1137 /// specified in the source.
1138 ///
1139 class ForStmt : public Stmt {
1140 SourceLocation ForLoc;
1141 enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
1142 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
1143 SourceLocation LParenLoc, RParenLoc;
1144
1145 public:
1146 ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
1147 Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
1148 SourceLocation RP);
1149
1150 /// \brief Build an empty for statement.
ForStmt(EmptyShell Empty)1151 explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
1152
getInit()1153 Stmt *getInit() { return SubExprs[INIT]; }
1154
1155 /// \brief Retrieve the variable declared in this "for" statement, if any.
1156 ///
1157 /// In the following example, "y" is the condition variable.
1158 /// \code
1159 /// for (int x = random(); int y = mangle(x); ++x) {
1160 /// // ...
1161 /// }
1162 /// \endcode
1163 VarDecl *getConditionVariable() const;
1164 void setConditionVariable(const ASTContext &C, VarDecl *V);
1165
1166 /// If this ForStmt has a condition variable, return the faux DeclStmt
1167 /// associated with the creation of that condition variable.
getConditionVariableDeclStmt()1168 const DeclStmt *getConditionVariableDeclStmt() const {
1169 return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
1170 }
1171
getCond()1172 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
getInc()1173 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
getBody()1174 Stmt *getBody() { return SubExprs[BODY]; }
1175
getInit()1176 const Stmt *getInit() const { return SubExprs[INIT]; }
getCond()1177 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
getInc()1178 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
getBody()1179 const Stmt *getBody() const { return SubExprs[BODY]; }
1180
setInit(Stmt * S)1181 void setInit(Stmt *S) { SubExprs[INIT] = S; }
setCond(Expr * E)1182 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
setInc(Expr * E)1183 void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
setBody(Stmt * S)1184 void setBody(Stmt *S) { SubExprs[BODY] = S; }
1185
getForLoc()1186 SourceLocation getForLoc() const { return ForLoc; }
setForLoc(SourceLocation L)1187 void setForLoc(SourceLocation L) { ForLoc = L; }
getLParenLoc()1188 SourceLocation getLParenLoc() const { return LParenLoc; }
setLParenLoc(SourceLocation L)1189 void setLParenLoc(SourceLocation L) { LParenLoc = L; }
getRParenLoc()1190 SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)1191 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
1192
getLocStart()1193 SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
getLocEnd()1194 SourceLocation getLocEnd() const LLVM_READONLY {
1195 return SubExprs[BODY]->getLocEnd();
1196 }
1197
classof(const Stmt * T)1198 static bool classof(const Stmt *T) {
1199 return T->getStmtClass() == ForStmtClass;
1200 }
1201
1202 // Iterators
children()1203 child_range children() {
1204 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
1205 }
1206 };
1207
1208 /// GotoStmt - This represents a direct goto.
1209 ///
1210 class GotoStmt : public Stmt {
1211 LabelDecl *Label;
1212 SourceLocation GotoLoc;
1213 SourceLocation LabelLoc;
1214 public:
GotoStmt(LabelDecl * label,SourceLocation GL,SourceLocation LL)1215 GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL)
1216 : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
1217
1218 /// \brief Build an empty goto statement.
GotoStmt(EmptyShell Empty)1219 explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
1220
getLabel()1221 LabelDecl *getLabel() const { return Label; }
setLabel(LabelDecl * D)1222 void setLabel(LabelDecl *D) { Label = D; }
1223
getGotoLoc()1224 SourceLocation getGotoLoc() const { return GotoLoc; }
setGotoLoc(SourceLocation L)1225 void setGotoLoc(SourceLocation L) { GotoLoc = L; }
getLabelLoc()1226 SourceLocation getLabelLoc() const { return LabelLoc; }
setLabelLoc(SourceLocation L)1227 void setLabelLoc(SourceLocation L) { LabelLoc = L; }
1228
getLocStart()1229 SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
getLocEnd()1230 SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
1231
classof(const Stmt * T)1232 static bool classof(const Stmt *T) {
1233 return T->getStmtClass() == GotoStmtClass;
1234 }
1235
1236 // Iterators
children()1237 child_range children() { return child_range(); }
1238 };
1239
1240 /// IndirectGotoStmt - This represents an indirect goto.
1241 ///
1242 class IndirectGotoStmt : public Stmt {
1243 SourceLocation GotoLoc;
1244 SourceLocation StarLoc;
1245 Stmt *Target;
1246 public:
IndirectGotoStmt(SourceLocation gotoLoc,SourceLocation starLoc,Expr * target)1247 IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
1248 Expr *target)
1249 : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
1250 Target((Stmt*)target) {}
1251
1252 /// \brief Build an empty indirect goto statement.
IndirectGotoStmt(EmptyShell Empty)1253 explicit IndirectGotoStmt(EmptyShell Empty)
1254 : Stmt(IndirectGotoStmtClass, Empty) { }
1255
setGotoLoc(SourceLocation L)1256 void setGotoLoc(SourceLocation L) { GotoLoc = L; }
getGotoLoc()1257 SourceLocation getGotoLoc() const { return GotoLoc; }
setStarLoc(SourceLocation L)1258 void setStarLoc(SourceLocation L) { StarLoc = L; }
getStarLoc()1259 SourceLocation getStarLoc() const { return StarLoc; }
1260
getTarget()1261 Expr *getTarget() { return reinterpret_cast<Expr*>(Target); }
getTarget()1262 const Expr *getTarget() const {return reinterpret_cast<const Expr*>(Target);}
setTarget(Expr * E)1263 void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
1264
1265 /// getConstantTarget - Returns the fixed target of this indirect
1266 /// goto, if one exists.
1267 LabelDecl *getConstantTarget();
getConstantTarget()1268 const LabelDecl *getConstantTarget() const {
1269 return const_cast<IndirectGotoStmt*>(this)->getConstantTarget();
1270 }
1271
getLocStart()1272 SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
getLocEnd()1273 SourceLocation getLocEnd() const LLVM_READONLY { return Target->getLocEnd(); }
1274
classof(const Stmt * T)1275 static bool classof(const Stmt *T) {
1276 return T->getStmtClass() == IndirectGotoStmtClass;
1277 }
1278
1279 // Iterators
children()1280 child_range children() { return child_range(&Target, &Target+1); }
1281 };
1282
1283
1284 /// ContinueStmt - This represents a continue.
1285 ///
1286 class ContinueStmt : public Stmt {
1287 SourceLocation ContinueLoc;
1288 public:
ContinueStmt(SourceLocation CL)1289 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
1290
1291 /// \brief Build an empty continue statement.
ContinueStmt(EmptyShell Empty)1292 explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { }
1293
getContinueLoc()1294 SourceLocation getContinueLoc() const { return ContinueLoc; }
setContinueLoc(SourceLocation L)1295 void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
1296
getLocStart()1297 SourceLocation getLocStart() const LLVM_READONLY { return ContinueLoc; }
getLocEnd()1298 SourceLocation getLocEnd() const LLVM_READONLY { return ContinueLoc; }
1299
classof(const Stmt * T)1300 static bool classof(const Stmt *T) {
1301 return T->getStmtClass() == ContinueStmtClass;
1302 }
1303
1304 // Iterators
children()1305 child_range children() { return child_range(); }
1306 };
1307
1308 /// BreakStmt - This represents a break.
1309 ///
1310 class BreakStmt : public Stmt {
1311 SourceLocation BreakLoc;
1312
1313 public:
BreakStmt(SourceLocation BL)1314 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {
1315 static_assert(sizeof(BreakStmt) == 2 * sizeof(SourceLocation),
1316 "BreakStmt too large");
1317 }
1318
1319 /// \brief Build an empty break statement.
BreakStmt(EmptyShell Empty)1320 explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
1321
getBreakLoc()1322 SourceLocation getBreakLoc() const { return BreakLoc; }
setBreakLoc(SourceLocation L)1323 void setBreakLoc(SourceLocation L) { BreakLoc = L; }
1324
getLocStart()1325 SourceLocation getLocStart() const LLVM_READONLY { return BreakLoc; }
getLocEnd()1326 SourceLocation getLocEnd() const LLVM_READONLY { return BreakLoc; }
1327
classof(const Stmt * T)1328 static bool classof(const Stmt *T) {
1329 return T->getStmtClass() == BreakStmtClass;
1330 }
1331
1332 // Iterators
children()1333 child_range children() { return child_range(); }
1334 };
1335
1336
1337 /// ReturnStmt - This represents a return, optionally of an expression:
1338 /// return;
1339 /// return 4;
1340 ///
1341 /// Note that GCC allows return with no argument in a function declared to
1342 /// return a value, and it allows returning a value in functions declared to
1343 /// return void. We explicitly model this in the AST, which means you can't
1344 /// depend on the return type of the function and the presence of an argument.
1345 ///
1346 class ReturnStmt : public Stmt {
1347 SourceLocation RetLoc;
1348 Stmt *RetExpr;
1349 const VarDecl *NRVOCandidate;
1350
1351 public:
ReturnStmt(SourceLocation RL)1352 explicit ReturnStmt(SourceLocation RL) : ReturnStmt(RL, nullptr, nullptr) {}
1353
ReturnStmt(SourceLocation RL,Expr * E,const VarDecl * NRVOCandidate)1354 ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
1355 : Stmt(ReturnStmtClass), RetLoc(RL), RetExpr((Stmt *)E),
1356 NRVOCandidate(NRVOCandidate) {}
1357
1358 /// \brief Build an empty return expression.
ReturnStmt(EmptyShell Empty)1359 explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
1360
1361 const Expr *getRetValue() const;
1362 Expr *getRetValue();
setRetValue(Expr * E)1363 void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); }
1364
getReturnLoc()1365 SourceLocation getReturnLoc() const { return RetLoc; }
setReturnLoc(SourceLocation L)1366 void setReturnLoc(SourceLocation L) { RetLoc = L; }
1367
1368 /// \brief Retrieve the variable that might be used for the named return
1369 /// value optimization.
1370 ///
1371 /// The optimization itself can only be performed if the variable is
1372 /// also marked as an NRVO object.
getNRVOCandidate()1373 const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
setNRVOCandidate(const VarDecl * Var)1374 void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
1375
getLocStart()1376 SourceLocation getLocStart() const LLVM_READONLY { return RetLoc; }
getLocEnd()1377 SourceLocation getLocEnd() const LLVM_READONLY {
1378 return RetExpr ? RetExpr->getLocEnd() : RetLoc;
1379 }
1380
classof(const Stmt * T)1381 static bool classof(const Stmt *T) {
1382 return T->getStmtClass() == ReturnStmtClass;
1383 }
1384
1385 // Iterators
children()1386 child_range children() {
1387 if (RetExpr) return child_range(&RetExpr, &RetExpr+1);
1388 return child_range();
1389 }
1390 };
1391
1392 /// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
1393 ///
1394 class AsmStmt : public Stmt {
1395 protected:
1396 SourceLocation AsmLoc;
1397 /// \brief True if the assembly statement does not have any input or output
1398 /// operands.
1399 bool IsSimple;
1400
1401 /// \brief If true, treat this inline assembly as having side effects.
1402 /// This assembly statement should not be optimized, deleted or moved.
1403 bool IsVolatile;
1404
1405 unsigned NumOutputs;
1406 unsigned NumInputs;
1407 unsigned NumClobbers;
1408
1409 Stmt **Exprs;
1410
AsmStmt(StmtClass SC,SourceLocation asmloc,bool issimple,bool isvolatile,unsigned numoutputs,unsigned numinputs,unsigned numclobbers)1411 AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile,
1412 unsigned numoutputs, unsigned numinputs, unsigned numclobbers) :
1413 Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
1414 NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { }
1415
1416 friend class ASTStmtReader;
1417
1418 public:
1419 /// \brief Build an empty inline-assembly statement.
AsmStmt(StmtClass SC,EmptyShell Empty)1420 explicit AsmStmt(StmtClass SC, EmptyShell Empty) :
1421 Stmt(SC, Empty), Exprs(nullptr) { }
1422
getAsmLoc()1423 SourceLocation getAsmLoc() const { return AsmLoc; }
setAsmLoc(SourceLocation L)1424 void setAsmLoc(SourceLocation L) { AsmLoc = L; }
1425
isSimple()1426 bool isSimple() const { return IsSimple; }
setSimple(bool V)1427 void setSimple(bool V) { IsSimple = V; }
1428
isVolatile()1429 bool isVolatile() const { return IsVolatile; }
setVolatile(bool V)1430 void setVolatile(bool V) { IsVolatile = V; }
1431
getLocStart()1432 SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
getLocEnd()1433 SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
1434
1435 //===--- Asm String Analysis ---===//
1436
1437 /// Assemble final IR asm string.
1438 std::string generateAsmString(const ASTContext &C) const;
1439
1440 //===--- Output operands ---===//
1441
getNumOutputs()1442 unsigned getNumOutputs() const { return NumOutputs; }
1443
1444 /// getOutputConstraint - Return the constraint string for the specified
1445 /// output operand. All output constraints are known to be non-empty (either
1446 /// '=' or '+').
1447 StringRef getOutputConstraint(unsigned i) const;
1448
1449 /// isOutputPlusConstraint - Return true if the specified output constraint
1450 /// is a "+" constraint (which is both an input and an output) or false if it
1451 /// is an "=" constraint (just an output).
isOutputPlusConstraint(unsigned i)1452 bool isOutputPlusConstraint(unsigned i) const {
1453 return getOutputConstraint(i)[0] == '+';
1454 }
1455
1456 const Expr *getOutputExpr(unsigned i) const;
1457
1458 /// getNumPlusOperands - Return the number of output operands that have a "+"
1459 /// constraint.
1460 unsigned getNumPlusOperands() const;
1461
1462 //===--- Input operands ---===//
1463
getNumInputs()1464 unsigned getNumInputs() const { return NumInputs; }
1465
1466 /// getInputConstraint - Return the specified input constraint. Unlike output
1467 /// constraints, these can be empty.
1468 StringRef getInputConstraint(unsigned i) const;
1469
1470 const Expr *getInputExpr(unsigned i) const;
1471
1472 //===--- Other ---===//
1473
getNumClobbers()1474 unsigned getNumClobbers() const { return NumClobbers; }
1475 StringRef getClobber(unsigned i) const;
1476
classof(const Stmt * T)1477 static bool classof(const Stmt *T) {
1478 return T->getStmtClass() == GCCAsmStmtClass ||
1479 T->getStmtClass() == MSAsmStmtClass;
1480 }
1481
1482 // Input expr iterators.
1483
1484 typedef ExprIterator inputs_iterator;
1485 typedef ConstExprIterator const_inputs_iterator;
1486 typedef llvm::iterator_range<inputs_iterator> inputs_range;
1487 typedef llvm::iterator_range<const_inputs_iterator> inputs_const_range;
1488
begin_inputs()1489 inputs_iterator begin_inputs() {
1490 return &Exprs[0] + NumOutputs;
1491 }
1492
end_inputs()1493 inputs_iterator end_inputs() {
1494 return &Exprs[0] + NumOutputs + NumInputs;
1495 }
1496
inputs()1497 inputs_range inputs() { return inputs_range(begin_inputs(), end_inputs()); }
1498
begin_inputs()1499 const_inputs_iterator begin_inputs() const {
1500 return &Exprs[0] + NumOutputs;
1501 }
1502
end_inputs()1503 const_inputs_iterator end_inputs() const {
1504 return &Exprs[0] + NumOutputs + NumInputs;
1505 }
1506
inputs()1507 inputs_const_range inputs() const {
1508 return inputs_const_range(begin_inputs(), end_inputs());
1509 }
1510
1511 // Output expr iterators.
1512
1513 typedef ExprIterator outputs_iterator;
1514 typedef ConstExprIterator const_outputs_iterator;
1515 typedef llvm::iterator_range<outputs_iterator> outputs_range;
1516 typedef llvm::iterator_range<const_outputs_iterator> outputs_const_range;
1517
begin_outputs()1518 outputs_iterator begin_outputs() {
1519 return &Exprs[0];
1520 }
end_outputs()1521 outputs_iterator end_outputs() {
1522 return &Exprs[0] + NumOutputs;
1523 }
outputs()1524 outputs_range outputs() {
1525 return outputs_range(begin_outputs(), end_outputs());
1526 }
1527
begin_outputs()1528 const_outputs_iterator begin_outputs() const {
1529 return &Exprs[0];
1530 }
end_outputs()1531 const_outputs_iterator end_outputs() const {
1532 return &Exprs[0] + NumOutputs;
1533 }
outputs()1534 outputs_const_range outputs() const {
1535 return outputs_const_range(begin_outputs(), end_outputs());
1536 }
1537
children()1538 child_range children() {
1539 return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
1540 }
1541 };
1542
1543 /// This represents a GCC inline-assembly statement extension.
1544 ///
1545 class GCCAsmStmt : public AsmStmt {
1546 SourceLocation RParenLoc;
1547 StringLiteral *AsmStr;
1548
1549 // FIXME: If we wanted to, we could allocate all of these in one big array.
1550 StringLiteral **Constraints;
1551 StringLiteral **Clobbers;
1552 IdentifierInfo **Names;
1553
1554 friend class ASTStmtReader;
1555
1556 public:
1557 GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
1558 bool isvolatile, unsigned numoutputs, unsigned numinputs,
1559 IdentifierInfo **names, StringLiteral **constraints, Expr **exprs,
1560 StringLiteral *asmstr, unsigned numclobbers,
1561 StringLiteral **clobbers, SourceLocation rparenloc);
1562
1563 /// \brief Build an empty inline-assembly statement.
GCCAsmStmt(EmptyShell Empty)1564 explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty),
1565 Constraints(nullptr), Clobbers(nullptr), Names(nullptr) { }
1566
getRParenLoc()1567 SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)1568 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
1569
1570 //===--- Asm String Analysis ---===//
1571
getAsmString()1572 const StringLiteral *getAsmString() const { return AsmStr; }
getAsmString()1573 StringLiteral *getAsmString() { return AsmStr; }
setAsmString(StringLiteral * E)1574 void setAsmString(StringLiteral *E) { AsmStr = E; }
1575
1576 /// AsmStringPiece - this is part of a decomposed asm string specification
1577 /// (for use with the AnalyzeAsmString function below). An asm string is
1578 /// considered to be a concatenation of these parts.
1579 class AsmStringPiece {
1580 public:
1581 enum Kind {
1582 String, // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
1583 Operand // Operand reference, with optional modifier %c4.
1584 };
1585 private:
1586 Kind MyKind;
1587 std::string Str;
1588 unsigned OperandNo;
1589
1590 // Source range for operand references.
1591 CharSourceRange Range;
1592 public:
AsmStringPiece(const std::string & S)1593 AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
AsmStringPiece(unsigned OpNo,const std::string & S,SourceLocation Begin,SourceLocation End)1594 AsmStringPiece(unsigned OpNo, const std::string &S, SourceLocation Begin,
1595 SourceLocation End)
1596 : MyKind(Operand), Str(S), OperandNo(OpNo),
1597 Range(CharSourceRange::getCharRange(Begin, End)) {
1598 }
1599
isString()1600 bool isString() const { return MyKind == String; }
isOperand()1601 bool isOperand() const { return MyKind == Operand; }
1602
getString()1603 const std::string &getString() const {
1604 return Str;
1605 }
1606
getOperandNo()1607 unsigned getOperandNo() const {
1608 assert(isOperand());
1609 return OperandNo;
1610 }
1611
getRange()1612 CharSourceRange getRange() const {
1613 assert(isOperand() && "Range is currently used only for Operands.");
1614 return Range;
1615 }
1616
1617 /// getModifier - Get the modifier for this operand, if present. This
1618 /// returns '\0' if there was no modifier.
1619 char getModifier() const;
1620 };
1621
1622 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
1623 /// it into pieces. If the asm string is erroneous, emit errors and return
1624 /// true, otherwise return false. This handles canonicalization and
1625 /// translation of strings from GCC syntax to LLVM IR syntax, and handles
1626 //// flattening of named references like %[foo] to Operand AsmStringPiece's.
1627 unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces,
1628 const ASTContext &C, unsigned &DiagOffs) const;
1629
1630 /// Assemble final IR asm string.
1631 std::string generateAsmString(const ASTContext &C) const;
1632
1633 //===--- Output operands ---===//
1634
getOutputIdentifier(unsigned i)1635 IdentifierInfo *getOutputIdentifier(unsigned i) const {
1636 return Names[i];
1637 }
1638
getOutputName(unsigned i)1639 StringRef getOutputName(unsigned i) const {
1640 if (IdentifierInfo *II = getOutputIdentifier(i))
1641 return II->getName();
1642
1643 return StringRef();
1644 }
1645
1646 StringRef getOutputConstraint(unsigned i) const;
1647
getOutputConstraintLiteral(unsigned i)1648 const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
1649 return Constraints[i];
1650 }
getOutputConstraintLiteral(unsigned i)1651 StringLiteral *getOutputConstraintLiteral(unsigned i) {
1652 return Constraints[i];
1653 }
1654
1655 Expr *getOutputExpr(unsigned i);
1656
getOutputExpr(unsigned i)1657 const Expr *getOutputExpr(unsigned i) const {
1658 return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i);
1659 }
1660
1661 //===--- Input operands ---===//
1662
getInputIdentifier(unsigned i)1663 IdentifierInfo *getInputIdentifier(unsigned i) const {
1664 return Names[i + NumOutputs];
1665 }
1666
getInputName(unsigned i)1667 StringRef getInputName(unsigned i) const {
1668 if (IdentifierInfo *II = getInputIdentifier(i))
1669 return II->getName();
1670
1671 return StringRef();
1672 }
1673
1674 StringRef getInputConstraint(unsigned i) const;
1675
getInputConstraintLiteral(unsigned i)1676 const StringLiteral *getInputConstraintLiteral(unsigned i) const {
1677 return Constraints[i + NumOutputs];
1678 }
getInputConstraintLiteral(unsigned i)1679 StringLiteral *getInputConstraintLiteral(unsigned i) {
1680 return Constraints[i + NumOutputs];
1681 }
1682
1683 Expr *getInputExpr(unsigned i);
1684 void setInputExpr(unsigned i, Expr *E);
1685
getInputExpr(unsigned i)1686 const Expr *getInputExpr(unsigned i) const {
1687 return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
1688 }
1689
1690 private:
1691 void setOutputsAndInputsAndClobbers(const ASTContext &C,
1692 IdentifierInfo **Names,
1693 StringLiteral **Constraints,
1694 Stmt **Exprs,
1695 unsigned NumOutputs,
1696 unsigned NumInputs,
1697 StringLiteral **Clobbers,
1698 unsigned NumClobbers);
1699 public:
1700
1701 //===--- Other ---===//
1702
1703 /// getNamedOperand - Given a symbolic operand reference like %[foo],
1704 /// translate this into a numeric value needed to reference the same operand.
1705 /// This returns -1 if the operand name is invalid.
1706 int getNamedOperand(StringRef SymbolicName) const;
1707
1708 StringRef getClobber(unsigned i) const;
getClobberStringLiteral(unsigned i)1709 StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; }
getClobberStringLiteral(unsigned i)1710 const StringLiteral *getClobberStringLiteral(unsigned i) const {
1711 return Clobbers[i];
1712 }
1713
getLocStart()1714 SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
getLocEnd()1715 SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
1716
classof(const Stmt * T)1717 static bool classof(const Stmt *T) {
1718 return T->getStmtClass() == GCCAsmStmtClass;
1719 }
1720 };
1721
1722 /// This represents a Microsoft inline-assembly statement extension.
1723 ///
1724 class MSAsmStmt : public AsmStmt {
1725 SourceLocation LBraceLoc, EndLoc;
1726 StringRef AsmStr;
1727
1728 unsigned NumAsmToks;
1729
1730 Token *AsmToks;
1731 StringRef *Constraints;
1732 StringRef *Clobbers;
1733
1734 friend class ASTStmtReader;
1735
1736 public:
1737 MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
1738 SourceLocation lbraceloc, bool issimple, bool isvolatile,
1739 ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs,
1740 ArrayRef<StringRef> constraints,
1741 ArrayRef<Expr*> exprs, StringRef asmstr,
1742 ArrayRef<StringRef> clobbers, SourceLocation endloc);
1743
1744 /// \brief Build an empty MS-style inline-assembly statement.
MSAsmStmt(EmptyShell Empty)1745 explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty),
1746 NumAsmToks(0), AsmToks(nullptr), Constraints(nullptr), Clobbers(nullptr) { }
1747
getLBraceLoc()1748 SourceLocation getLBraceLoc() const { return LBraceLoc; }
setLBraceLoc(SourceLocation L)1749 void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
getEndLoc()1750 SourceLocation getEndLoc() const { return EndLoc; }
setEndLoc(SourceLocation L)1751 void setEndLoc(SourceLocation L) { EndLoc = L; }
1752
hasBraces()1753 bool hasBraces() const { return LBraceLoc.isValid(); }
1754
getNumAsmToks()1755 unsigned getNumAsmToks() { return NumAsmToks; }
getAsmToks()1756 Token *getAsmToks() { return AsmToks; }
1757
1758 //===--- Asm String Analysis ---===//
getAsmString()1759 StringRef getAsmString() const { return AsmStr; }
1760
1761 /// Assemble final IR asm string.
1762 std::string generateAsmString(const ASTContext &C) const;
1763
1764 //===--- Output operands ---===//
1765
getOutputConstraint(unsigned i)1766 StringRef getOutputConstraint(unsigned i) const {
1767 assert(i < NumOutputs);
1768 return Constraints[i];
1769 }
1770
1771 Expr *getOutputExpr(unsigned i);
1772
getOutputExpr(unsigned i)1773 const Expr *getOutputExpr(unsigned i) const {
1774 return const_cast<MSAsmStmt*>(this)->getOutputExpr(i);
1775 }
1776
1777 //===--- Input operands ---===//
1778
getInputConstraint(unsigned i)1779 StringRef getInputConstraint(unsigned i) const {
1780 assert(i < NumInputs);
1781 return Constraints[i + NumOutputs];
1782 }
1783
1784 Expr *getInputExpr(unsigned i);
1785 void setInputExpr(unsigned i, Expr *E);
1786
getInputExpr(unsigned i)1787 const Expr *getInputExpr(unsigned i) const {
1788 return const_cast<MSAsmStmt*>(this)->getInputExpr(i);
1789 }
1790
1791 //===--- Other ---===//
1792
getAllConstraints()1793 ArrayRef<StringRef> getAllConstraints() const {
1794 return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs);
1795 }
getClobbers()1796 ArrayRef<StringRef> getClobbers() const {
1797 return llvm::makeArrayRef(Clobbers, NumClobbers);
1798 }
getAllExprs()1799 ArrayRef<Expr*> getAllExprs() const {
1800 return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs),
1801 NumInputs + NumOutputs);
1802 }
1803
getClobber(unsigned i)1804 StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
1805
1806 private:
1807 void initialize(const ASTContext &C, StringRef AsmString,
1808 ArrayRef<Token> AsmToks, ArrayRef<StringRef> Constraints,
1809 ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers);
1810 public:
1811
getLocStart()1812 SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
getLocEnd()1813 SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
1814
classof(const Stmt * T)1815 static bool classof(const Stmt *T) {
1816 return T->getStmtClass() == MSAsmStmtClass;
1817 }
1818
children()1819 child_range children() {
1820 return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
1821 }
1822 };
1823
1824 class SEHExceptStmt : public Stmt {
1825 SourceLocation Loc;
1826 Stmt *Children[2];
1827
1828 enum { FILTER_EXPR, BLOCK };
1829
1830 SEHExceptStmt(SourceLocation Loc,
1831 Expr *FilterExpr,
1832 Stmt *Block);
1833
1834 friend class ASTReader;
1835 friend class ASTStmtReader;
SEHExceptStmt(EmptyShell E)1836 explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { }
1837
1838 public:
1839 static SEHExceptStmt* Create(const ASTContext &C,
1840 SourceLocation ExceptLoc,
1841 Expr *FilterExpr,
1842 Stmt *Block);
1843
getLocStart()1844 SourceLocation getLocStart() const LLVM_READONLY { return getExceptLoc(); }
getLocEnd()1845 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
1846
getExceptLoc()1847 SourceLocation getExceptLoc() const { return Loc; }
getEndLoc()1848 SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); }
1849
getFilterExpr()1850 Expr *getFilterExpr() const {
1851 return reinterpret_cast<Expr*>(Children[FILTER_EXPR]);
1852 }
1853
getBlock()1854 CompoundStmt *getBlock() const {
1855 return cast<CompoundStmt>(Children[BLOCK]);
1856 }
1857
children()1858 child_range children() {
1859 return child_range(Children,Children+2);
1860 }
1861
classof(const Stmt * T)1862 static bool classof(const Stmt *T) {
1863 return T->getStmtClass() == SEHExceptStmtClass;
1864 }
1865
1866 };
1867
1868 class SEHFinallyStmt : public Stmt {
1869 SourceLocation Loc;
1870 Stmt *Block;
1871
1872 SEHFinallyStmt(SourceLocation Loc,
1873 Stmt *Block);
1874
1875 friend class ASTReader;
1876 friend class ASTStmtReader;
SEHFinallyStmt(EmptyShell E)1877 explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { }
1878
1879 public:
1880 static SEHFinallyStmt* Create(const ASTContext &C,
1881 SourceLocation FinallyLoc,
1882 Stmt *Block);
1883
getLocStart()1884 SourceLocation getLocStart() const LLVM_READONLY { return getFinallyLoc(); }
getLocEnd()1885 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
1886
getFinallyLoc()1887 SourceLocation getFinallyLoc() const { return Loc; }
getEndLoc()1888 SourceLocation getEndLoc() const { return Block->getLocEnd(); }
1889
getBlock()1890 CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); }
1891
children()1892 child_range children() {
1893 return child_range(&Block,&Block+1);
1894 }
1895
classof(const Stmt * T)1896 static bool classof(const Stmt *T) {
1897 return T->getStmtClass() == SEHFinallyStmtClass;
1898 }
1899
1900 };
1901
1902 class SEHTryStmt : public Stmt {
1903 bool IsCXXTry;
1904 SourceLocation TryLoc;
1905 Stmt *Children[2];
1906
1907 enum { TRY = 0, HANDLER = 1 };
1908
1909 SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try'
1910 SourceLocation TryLoc,
1911 Stmt *TryBlock,
1912 Stmt *Handler);
1913
1914 friend class ASTReader;
1915 friend class ASTStmtReader;
SEHTryStmt(EmptyShell E)1916 explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { }
1917
1918 public:
1919 static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry,
1920 SourceLocation TryLoc, Stmt *TryBlock,
1921 Stmt *Handler);
1922
getLocStart()1923 SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
getLocEnd()1924 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
1925
getTryLoc()1926 SourceLocation getTryLoc() const { return TryLoc; }
getEndLoc()1927 SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); }
1928
getIsCXXTry()1929 bool getIsCXXTry() const { return IsCXXTry; }
1930
getTryBlock()1931 CompoundStmt* getTryBlock() const {
1932 return cast<CompoundStmt>(Children[TRY]);
1933 }
1934
getHandler()1935 Stmt *getHandler() const { return Children[HANDLER]; }
1936
1937 /// Returns 0 if not defined
1938 SEHExceptStmt *getExceptHandler() const;
1939 SEHFinallyStmt *getFinallyHandler() const;
1940
children()1941 child_range children() {
1942 return child_range(Children,Children+2);
1943 }
1944
classof(const Stmt * T)1945 static bool classof(const Stmt *T) {
1946 return T->getStmtClass() == SEHTryStmtClass;
1947 }
1948 };
1949
1950 /// Represents a __leave statement.
1951 ///
1952 class SEHLeaveStmt : public Stmt {
1953 SourceLocation LeaveLoc;
1954 public:
SEHLeaveStmt(SourceLocation LL)1955 explicit SEHLeaveStmt(SourceLocation LL)
1956 : Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {}
1957
1958 /// \brief Build an empty __leave statement.
SEHLeaveStmt(EmptyShell Empty)1959 explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) { }
1960
getLeaveLoc()1961 SourceLocation getLeaveLoc() const { return LeaveLoc; }
setLeaveLoc(SourceLocation L)1962 void setLeaveLoc(SourceLocation L) { LeaveLoc = L; }
1963
getLocStart()1964 SourceLocation getLocStart() const LLVM_READONLY { return LeaveLoc; }
getLocEnd()1965 SourceLocation getLocEnd() const LLVM_READONLY { return LeaveLoc; }
1966
classof(const Stmt * T)1967 static bool classof(const Stmt *T) {
1968 return T->getStmtClass() == SEHLeaveStmtClass;
1969 }
1970
1971 // Iterators
children()1972 child_range children() { return child_range(); }
1973 };
1974
1975 /// \brief This captures a statement into a function. For example, the following
1976 /// pragma annotated compound statement can be represented as a CapturedStmt,
1977 /// and this compound statement is the body of an anonymous outlined function.
1978 /// @code
1979 /// #pragma omp parallel
1980 /// {
1981 /// compute();
1982 /// }
1983 /// @endcode
1984 class CapturedStmt : public Stmt {
1985 public:
1986 /// \brief The different capture forms: by 'this', by reference, capture for
1987 /// variable-length array type etc.
1988 enum VariableCaptureKind {
1989 VCK_This,
1990 VCK_ByRef,
1991 VCK_VLAType,
1992 };
1993
1994 /// \brief Describes the capture of either a variable, or 'this', or
1995 /// variable-length array type.
1996 class Capture {
1997 llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind;
1998 SourceLocation Loc;
1999
2000 public:
2001 /// \brief Create a new capture.
2002 ///
2003 /// \param Loc The source location associated with this capture.
2004 ///
2005 /// \param Kind The kind of capture (this, ByRef, ...).
2006 ///
2007 /// \param Var The variable being captured, or null if capturing this.
2008 ///
2009 Capture(SourceLocation Loc, VariableCaptureKind Kind,
2010 VarDecl *Var = nullptr)
VarAndKind(Var,Kind)2011 : VarAndKind(Var, Kind), Loc(Loc) {
2012 switch (Kind) {
2013 case VCK_This:
2014 assert(!Var && "'this' capture cannot have a variable!");
2015 break;
2016 case VCK_ByRef:
2017 assert(Var && "capturing by reference must have a variable!");
2018 break;
2019 case VCK_VLAType:
2020 assert(!Var &&
2021 "Variable-length array type capture cannot have a variable!");
2022 break;
2023 }
2024 }
2025
2026 /// \brief Determine the kind of capture.
getCaptureKind()2027 VariableCaptureKind getCaptureKind() const { return VarAndKind.getInt(); }
2028
2029 /// \brief Retrieve the source location at which the variable or 'this' was
2030 /// first used.
getLocation()2031 SourceLocation getLocation() const { return Loc; }
2032
2033 /// \brief Determine whether this capture handles the C++ 'this' pointer.
capturesThis()2034 bool capturesThis() const { return getCaptureKind() == VCK_This; }
2035
2036 /// \brief Determine whether this capture handles a variable.
capturesVariable()2037 bool capturesVariable() const { return getCaptureKind() == VCK_ByRef; }
2038
2039 /// \brief Determine whether this capture handles a variable-length array
2040 /// type.
capturesVariableArrayType()2041 bool capturesVariableArrayType() const {
2042 return getCaptureKind() == VCK_VLAType;
2043 }
2044
2045 /// \brief Retrieve the declaration of the variable being captured.
2046 ///
2047 /// This operation is only valid if this capture captures a variable.
getCapturedVar()2048 VarDecl *getCapturedVar() const {
2049 assert(capturesVariable() &&
2050 "No variable available for 'this' or VAT capture");
2051 return VarAndKind.getPointer();
2052 }
2053 friend class ASTStmtReader;
2054 };
2055
2056 private:
2057 /// \brief The number of variable captured, including 'this'.
2058 unsigned NumCaptures;
2059
2060 /// \brief The pointer part is the implicit the outlined function and the
2061 /// int part is the captured region kind, 'CR_Default' etc.
2062 llvm::PointerIntPair<CapturedDecl *, 1, CapturedRegionKind> CapDeclAndKind;
2063
2064 /// \brief The record for captured variables, a RecordDecl or CXXRecordDecl.
2065 RecordDecl *TheRecordDecl;
2066
2067 /// \brief Construct a captured statement.
2068 CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures,
2069 ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD);
2070
2071 /// \brief Construct an empty captured statement.
2072 CapturedStmt(EmptyShell Empty, unsigned NumCaptures);
2073
getStoredStmts()2074 Stmt **getStoredStmts() const {
2075 return reinterpret_cast<Stmt **>(const_cast<CapturedStmt *>(this) + 1);
2076 }
2077
2078 Capture *getStoredCaptures() const;
2079
setCapturedStmt(Stmt * S)2080 void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; }
2081
2082 public:
2083 static CapturedStmt *Create(const ASTContext &Context, Stmt *S,
2084 CapturedRegionKind Kind,
2085 ArrayRef<Capture> Captures,
2086 ArrayRef<Expr *> CaptureInits,
2087 CapturedDecl *CD, RecordDecl *RD);
2088
2089 static CapturedStmt *CreateDeserialized(const ASTContext &Context,
2090 unsigned NumCaptures);
2091
2092 /// \brief Retrieve the statement being captured.
getCapturedStmt()2093 Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; }
getCapturedStmt()2094 const Stmt *getCapturedStmt() const {
2095 return const_cast<CapturedStmt *>(this)->getCapturedStmt();
2096 }
2097
2098 /// \brief Retrieve the outlined function declaration.
getCapturedDecl()2099 CapturedDecl *getCapturedDecl() { return CapDeclAndKind.getPointer(); }
getCapturedDecl()2100 const CapturedDecl *getCapturedDecl() const {
2101 return const_cast<CapturedStmt *>(this)->getCapturedDecl();
2102 }
2103
2104 /// \brief Set the outlined function declaration.
setCapturedDecl(CapturedDecl * D)2105 void setCapturedDecl(CapturedDecl *D) {
2106 assert(D && "null CapturedDecl");
2107 CapDeclAndKind.setPointer(D);
2108 }
2109
2110 /// \brief Retrieve the captured region kind.
getCapturedRegionKind()2111 CapturedRegionKind getCapturedRegionKind() const {
2112 return CapDeclAndKind.getInt();
2113 }
2114
2115 /// \brief Set the captured region kind.
setCapturedRegionKind(CapturedRegionKind Kind)2116 void setCapturedRegionKind(CapturedRegionKind Kind) {
2117 CapDeclAndKind.setInt(Kind);
2118 }
2119
2120 /// \brief Retrieve the record declaration for captured variables.
getCapturedRecordDecl()2121 const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; }
2122
2123 /// \brief Set the record declaration for captured variables.
setCapturedRecordDecl(RecordDecl * D)2124 void setCapturedRecordDecl(RecordDecl *D) {
2125 assert(D && "null RecordDecl");
2126 TheRecordDecl = D;
2127 }
2128
2129 /// \brief True if this variable has been captured.
2130 bool capturesVariable(const VarDecl *Var) const;
2131
2132 /// \brief An iterator that walks over the captures.
2133 typedef Capture *capture_iterator;
2134 typedef const Capture *const_capture_iterator;
2135 typedef llvm::iterator_range<capture_iterator> capture_range;
2136 typedef llvm::iterator_range<const_capture_iterator> capture_const_range;
2137
captures()2138 capture_range captures() {
2139 return capture_range(capture_begin(), capture_end());
2140 }
captures()2141 capture_const_range captures() const {
2142 return capture_const_range(capture_begin(), capture_end());
2143 }
2144
2145 /// \brief Retrieve an iterator pointing to the first capture.
capture_begin()2146 capture_iterator capture_begin() { return getStoredCaptures(); }
capture_begin()2147 const_capture_iterator capture_begin() const { return getStoredCaptures(); }
2148
2149 /// \brief Retrieve an iterator pointing past the end of the sequence of
2150 /// captures.
capture_end()2151 capture_iterator capture_end() const {
2152 return getStoredCaptures() + NumCaptures;
2153 }
2154
2155 /// \brief Retrieve the number of captures, including 'this'.
capture_size()2156 unsigned capture_size() const { return NumCaptures; }
2157
2158 /// \brief Iterator that walks over the capture initialization arguments.
2159 typedef Expr **capture_init_iterator;
2160 typedef llvm::iterator_range<capture_init_iterator> capture_init_range;
2161
capture_inits()2162 capture_init_range capture_inits() const {
2163 return capture_init_range(capture_init_begin(), capture_init_end());
2164 }
2165
2166 /// \brief Retrieve the first initialization argument.
capture_init_begin()2167 capture_init_iterator capture_init_begin() const {
2168 return reinterpret_cast<Expr **>(getStoredStmts());
2169 }
2170
2171 /// \brief Retrieve the iterator pointing one past the last initialization
2172 /// argument.
capture_init_end()2173 capture_init_iterator capture_init_end() const {
2174 return capture_init_begin() + NumCaptures;
2175 }
2176
getLocStart()2177 SourceLocation getLocStart() const LLVM_READONLY {
2178 return getCapturedStmt()->getLocStart();
2179 }
getLocEnd()2180 SourceLocation getLocEnd() const LLVM_READONLY {
2181 return getCapturedStmt()->getLocEnd();
2182 }
getSourceRange()2183 SourceRange getSourceRange() const LLVM_READONLY {
2184 return getCapturedStmt()->getSourceRange();
2185 }
2186
classof(const Stmt * T)2187 static bool classof(const Stmt *T) {
2188 return T->getStmtClass() == CapturedStmtClass;
2189 }
2190
2191 child_range children();
2192
2193 friend class ASTStmtReader;
2194 };
2195
2196 } // end namespace clang
2197
2198 #endif
2199