1 //===- Stmt.h - Classes for representing statements -------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the Stmt interface and subclasses.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_CLANG_AST_STMT_H
14 #define LLVM_CLANG_AST_STMT_H
15
16 #include "clang/AST/DeclGroup.h"
17 #include "clang/AST/DependenceFlags.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/BitmaskEnum.h"
25 #include "llvm/ADT/PointerIntPair.h"
26 #include "llvm/ADT/StringRef.h"
27 #include "llvm/ADT/iterator.h"
28 #include "llvm/ADT/iterator_range.h"
29 #include "llvm/Support/Casting.h"
30 #include "llvm/Support/Compiler.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include <algorithm>
33 #include <cassert>
34 #include <cstddef>
35 #include <iterator>
36 #include <string>
37
38 namespace llvm {
39
40 class FoldingSetNodeID;
41
42 } // namespace llvm
43
44 namespace clang {
45
46 class ASTContext;
47 class Attr;
48 class CapturedDecl;
49 class Decl;
50 class Expr;
51 class AddrLabelExpr;
52 class LabelDecl;
53 class ODRHash;
54 class PrinterHelper;
55 struct PrintingPolicy;
56 class RecordDecl;
57 class SourceManager;
58 class StringLiteral;
59 class Token;
60 class VarDecl;
61
62 //===----------------------------------------------------------------------===//
63 // AST classes for statements.
64 //===----------------------------------------------------------------------===//
65
66 /// Stmt - This represents one statement.
67 ///
alignas(void *)68 class alignas(void *) Stmt {
69 public:
70 enum StmtClass {
71 NoStmtClass = 0,
72 #define STMT(CLASS, PARENT) CLASS##Class,
73 #define STMT_RANGE(BASE, FIRST, LAST) \
74 first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class,
75 #define LAST_STMT_RANGE(BASE, FIRST, LAST) \
76 first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
77 #define ABSTRACT_STMT(STMT)
78 #include "clang/AST/StmtNodes.inc"
79 };
80
81 // Make vanilla 'new' and 'delete' illegal for Stmts.
82 protected:
83 friend class ASTStmtReader;
84 friend class ASTStmtWriter;
85
86 void *operator new(size_t bytes) noexcept {
87 llvm_unreachable("Stmts cannot be allocated with regular 'new'.");
88 }
89
90 void operator delete(void *data) noexcept {
91 llvm_unreachable("Stmts cannot be released with regular 'delete'.");
92 }
93
94 //===--- Statement bitfields classes ---===//
95
96 class StmtBitfields {
97 friend class ASTStmtReader;
98 friend class ASTStmtWriter;
99 friend class Stmt;
100
101 /// The statement class.
102 unsigned sClass : 8;
103 };
104 enum { NumStmtBits = 8 };
105
106 class NullStmtBitfields {
107 friend class ASTStmtReader;
108 friend class ASTStmtWriter;
109 friend class NullStmt;
110
111 unsigned : NumStmtBits;
112
113 /// True if the null statement was preceded by an empty macro, e.g:
114 /// @code
115 /// #define CALL(x)
116 /// CALL(0);
117 /// @endcode
118 unsigned HasLeadingEmptyMacro : 1;
119
120 /// The location of the semi-colon.
121 SourceLocation SemiLoc;
122 };
123
124 class CompoundStmtBitfields {
125 friend class ASTStmtReader;
126 friend class CompoundStmt;
127
128 unsigned : NumStmtBits;
129
130 unsigned NumStmts : 32 - NumStmtBits;
131
132 /// The location of the opening "{".
133 SourceLocation LBraceLoc;
134 };
135
136 class LabelStmtBitfields {
137 friend class LabelStmt;
138
139 unsigned : NumStmtBits;
140
141 SourceLocation IdentLoc;
142 };
143
144 class AttributedStmtBitfields {
145 friend class ASTStmtReader;
146 friend class AttributedStmt;
147
148 unsigned : NumStmtBits;
149
150 /// Number of attributes.
151 unsigned NumAttrs : 32 - NumStmtBits;
152
153 /// The location of the attribute.
154 SourceLocation AttrLoc;
155 };
156
157 class IfStmtBitfields {
158 friend class ASTStmtReader;
159 friend class IfStmt;
160
161 unsigned : NumStmtBits;
162
163 /// True if this if statement is a constexpr if.
164 unsigned IsConstexpr : 1;
165
166 /// True if this if statement has storage for an else statement.
167 unsigned HasElse : 1;
168
169 /// True if this if statement has storage for a variable declaration.
170 unsigned HasVar : 1;
171
172 /// True if this if statement has storage for an init statement.
173 unsigned HasInit : 1;
174
175 /// The location of the "if".
176 SourceLocation IfLoc;
177 };
178
179 class SwitchStmtBitfields {
180 friend class SwitchStmt;
181
182 unsigned : NumStmtBits;
183
184 /// True if the SwitchStmt has storage for an init statement.
185 unsigned HasInit : 1;
186
187 /// True if the SwitchStmt has storage for a condition variable.
188 unsigned HasVar : 1;
189
190 /// If the SwitchStmt is a switch on an enum value, records whether all
191 /// the enum values were covered by CaseStmts. The coverage information
192 /// value is meant to be a hint for possible clients.
193 unsigned AllEnumCasesCovered : 1;
194
195 /// The location of the "switch".
196 SourceLocation SwitchLoc;
197 };
198
199 class WhileStmtBitfields {
200 friend class ASTStmtReader;
201 friend class WhileStmt;
202
203 unsigned : NumStmtBits;
204
205 /// True if the WhileStmt has storage for a condition variable.
206 unsigned HasVar : 1;
207
208 /// The location of the "while".
209 SourceLocation WhileLoc;
210 };
211
212 class DoStmtBitfields {
213 friend class DoStmt;
214
215 unsigned : NumStmtBits;
216
217 /// The location of the "do".
218 SourceLocation DoLoc;
219 };
220
221 class ForStmtBitfields {
222 friend class ForStmt;
223
224 unsigned : NumStmtBits;
225
226 /// The location of the "for".
227 SourceLocation ForLoc;
228 };
229
230 class GotoStmtBitfields {
231 friend class GotoStmt;
232 friend class IndirectGotoStmt;
233
234 unsigned : NumStmtBits;
235
236 /// The location of the "goto".
237 SourceLocation GotoLoc;
238 };
239
240 class ContinueStmtBitfields {
241 friend class ContinueStmt;
242
243 unsigned : NumStmtBits;
244
245 /// The location of the "continue".
246 SourceLocation ContinueLoc;
247 };
248
249 class BreakStmtBitfields {
250 friend class BreakStmt;
251
252 unsigned : NumStmtBits;
253
254 /// The location of the "break".
255 SourceLocation BreakLoc;
256 };
257
258 class ReturnStmtBitfields {
259 friend class ReturnStmt;
260
261 unsigned : NumStmtBits;
262
263 /// True if this ReturnStmt has storage for an NRVO candidate.
264 unsigned HasNRVOCandidate : 1;
265
266 /// The location of the "return".
267 SourceLocation RetLoc;
268 };
269
270 class SwitchCaseBitfields {
271 friend class SwitchCase;
272 friend class CaseStmt;
273
274 unsigned : NumStmtBits;
275
276 /// Used by CaseStmt to store whether it is a case statement
277 /// of the form case LHS ... RHS (a GNU extension).
278 unsigned CaseStmtIsGNURange : 1;
279
280 /// The location of the "case" or "default" keyword.
281 SourceLocation KeywordLoc;
282 };
283
284 //===--- Expression bitfields classes ---===//
285
286 class ExprBitfields {
287 friend class ASTStmtReader; // deserialization
288 friend class AtomicExpr; // ctor
289 friend class BlockDeclRefExpr; // ctor
290 friend class CallExpr; // ctor
291 friend class CXXConstructExpr; // ctor
292 friend class CXXDependentScopeMemberExpr; // ctor
293 friend class CXXNewExpr; // ctor
294 friend class CXXUnresolvedConstructExpr; // ctor
295 friend class DeclRefExpr; // computeDependence
296 friend class DependentScopeDeclRefExpr; // ctor
297 friend class DesignatedInitExpr; // ctor
298 friend class Expr;
299 friend class InitListExpr; // ctor
300 friend class ObjCArrayLiteral; // ctor
301 friend class ObjCDictionaryLiteral; // ctor
302 friend class ObjCMessageExpr; // ctor
303 friend class OffsetOfExpr; // ctor
304 friend class OpaqueValueExpr; // ctor
305 friend class OverloadExpr; // ctor
306 friend class ParenListExpr; // ctor
307 friend class PseudoObjectExpr; // ctor
308 friend class ShuffleVectorExpr; // ctor
309
310 unsigned : NumStmtBits;
311
312 unsigned ValueKind : 2;
313 unsigned ObjectKind : 3;
314 unsigned /*ExprDependence*/ Dependent : llvm::BitWidth<ExprDependence>;
315 };
316 enum { NumExprBits = NumStmtBits + 5 + llvm::BitWidth<ExprDependence> };
317
318 class ConstantExprBitfields {
319 friend class ASTStmtReader;
320 friend class ASTStmtWriter;
321 friend class ConstantExpr;
322
323 unsigned : NumExprBits;
324
325 /// The kind of result that is tail-allocated.
326 unsigned ResultKind : 2;
327
328 /// The kind of Result as defined by APValue::Kind.
329 unsigned APValueKind : 4;
330
331 /// When ResultKind == RSK_Int64, true if the tail-allocated integer is
332 /// unsigned.
333 unsigned IsUnsigned : 1;
334
335 /// When ResultKind == RSK_Int64. the BitWidth of the tail-allocated
336 /// integer. 7 bits because it is the minimal number of bits to represent a
337 /// value from 0 to 64 (the size of the tail-allocated integer).
338 unsigned BitWidth : 7;
339
340 /// When ResultKind == RSK_APValue, true if the ASTContext will cleanup the
341 /// tail-allocated APValue.
342 unsigned HasCleanup : 1;
343
344 /// True if this ConstantExpr was created for immediate invocation.
345 unsigned IsImmediateInvocation : 1;
346 };
347
348 class PredefinedExprBitfields {
349 friend class ASTStmtReader;
350 friend class PredefinedExpr;
351
352 unsigned : NumExprBits;
353
354 /// The kind of this PredefinedExpr. One of the enumeration values
355 /// in PredefinedExpr::IdentKind.
356 unsigned Kind : 4;
357
358 /// True if this PredefinedExpr has a trailing "StringLiteral *"
359 /// for the predefined identifier.
360 unsigned HasFunctionName : 1;
361
362 /// The location of this PredefinedExpr.
363 SourceLocation Loc;
364 };
365
366 class DeclRefExprBitfields {
367 friend class ASTStmtReader; // deserialization
368 friend class DeclRefExpr;
369
370 unsigned : NumExprBits;
371
372 unsigned HasQualifier : 1;
373 unsigned HasTemplateKWAndArgsInfo : 1;
374 unsigned HasFoundDecl : 1;
375 unsigned HadMultipleCandidates : 1;
376 unsigned RefersToEnclosingVariableOrCapture : 1;
377 unsigned NonOdrUseReason : 2;
378
379 /// The location of the declaration name itself.
380 SourceLocation Loc;
381 };
382
383
384 class FloatingLiteralBitfields {
385 friend class FloatingLiteral;
386
387 unsigned : NumExprBits;
388
389 unsigned Semantics : 3; // Provides semantics for APFloat construction
390 unsigned IsExact : 1;
391 };
392
393 class StringLiteralBitfields {
394 friend class ASTStmtReader;
395 friend class StringLiteral;
396
397 unsigned : NumExprBits;
398
399 /// The kind of this string literal.
400 /// One of the enumeration values of StringLiteral::StringKind.
401 unsigned Kind : 3;
402
403 /// The width of a single character in bytes. Only values of 1, 2,
404 /// and 4 bytes are supported. StringLiteral::mapCharByteWidth maps
405 /// the target + string kind to the appropriate CharByteWidth.
406 unsigned CharByteWidth : 3;
407
408 unsigned IsPascal : 1;
409
410 /// The number of concatenated token this string is made of.
411 /// This is the number of trailing SourceLocation.
412 unsigned NumConcatenated;
413 };
414
415 class CharacterLiteralBitfields {
416 friend class CharacterLiteral;
417
418 unsigned : NumExprBits;
419
420 unsigned Kind : 3;
421 };
422
423 class UnaryOperatorBitfields {
424 friend class UnaryOperator;
425
426 unsigned : NumExprBits;
427
428 unsigned Opc : 5;
429 unsigned CanOverflow : 1;
430 //
431 /// This is only meaningful for operations on floating point
432 /// types when additional values need to be in trailing storage.
433 /// It is 0 otherwise.
434 unsigned HasFPFeatures : 1;
435
436 SourceLocation Loc;
437 };
438
439 class UnaryExprOrTypeTraitExprBitfields {
440 friend class UnaryExprOrTypeTraitExpr;
441
442 unsigned : NumExprBits;
443
444 unsigned Kind : 3;
445 unsigned IsType : 1; // true if operand is a type, false if an expression.
446 };
447
448 class ArrayOrMatrixSubscriptExprBitfields {
449 friend class ArraySubscriptExpr;
450 friend class MatrixSubscriptExpr;
451
452 unsigned : NumExprBits;
453
454 SourceLocation RBracketLoc;
455 };
456
457 class CallExprBitfields {
458 friend class CallExpr;
459
460 unsigned : NumExprBits;
461
462 unsigned NumPreArgs : 1;
463
464 /// True if the callee of the call expression was found using ADL.
465 unsigned UsesADL : 1;
466
467 /// Padding used to align OffsetToTrailingObjects to a byte multiple.
468 unsigned : 24 - 2 - NumExprBits;
469
470 /// The offset in bytes from the this pointer to the start of the
471 /// trailing objects belonging to CallExpr. Intentionally byte sized
472 /// for faster access.
473 unsigned OffsetToTrailingObjects : 8;
474 };
475 enum { NumCallExprBits = 32 };
476
477 class MemberExprBitfields {
478 friend class ASTStmtReader;
479 friend class MemberExpr;
480
481 unsigned : NumExprBits;
482
483 /// IsArrow - True if this is "X->F", false if this is "X.F".
484 unsigned IsArrow : 1;
485
486 /// True if this member expression used a nested-name-specifier to
487 /// refer to the member, e.g., "x->Base::f", or found its member via
488 /// a using declaration. When true, a MemberExprNameQualifier
489 /// structure is allocated immediately after the MemberExpr.
490 unsigned HasQualifierOrFoundDecl : 1;
491
492 /// True if this member expression specified a template keyword
493 /// and/or a template argument list explicitly, e.g., x->f<int>,
494 /// x->template f, x->template f<int>.
495 /// When true, an ASTTemplateKWAndArgsInfo structure and its
496 /// TemplateArguments (if any) are present.
497 unsigned HasTemplateKWAndArgsInfo : 1;
498
499 /// True if this member expression refers to a method that
500 /// was resolved from an overloaded set having size greater than 1.
501 unsigned HadMultipleCandidates : 1;
502
503 /// Value of type NonOdrUseReason indicating why this MemberExpr does
504 /// not constitute an odr-use of the named declaration. Meaningful only
505 /// when naming a static member.
506 unsigned NonOdrUseReason : 2;
507
508 /// This is the location of the -> or . in the expression.
509 SourceLocation OperatorLoc;
510 };
511
512 class CastExprBitfields {
513 friend class CastExpr;
514 friend class ImplicitCastExpr;
515
516 unsigned : NumExprBits;
517
518 #define CAST_KIND_BITS 7
519 unsigned Kind : CAST_KIND_BITS;
520 unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
521
522 /// The number of CXXBaseSpecifiers in the cast. 14 bits would be enough
523 /// here. ([implimits] Direct and indirect base classes [16384]).
524 unsigned BasePathSize;
525 };
526
527 class BinaryOperatorBitfields {
528 friend class BinaryOperator;
529
530 unsigned : NumExprBits;
531
532 unsigned Opc : 6;
533
534 /// This is only meaningful for operations on floating point
535 /// types when additional values need to be in trailing storage.
536 /// It is 0 otherwise.
537 unsigned HasFPFeatures : 1;
538
539 SourceLocation OpLoc;
540 };
541
542 class InitListExprBitfields {
543 friend class InitListExpr;
544
545 unsigned : NumExprBits;
546
547 /// Whether this initializer list originally had a GNU array-range
548 /// designator in it. This is a temporary marker used by CodeGen.
549 unsigned HadArrayRangeDesignator : 1;
550 };
551
552 class ParenListExprBitfields {
553 friend class ASTStmtReader;
554 friend class ParenListExpr;
555
556 unsigned : NumExprBits;
557
558 /// The number of expressions in the paren list.
559 unsigned NumExprs;
560 };
561
562 class GenericSelectionExprBitfields {
563 friend class ASTStmtReader;
564 friend class GenericSelectionExpr;
565
566 unsigned : NumExprBits;
567
568 /// The location of the "_Generic".
569 SourceLocation GenericLoc;
570 };
571
572 class PseudoObjectExprBitfields {
573 friend class ASTStmtReader; // deserialization
574 friend class PseudoObjectExpr;
575
576 unsigned : NumExprBits;
577
578 // These don't need to be particularly wide, because they're
579 // strictly limited by the forms of expressions we permit.
580 unsigned NumSubExprs : 8;
581 unsigned ResultIndex : 32 - 8 - NumExprBits;
582 };
583
584 class SourceLocExprBitfields {
585 friend class ASTStmtReader;
586 friend class SourceLocExpr;
587
588 unsigned : NumExprBits;
589
590 /// The kind of source location builtin represented by the SourceLocExpr.
591 /// Ex. __builtin_LINE, __builtin_FUNCTION, ect.
592 unsigned Kind : 2;
593 };
594
595 class StmtExprBitfields {
596 friend class ASTStmtReader;
597 friend class StmtExpr;
598
599 unsigned : NumExprBits;
600
601 /// The number of levels of template parameters enclosing this statement
602 /// expression. Used to determine if a statement expression remains
603 /// dependent after instantiation.
604 unsigned TemplateDepth;
605 };
606
607 //===--- C++ Expression bitfields classes ---===//
608
609 class CXXOperatorCallExprBitfields {
610 friend class ASTStmtReader;
611 friend class CXXOperatorCallExpr;
612
613 unsigned : NumCallExprBits;
614
615 /// The kind of this overloaded operator. One of the enumerator
616 /// value of OverloadedOperatorKind.
617 unsigned OperatorKind : 6;
618 };
619
620 class CXXRewrittenBinaryOperatorBitfields {
621 friend class ASTStmtReader;
622 friend class CXXRewrittenBinaryOperator;
623
624 unsigned : NumCallExprBits;
625
626 unsigned IsReversed : 1;
627 };
628
629 class CXXBoolLiteralExprBitfields {
630 friend class CXXBoolLiteralExpr;
631
632 unsigned : NumExprBits;
633
634 /// The value of the boolean literal.
635 unsigned Value : 1;
636
637 /// The location of the boolean literal.
638 SourceLocation Loc;
639 };
640
641 class CXXNullPtrLiteralExprBitfields {
642 friend class CXXNullPtrLiteralExpr;
643
644 unsigned : NumExprBits;
645
646 /// The location of the null pointer literal.
647 SourceLocation Loc;
648 };
649
650 class CXXThisExprBitfields {
651 friend class CXXThisExpr;
652
653 unsigned : NumExprBits;
654
655 /// Whether this is an implicit "this".
656 unsigned IsImplicit : 1;
657
658 /// The location of the "this".
659 SourceLocation Loc;
660 };
661
662 class CXXThrowExprBitfields {
663 friend class ASTStmtReader;
664 friend class CXXThrowExpr;
665
666 unsigned : NumExprBits;
667
668 /// Whether the thrown variable (if any) is in scope.
669 unsigned IsThrownVariableInScope : 1;
670
671 /// The location of the "throw".
672 SourceLocation ThrowLoc;
673 };
674
675 class CXXDefaultArgExprBitfields {
676 friend class ASTStmtReader;
677 friend class CXXDefaultArgExpr;
678
679 unsigned : NumExprBits;
680
681 /// The location where the default argument expression was used.
682 SourceLocation Loc;
683 };
684
685 class CXXDefaultInitExprBitfields {
686 friend class ASTStmtReader;
687 friend class CXXDefaultInitExpr;
688
689 unsigned : NumExprBits;
690
691 /// The location where the default initializer expression was used.
692 SourceLocation Loc;
693 };
694
695 class CXXScalarValueInitExprBitfields {
696 friend class ASTStmtReader;
697 friend class CXXScalarValueInitExpr;
698
699 unsigned : NumExprBits;
700
701 SourceLocation RParenLoc;
702 };
703
704 class CXXNewExprBitfields {
705 friend class ASTStmtReader;
706 friend class ASTStmtWriter;
707 friend class CXXNewExpr;
708
709 unsigned : NumExprBits;
710
711 /// Was the usage ::new, i.e. is the global new to be used?
712 unsigned IsGlobalNew : 1;
713
714 /// Do we allocate an array? If so, the first trailing "Stmt *" is the
715 /// size expression.
716 unsigned IsArray : 1;
717
718 /// Should the alignment be passed to the allocation function?
719 unsigned ShouldPassAlignment : 1;
720
721 /// If this is an array allocation, does the usual deallocation
722 /// function for the allocated type want to know the allocated size?
723 unsigned UsualArrayDeleteWantsSize : 1;
724
725 /// What kind of initializer do we have? Could be none, parens, or braces.
726 /// In storage, we distinguish between "none, and no initializer expr", and
727 /// "none, but an implicit initializer expr".
728 unsigned StoredInitializationStyle : 2;
729
730 /// True if the allocated type was expressed as a parenthesized type-id.
731 unsigned IsParenTypeId : 1;
732
733 /// The number of placement new arguments.
734 unsigned NumPlacementArgs;
735 };
736
737 class CXXDeleteExprBitfields {
738 friend class ASTStmtReader;
739 friend class CXXDeleteExpr;
740
741 unsigned : NumExprBits;
742
743 /// Is this a forced global delete, i.e. "::delete"?
744 unsigned GlobalDelete : 1;
745
746 /// Is this the array form of delete, i.e. "delete[]"?
747 unsigned ArrayForm : 1;
748
749 /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is
750 /// applied to pointer-to-array type (ArrayFormAsWritten will be false
751 /// while ArrayForm will be true).
752 unsigned ArrayFormAsWritten : 1;
753
754 /// Does the usual deallocation function for the element type require
755 /// a size_t argument?
756 unsigned UsualArrayDeleteWantsSize : 1;
757
758 /// Location of the expression.
759 SourceLocation Loc;
760 };
761
762 class TypeTraitExprBitfields {
763 friend class ASTStmtReader;
764 friend class ASTStmtWriter;
765 friend class TypeTraitExpr;
766
767 unsigned : NumExprBits;
768
769 /// The kind of type trait, which is a value of a TypeTrait enumerator.
770 unsigned Kind : 8;
771
772 /// If this expression is not value-dependent, this indicates whether
773 /// the trait evaluated true or false.
774 unsigned Value : 1;
775
776 /// The number of arguments to this type trait. According to [implimits]
777 /// 8 bits would be enough, but we require (and test for) at least 16 bits
778 /// to mirror FunctionType.
779 unsigned NumArgs;
780 };
781
782 class DependentScopeDeclRefExprBitfields {
783 friend class ASTStmtReader;
784 friend class ASTStmtWriter;
785 friend class DependentScopeDeclRefExpr;
786
787 unsigned : NumExprBits;
788
789 /// Whether the name includes info for explicit template
790 /// keyword and arguments.
791 unsigned HasTemplateKWAndArgsInfo : 1;
792 };
793
794 class CXXConstructExprBitfields {
795 friend class ASTStmtReader;
796 friend class CXXConstructExpr;
797
798 unsigned : NumExprBits;
799
800 unsigned Elidable : 1;
801 unsigned HadMultipleCandidates : 1;
802 unsigned ListInitialization : 1;
803 unsigned StdInitListInitialization : 1;
804 unsigned ZeroInitialization : 1;
805 unsigned ConstructionKind : 3;
806
807 SourceLocation Loc;
808 };
809
810 class ExprWithCleanupsBitfields {
811 friend class ASTStmtReader; // deserialization
812 friend class ExprWithCleanups;
813
814 unsigned : NumExprBits;
815
816 // When false, it must not have side effects.
817 unsigned CleanupsHaveSideEffects : 1;
818
819 unsigned NumObjects : 32 - 1 - NumExprBits;
820 };
821
822 class CXXUnresolvedConstructExprBitfields {
823 friend class ASTStmtReader;
824 friend class CXXUnresolvedConstructExpr;
825
826 unsigned : NumExprBits;
827
828 /// The number of arguments used to construct the type.
829 unsigned NumArgs;
830 };
831
832 class CXXDependentScopeMemberExprBitfields {
833 friend class ASTStmtReader;
834 friend class CXXDependentScopeMemberExpr;
835
836 unsigned : NumExprBits;
837
838 /// Whether this member expression used the '->' operator or
839 /// the '.' operator.
840 unsigned IsArrow : 1;
841
842 /// Whether this member expression has info for explicit template
843 /// keyword and arguments.
844 unsigned HasTemplateKWAndArgsInfo : 1;
845
846 /// See getFirstQualifierFoundInScope() and the comment listing
847 /// the trailing objects.
848 unsigned HasFirstQualifierFoundInScope : 1;
849
850 /// The location of the '->' or '.' operator.
851 SourceLocation OperatorLoc;
852 };
853
854 class OverloadExprBitfields {
855 friend class ASTStmtReader;
856 friend class OverloadExpr;
857
858 unsigned : NumExprBits;
859
860 /// Whether the name includes info for explicit template
861 /// keyword and arguments.
862 unsigned HasTemplateKWAndArgsInfo : 1;
863
864 /// Padding used by the derived classes to store various bits. If you
865 /// need to add some data here, shrink this padding and add your data
866 /// above. NumOverloadExprBits also needs to be updated.
867 unsigned : 32 - NumExprBits - 1;
868
869 /// The number of results.
870 unsigned NumResults;
871 };
872 enum { NumOverloadExprBits = NumExprBits + 1 };
873
874 class UnresolvedLookupExprBitfields {
875 friend class ASTStmtReader;
876 friend class UnresolvedLookupExpr;
877
878 unsigned : NumOverloadExprBits;
879
880 /// True if these lookup results should be extended by
881 /// argument-dependent lookup if this is the operand of a function call.
882 unsigned RequiresADL : 1;
883
884 /// True if these lookup results are overloaded. This is pretty trivially
885 /// rederivable if we urgently need to kill this field.
886 unsigned Overloaded : 1;
887 };
888 static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4,
889 "UnresolvedLookupExprBitfields must be <= than 4 bytes to"
890 "avoid trashing OverloadExprBitfields::NumResults!");
891
892 class UnresolvedMemberExprBitfields {
893 friend class ASTStmtReader;
894 friend class UnresolvedMemberExpr;
895
896 unsigned : NumOverloadExprBits;
897
898 /// Whether this member expression used the '->' operator or
899 /// the '.' operator.
900 unsigned IsArrow : 1;
901
902 /// Whether the lookup results contain an unresolved using declaration.
903 unsigned HasUnresolvedUsing : 1;
904 };
905 static_assert(sizeof(UnresolvedMemberExprBitfields) <= 4,
906 "UnresolvedMemberExprBitfields must be <= than 4 bytes to"
907 "avoid trashing OverloadExprBitfields::NumResults!");
908
909 class CXXNoexceptExprBitfields {
910 friend class ASTStmtReader;
911 friend class CXXNoexceptExpr;
912
913 unsigned : NumExprBits;
914
915 unsigned Value : 1;
916 };
917
918 class SubstNonTypeTemplateParmExprBitfields {
919 friend class ASTStmtReader;
920 friend class SubstNonTypeTemplateParmExpr;
921
922 unsigned : NumExprBits;
923
924 /// The location of the non-type template parameter reference.
925 SourceLocation NameLoc;
926 };
927
928 class LambdaExprBitfields {
929 friend class ASTStmtReader;
930 friend class ASTStmtWriter;
931 friend class LambdaExpr;
932
933 unsigned : NumExprBits;
934
935 /// The default capture kind, which is a value of type
936 /// LambdaCaptureDefault.
937 unsigned CaptureDefault : 2;
938
939 /// Whether this lambda had an explicit parameter list vs. an
940 /// implicit (and empty) parameter list.
941 unsigned ExplicitParams : 1;
942
943 /// Whether this lambda had the result type explicitly specified.
944 unsigned ExplicitResultType : 1;
945
946 /// The number of captures.
947 unsigned NumCaptures : 16;
948 };
949
950 class RequiresExprBitfields {
951 friend class ASTStmtReader;
952 friend class ASTStmtWriter;
953 friend class RequiresExpr;
954
955 unsigned : NumExprBits;
956
957 unsigned IsSatisfied : 1;
958 SourceLocation RequiresKWLoc;
959 };
960
961 //===--- C++ Coroutines TS bitfields classes ---===//
962
963 class CoawaitExprBitfields {
964 friend class CoawaitExpr;
965
966 unsigned : NumExprBits;
967
968 unsigned IsImplicit : 1;
969 };
970
971 //===--- Obj-C Expression bitfields classes ---===//
972
973 class ObjCIndirectCopyRestoreExprBitfields {
974 friend class ObjCIndirectCopyRestoreExpr;
975
976 unsigned : NumExprBits;
977
978 unsigned ShouldCopy : 1;
979 };
980
981 //===--- Clang Extensions bitfields classes ---===//
982
983 class OpaqueValueExprBitfields {
984 friend class ASTStmtReader;
985 friend class OpaqueValueExpr;
986
987 unsigned : NumExprBits;
988
989 /// The OVE is a unique semantic reference to its source expression if this
990 /// bit is set to true.
991 unsigned IsUnique : 1;
992
993 SourceLocation Loc;
994 };
995
996 union {
997 // Same order as in StmtNodes.td.
998 // Statements
999 StmtBitfields StmtBits;
1000 NullStmtBitfields NullStmtBits;
1001 CompoundStmtBitfields CompoundStmtBits;
1002 LabelStmtBitfields LabelStmtBits;
1003 AttributedStmtBitfields AttributedStmtBits;
1004 IfStmtBitfields IfStmtBits;
1005 SwitchStmtBitfields SwitchStmtBits;
1006 WhileStmtBitfields WhileStmtBits;
1007 DoStmtBitfields DoStmtBits;
1008 ForStmtBitfields ForStmtBits;
1009 GotoStmtBitfields GotoStmtBits;
1010 ContinueStmtBitfields ContinueStmtBits;
1011 BreakStmtBitfields BreakStmtBits;
1012 ReturnStmtBitfields ReturnStmtBits;
1013 SwitchCaseBitfields SwitchCaseBits;
1014
1015 // Expressions
1016 ExprBitfields ExprBits;
1017 ConstantExprBitfields ConstantExprBits;
1018 PredefinedExprBitfields PredefinedExprBits;
1019 DeclRefExprBitfields DeclRefExprBits;
1020 FloatingLiteralBitfields FloatingLiteralBits;
1021 StringLiteralBitfields StringLiteralBits;
1022 CharacterLiteralBitfields CharacterLiteralBits;
1023 UnaryOperatorBitfields UnaryOperatorBits;
1024 UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits;
1025 ArrayOrMatrixSubscriptExprBitfields ArrayOrMatrixSubscriptExprBits;
1026 CallExprBitfields CallExprBits;
1027 MemberExprBitfields MemberExprBits;
1028 CastExprBitfields CastExprBits;
1029 BinaryOperatorBitfields BinaryOperatorBits;
1030 InitListExprBitfields InitListExprBits;
1031 ParenListExprBitfields ParenListExprBits;
1032 GenericSelectionExprBitfields GenericSelectionExprBits;
1033 PseudoObjectExprBitfields PseudoObjectExprBits;
1034 SourceLocExprBitfields SourceLocExprBits;
1035
1036 // GNU Extensions.
1037 StmtExprBitfields StmtExprBits;
1038
1039 // C++ Expressions
1040 CXXOperatorCallExprBitfields CXXOperatorCallExprBits;
1041 CXXRewrittenBinaryOperatorBitfields CXXRewrittenBinaryOperatorBits;
1042 CXXBoolLiteralExprBitfields CXXBoolLiteralExprBits;
1043 CXXNullPtrLiteralExprBitfields CXXNullPtrLiteralExprBits;
1044 CXXThisExprBitfields CXXThisExprBits;
1045 CXXThrowExprBitfields CXXThrowExprBits;
1046 CXXDefaultArgExprBitfields CXXDefaultArgExprBits;
1047 CXXDefaultInitExprBitfields CXXDefaultInitExprBits;
1048 CXXScalarValueInitExprBitfields CXXScalarValueInitExprBits;
1049 CXXNewExprBitfields CXXNewExprBits;
1050 CXXDeleteExprBitfields CXXDeleteExprBits;
1051 TypeTraitExprBitfields TypeTraitExprBits;
1052 DependentScopeDeclRefExprBitfields DependentScopeDeclRefExprBits;
1053 CXXConstructExprBitfields CXXConstructExprBits;
1054 ExprWithCleanupsBitfields ExprWithCleanupsBits;
1055 CXXUnresolvedConstructExprBitfields CXXUnresolvedConstructExprBits;
1056 CXXDependentScopeMemberExprBitfields CXXDependentScopeMemberExprBits;
1057 OverloadExprBitfields OverloadExprBits;
1058 UnresolvedLookupExprBitfields UnresolvedLookupExprBits;
1059 UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
1060 CXXNoexceptExprBitfields CXXNoexceptExprBits;
1061 SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
1062 LambdaExprBitfields LambdaExprBits;
1063 RequiresExprBitfields RequiresExprBits;
1064
1065 // C++ Coroutines TS expressions
1066 CoawaitExprBitfields CoawaitBits;
1067
1068 // Obj-C Expressions
1069 ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
1070
1071 // Clang Extensions
1072 OpaqueValueExprBitfields OpaqueValueExprBits;
1073 };
1074
1075 public:
1076 // Only allow allocation of Stmts using the allocator in ASTContext
1077 // or by doing a placement new.
1078 void* operator new(size_t bytes, const ASTContext& C,
1079 unsigned alignment = 8);
1080
1081 void* operator new(size_t bytes, const ASTContext* C,
1082 unsigned alignment = 8) {
1083 return operator new(bytes, *C, alignment);
1084 }
1085
1086 void *operator new(size_t bytes, void *mem) noexcept { return mem; }
1087
1088 void operator delete(void *, const ASTContext &, unsigned) noexcept {}
1089 void operator delete(void *, const ASTContext *, unsigned) noexcept {}
1090 void operator delete(void *, size_t) noexcept {}
1091 void operator delete(void *, void *) noexcept {}
1092
1093 public:
1094 /// A placeholder type used to construct an empty shell of a
1095 /// type, that will be filled in later (e.g., by some
1096 /// de-serialization).
1097 struct EmptyShell {};
1098
1099 protected:
1100 /// Iterator for iterating over Stmt * arrays that contain only T *.
1101 ///
1102 /// This is needed because AST nodes use Stmt* arrays to store
1103 /// references to children (to be compatible with StmtIterator).
1104 template<typename T, typename TPtr = T *, typename StmtPtr = Stmt *>
1105 struct CastIterator
1106 : llvm::iterator_adaptor_base<CastIterator<T, TPtr, StmtPtr>, StmtPtr *,
1107 std::random_access_iterator_tag, TPtr> {
1108 using Base = typename CastIterator::iterator_adaptor_base;
1109
1110 CastIterator() : Base(nullptr) {}
1111 CastIterator(StmtPtr *I) : Base(I) {}
1112
1113 typename Base::value_type operator*() const {
1114 return cast_or_null<T>(*this->I);
1115 }
1116 };
1117
1118 /// Const iterator for iterating over Stmt * arrays that contain only T *.
1119 template <typename T>
1120 using ConstCastIterator = CastIterator<T, const T *const, const Stmt *const>;
1121
1122 using ExprIterator = CastIterator<Expr>;
1123 using ConstExprIterator = ConstCastIterator<Expr>;
1124
1125 private:
1126 /// Whether statistic collection is enabled.
1127 static bool StatisticsEnabled;
1128
1129 protected:
1130 /// Construct an empty statement.
1131 explicit Stmt(StmtClass SC, EmptyShell) : Stmt(SC) {}
1132
1133 public:
1134 Stmt() = delete;
1135 Stmt(const Stmt &) = delete;
1136 Stmt(Stmt &&) = delete;
1137 Stmt &operator=(const Stmt &) = delete;
1138 Stmt &operator=(Stmt &&) = delete;
1139
1140 Stmt(StmtClass SC) {
1141 static_assert(sizeof(*this) <= 8,
1142 "changing bitfields changed sizeof(Stmt)");
1143 static_assert(sizeof(*this) % alignof(void *) == 0,
1144 "Insufficient alignment!");
1145 StmtBits.sClass = SC;
1146 if (StatisticsEnabled) Stmt::addStmtClass(SC);
1147 }
1148
1149 StmtClass getStmtClass() const {
1150 return static_cast<StmtClass>(StmtBits.sClass);
1151 }
1152
1153 const char *getStmtClassName() const;
1154
1155 /// SourceLocation tokens are not useful in isolation - they are low level
1156 /// value objects created/interpreted by SourceManager. We assume AST
1157 /// clients will have a pointer to the respective SourceManager.
1158 SourceRange getSourceRange() const LLVM_READONLY;
1159 SourceLocation getBeginLoc() const LLVM_READONLY;
1160 SourceLocation getEndLoc() const LLVM_READONLY;
1161
1162 // global temp stats (until we have a per-module visitor)
1163 static void addStmtClass(const StmtClass s);
1164 static void EnableStatistics();
1165 static void PrintStats();
1166
1167 /// Dumps the specified AST fragment and all subtrees to
1168 /// \c llvm::errs().
1169 void dump() const;
1170 void dump(raw_ostream &OS, const ASTContext &Context) const;
1171
1172 /// \return Unique reproducible object identifier
1173 int64_t getID(const ASTContext &Context) const;
1174
1175 /// dumpColor - same as dump(), but forces color highlighting.
1176 void dumpColor() const;
1177
1178 /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
1179 /// back to its original source language syntax.
1180 void dumpPretty(const ASTContext &Context) const;
1181 void printPretty(raw_ostream &OS, PrinterHelper *Helper,
1182 const PrintingPolicy &Policy, unsigned Indentation = 0,
1183 StringRef NewlineSymbol = "\n",
1184 const ASTContext *Context = nullptr) const;
1185
1186 /// Pretty-prints in JSON format.
1187 void printJson(raw_ostream &Out, PrinterHelper *Helper,
1188 const PrintingPolicy &Policy, bool AddQuotes) const;
1189
1190 /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
1191 /// works on systems with GraphViz (Mac OS X) or dot+gv installed.
1192 void viewAST() const;
1193
1194 /// Skip no-op (attributed, compound) container stmts and skip captured
1195 /// stmt at the top, if \a IgnoreCaptured is true.
1196 Stmt *IgnoreContainers(bool IgnoreCaptured = false);
1197 const Stmt *IgnoreContainers(bool IgnoreCaptured = false) const {
1198 return const_cast<Stmt *>(this)->IgnoreContainers(IgnoreCaptured);
1199 }
1200
1201 const Stmt *stripLabelLikeStatements() const;
1202 Stmt *stripLabelLikeStatements() {
1203 return const_cast<Stmt*>(
1204 const_cast<const Stmt*>(this)->stripLabelLikeStatements());
1205 }
1206
1207 /// Child Iterators: All subclasses must implement 'children'
1208 /// to permit easy iteration over the substatements/subexpessions of an
1209 /// AST node. This permits easy iteration over all nodes in the AST.
1210 using child_iterator = StmtIterator;
1211 using const_child_iterator = ConstStmtIterator;
1212
1213 using child_range = llvm::iterator_range<child_iterator>;
1214 using const_child_range = llvm::iterator_range<const_child_iterator>;
1215
1216 child_range children();
1217
1218 const_child_range children() const {
1219 auto Children = const_cast<Stmt *>(this)->children();
1220 return const_child_range(Children.begin(), Children.end());
1221 }
1222
1223 child_iterator child_begin() { return children().begin(); }
1224 child_iterator child_end() { return children().end(); }
1225
1226 const_child_iterator child_begin() const { return children().begin(); }
1227 const_child_iterator child_end() const { return children().end(); }
1228
1229 /// Produce a unique representation of the given statement.
1230 ///
1231 /// \param ID once the profiling operation is complete, will contain
1232 /// the unique representation of the given statement.
1233 ///
1234 /// \param Context the AST context in which the statement resides
1235 ///
1236 /// \param Canonical whether the profile should be based on the canonical
1237 /// representation of this statement (e.g., where non-type template
1238 /// parameters are identified by index/level rather than their
1239 /// declaration pointers) or the exact representation of the statement as
1240 /// written in the source.
1241 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
1242 bool Canonical) const;
1243
1244 /// Calculate a unique representation for a statement that is
1245 /// stable across compiler invocations.
1246 ///
1247 /// \param ID profile information will be stored in ID.
1248 ///
1249 /// \param Hash an ODRHash object which will be called where pointers would
1250 /// have been used in the Profile function.
1251 void ProcessODRHash(llvm::FoldingSetNodeID &ID, ODRHash& Hash) const;
1252 };
1253
1254 /// DeclStmt - Adaptor class for mixing declarations with statements and
1255 /// expressions. For example, CompoundStmt mixes statements, expressions
1256 /// and declarations (variables, types). Another example is ForStmt, where
1257 /// the first statement can be an expression or a declaration.
1258 class DeclStmt : public Stmt {
1259 DeclGroupRef DG;
1260 SourceLocation StartLoc, EndLoc;
1261
1262 public:
DeclStmt(DeclGroupRef dg,SourceLocation startLoc,SourceLocation endLoc)1263 DeclStmt(DeclGroupRef dg, SourceLocation startLoc, SourceLocation endLoc)
1264 : Stmt(DeclStmtClass), DG(dg), StartLoc(startLoc), EndLoc(endLoc) {}
1265
1266 /// Build an empty declaration statement.
DeclStmt(EmptyShell Empty)1267 explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) {}
1268
1269 /// isSingleDecl - This method returns true if this DeclStmt refers
1270 /// to a single Decl.
isSingleDecl()1271 bool isSingleDecl() const { return DG.isSingleDecl(); }
1272
getSingleDecl()1273 const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
getSingleDecl()1274 Decl *getSingleDecl() { return DG.getSingleDecl(); }
1275
getDeclGroup()1276 const DeclGroupRef getDeclGroup() const { return DG; }
getDeclGroup()1277 DeclGroupRef getDeclGroup() { return DG; }
setDeclGroup(DeclGroupRef DGR)1278 void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
1279
setStartLoc(SourceLocation L)1280 void setStartLoc(SourceLocation L) { StartLoc = L; }
getEndLoc()1281 SourceLocation getEndLoc() const { return EndLoc; }
setEndLoc(SourceLocation L)1282 void setEndLoc(SourceLocation L) { EndLoc = L; }
1283
getBeginLoc()1284 SourceLocation getBeginLoc() const LLVM_READONLY { return StartLoc; }
1285
classof(const Stmt * T)1286 static bool classof(const Stmt *T) {
1287 return T->getStmtClass() == DeclStmtClass;
1288 }
1289
1290 // Iterators over subexpressions.
children()1291 child_range children() {
1292 return child_range(child_iterator(DG.begin(), DG.end()),
1293 child_iterator(DG.end(), DG.end()));
1294 }
1295
children()1296 const_child_range children() const {
1297 auto Children = const_cast<DeclStmt *>(this)->children();
1298 return const_child_range(Children);
1299 }
1300
1301 using decl_iterator = DeclGroupRef::iterator;
1302 using const_decl_iterator = DeclGroupRef::const_iterator;
1303 using decl_range = llvm::iterator_range<decl_iterator>;
1304 using decl_const_range = llvm::iterator_range<const_decl_iterator>;
1305
decls()1306 decl_range decls() { return decl_range(decl_begin(), decl_end()); }
1307
decls()1308 decl_const_range decls() const {
1309 return decl_const_range(decl_begin(), decl_end());
1310 }
1311
decl_begin()1312 decl_iterator decl_begin() { return DG.begin(); }
decl_end()1313 decl_iterator decl_end() { return DG.end(); }
decl_begin()1314 const_decl_iterator decl_begin() const { return DG.begin(); }
decl_end()1315 const_decl_iterator decl_end() const { return DG.end(); }
1316
1317 using reverse_decl_iterator = std::reverse_iterator<decl_iterator>;
1318
decl_rbegin()1319 reverse_decl_iterator decl_rbegin() {
1320 return reverse_decl_iterator(decl_end());
1321 }
1322
decl_rend()1323 reverse_decl_iterator decl_rend() {
1324 return reverse_decl_iterator(decl_begin());
1325 }
1326 };
1327
1328 /// NullStmt - This is the null statement ";": C99 6.8.3p3.
1329 ///
1330 class NullStmt : public Stmt {
1331 public:
1332 NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
Stmt(NullStmtClass)1333 : Stmt(NullStmtClass) {
1334 NullStmtBits.HasLeadingEmptyMacro = hasLeadingEmptyMacro;
1335 setSemiLoc(L);
1336 }
1337
1338 /// Build an empty null statement.
NullStmt(EmptyShell Empty)1339 explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) {}
1340
getSemiLoc()1341 SourceLocation getSemiLoc() const { return NullStmtBits.SemiLoc; }
setSemiLoc(SourceLocation L)1342 void setSemiLoc(SourceLocation L) { NullStmtBits.SemiLoc = L; }
1343
hasLeadingEmptyMacro()1344 bool hasLeadingEmptyMacro() const {
1345 return NullStmtBits.HasLeadingEmptyMacro;
1346 }
1347
getBeginLoc()1348 SourceLocation getBeginLoc() const { return getSemiLoc(); }
getEndLoc()1349 SourceLocation getEndLoc() const { return getSemiLoc(); }
1350
classof(const Stmt * T)1351 static bool classof(const Stmt *T) {
1352 return T->getStmtClass() == NullStmtClass;
1353 }
1354
children()1355 child_range children() {
1356 return child_range(child_iterator(), child_iterator());
1357 }
1358
children()1359 const_child_range children() const {
1360 return const_child_range(const_child_iterator(), const_child_iterator());
1361 }
1362 };
1363
1364 /// CompoundStmt - This represents a group of statements like { stmt stmt }.
1365 class CompoundStmt final : public Stmt,
1366 private llvm::TrailingObjects<CompoundStmt, Stmt *> {
1367 friend class ASTStmtReader;
1368 friend TrailingObjects;
1369
1370 /// The location of the closing "}". LBraceLoc is stored in CompoundStmtBits.
1371 SourceLocation RBraceLoc;
1372
1373 CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB, SourceLocation RB);
CompoundStmt(EmptyShell Empty)1374 explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {}
1375
1376 void setStmts(ArrayRef<Stmt *> Stmts);
1377
1378 public:
1379 static CompoundStmt *Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
1380 SourceLocation LB, SourceLocation RB);
1381
1382 // Build an empty compound statement with a location.
CompoundStmt(SourceLocation Loc)1383 explicit CompoundStmt(SourceLocation Loc)
1384 : Stmt(CompoundStmtClass), RBraceLoc(Loc) {
1385 CompoundStmtBits.NumStmts = 0;
1386 CompoundStmtBits.LBraceLoc = Loc;
1387 }
1388
1389 // Build an empty compound statement.
1390 static CompoundStmt *CreateEmpty(const ASTContext &C, unsigned NumStmts);
1391
body_empty()1392 bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
size()1393 unsigned size() const { return CompoundStmtBits.NumStmts; }
1394
1395 using body_iterator = Stmt **;
1396 using body_range = llvm::iterator_range<body_iterator>;
1397
body()1398 body_range body() { return body_range(body_begin(), body_end()); }
body_begin()1399 body_iterator body_begin() { return getTrailingObjects<Stmt *>(); }
body_end()1400 body_iterator body_end() { return body_begin() + size(); }
body_front()1401 Stmt *body_front() { return !body_empty() ? body_begin()[0] : nullptr; }
1402
body_back()1403 Stmt *body_back() {
1404 return !body_empty() ? body_begin()[size() - 1] : nullptr;
1405 }
1406
1407 using const_body_iterator = Stmt *const *;
1408 using body_const_range = llvm::iterator_range<const_body_iterator>;
1409
body()1410 body_const_range body() const {
1411 return body_const_range(body_begin(), body_end());
1412 }
1413
body_begin()1414 const_body_iterator body_begin() const {
1415 return getTrailingObjects<Stmt *>();
1416 }
1417
body_end()1418 const_body_iterator body_end() const { return body_begin() + size(); }
1419
body_front()1420 const Stmt *body_front() const {
1421 return !body_empty() ? body_begin()[0] : nullptr;
1422 }
1423
body_back()1424 const Stmt *body_back() const {
1425 return !body_empty() ? body_begin()[size() - 1] : nullptr;
1426 }
1427
1428 using reverse_body_iterator = std::reverse_iterator<body_iterator>;
1429
body_rbegin()1430 reverse_body_iterator body_rbegin() {
1431 return reverse_body_iterator(body_end());
1432 }
1433
body_rend()1434 reverse_body_iterator body_rend() {
1435 return reverse_body_iterator(body_begin());
1436 }
1437
1438 using const_reverse_body_iterator =
1439 std::reverse_iterator<const_body_iterator>;
1440
body_rbegin()1441 const_reverse_body_iterator body_rbegin() const {
1442 return const_reverse_body_iterator(body_end());
1443 }
1444
body_rend()1445 const_reverse_body_iterator body_rend() const {
1446 return const_reverse_body_iterator(body_begin());
1447 }
1448
1449 // Get the Stmt that StmtExpr would consider to be the result of this
1450 // compound statement. This is used by StmtExpr to properly emulate the GCC
1451 // compound expression extension, which ignores trailing NullStmts when
1452 // getting the result of the expression.
1453 // i.e. ({ 5;;; })
1454 // ^^ ignored
1455 // If we don't find something that isn't a NullStmt, just return the last
1456 // Stmt.
getStmtExprResult()1457 Stmt *getStmtExprResult() {
1458 for (auto *B : llvm::reverse(body())) {
1459 if (!isa<NullStmt>(B))
1460 return B;
1461 }
1462 return body_back();
1463 }
1464
getStmtExprResult()1465 const Stmt *getStmtExprResult() const {
1466 return const_cast<CompoundStmt *>(this)->getStmtExprResult();
1467 }
1468
getBeginLoc()1469 SourceLocation getBeginLoc() const { return CompoundStmtBits.LBraceLoc; }
getEndLoc()1470 SourceLocation getEndLoc() const { return RBraceLoc; }
1471
getLBracLoc()1472 SourceLocation getLBracLoc() const { return CompoundStmtBits.LBraceLoc; }
getRBracLoc()1473 SourceLocation getRBracLoc() const { return RBraceLoc; }
1474
classof(const Stmt * T)1475 static bool classof(const Stmt *T) {
1476 return T->getStmtClass() == CompoundStmtClass;
1477 }
1478
1479 // Iterators
children()1480 child_range children() { return child_range(body_begin(), body_end()); }
1481
children()1482 const_child_range children() const {
1483 return const_child_range(body_begin(), body_end());
1484 }
1485 };
1486
1487 // SwitchCase is the base class for CaseStmt and DefaultStmt,
1488 class SwitchCase : public Stmt {
1489 protected:
1490 /// The location of the ":".
1491 SourceLocation ColonLoc;
1492
1493 // The location of the "case" or "default" keyword. Stored in SwitchCaseBits.
1494 // SourceLocation KeywordLoc;
1495
1496 /// A pointer to the following CaseStmt or DefaultStmt class,
1497 /// used by SwitchStmt.
1498 SwitchCase *NextSwitchCase = nullptr;
1499
SwitchCase(StmtClass SC,SourceLocation KWLoc,SourceLocation ColonLoc)1500 SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
1501 : Stmt(SC), ColonLoc(ColonLoc) {
1502 setKeywordLoc(KWLoc);
1503 }
1504
SwitchCase(StmtClass SC,EmptyShell)1505 SwitchCase(StmtClass SC, EmptyShell) : Stmt(SC) {}
1506
1507 public:
getNextSwitchCase()1508 const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
getNextSwitchCase()1509 SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
setNextSwitchCase(SwitchCase * SC)1510 void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
1511
getKeywordLoc()1512 SourceLocation getKeywordLoc() const { return SwitchCaseBits.KeywordLoc; }
setKeywordLoc(SourceLocation L)1513 void setKeywordLoc(SourceLocation L) { SwitchCaseBits.KeywordLoc = L; }
getColonLoc()1514 SourceLocation getColonLoc() const { return ColonLoc; }
setColonLoc(SourceLocation L)1515 void setColonLoc(SourceLocation L) { ColonLoc = L; }
1516
1517 inline Stmt *getSubStmt();
getSubStmt()1518 const Stmt *getSubStmt() const {
1519 return const_cast<SwitchCase *>(this)->getSubStmt();
1520 }
1521
getBeginLoc()1522 SourceLocation getBeginLoc() const { return getKeywordLoc(); }
1523 inline SourceLocation getEndLoc() const LLVM_READONLY;
1524
classof(const Stmt * T)1525 static bool classof(const Stmt *T) {
1526 return T->getStmtClass() == CaseStmtClass ||
1527 T->getStmtClass() == DefaultStmtClass;
1528 }
1529 };
1530
1531 /// CaseStmt - Represent a case statement. It can optionally be a GNU case
1532 /// statement of the form LHS ... RHS representing a range of cases.
1533 class CaseStmt final
1534 : public SwitchCase,
1535 private llvm::TrailingObjects<CaseStmt, Stmt *, SourceLocation> {
1536 friend TrailingObjects;
1537
1538 // CaseStmt is followed by several trailing objects, some of which optional.
1539 // Note that it would be more convenient to put the optional trailing objects
1540 // at the end but this would impact children().
1541 // The trailing objects are in order:
1542 //
1543 // * A "Stmt *" for the LHS of the case statement. Always present.
1544 //
1545 // * A "Stmt *" for the RHS of the case statement. This is a GNU extension
1546 // which allow ranges in cases statement of the form LHS ... RHS.
1547 // Present if and only if caseStmtIsGNURange() is true.
1548 //
1549 // * A "Stmt *" for the substatement of the case statement. Always present.
1550 //
1551 // * A SourceLocation for the location of the ... if this is a case statement
1552 // with a range. Present if and only if caseStmtIsGNURange() is true.
1553 enum { LhsOffset = 0, SubStmtOffsetFromRhs = 1 };
1554 enum { NumMandatoryStmtPtr = 2 };
1555
numTrailingObjects(OverloadToken<Stmt * >)1556 unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
1557 return NumMandatoryStmtPtr + caseStmtIsGNURange();
1558 }
1559
numTrailingObjects(OverloadToken<SourceLocation>)1560 unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
1561 return caseStmtIsGNURange();
1562 }
1563
lhsOffset()1564 unsigned lhsOffset() const { return LhsOffset; }
rhsOffset()1565 unsigned rhsOffset() const { return LhsOffset + caseStmtIsGNURange(); }
subStmtOffset()1566 unsigned subStmtOffset() const { return rhsOffset() + SubStmtOffsetFromRhs; }
1567
1568 /// Build a case statement assuming that the storage for the
1569 /// trailing objects has been properly allocated.
CaseStmt(Expr * lhs,Expr * rhs,SourceLocation caseLoc,SourceLocation ellipsisLoc,SourceLocation colonLoc)1570 CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
1571 SourceLocation ellipsisLoc, SourceLocation colonLoc)
1572 : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
1573 // Handle GNU case statements of the form LHS ... RHS.
1574 bool IsGNURange = rhs != nullptr;
1575 SwitchCaseBits.CaseStmtIsGNURange = IsGNURange;
1576 setLHS(lhs);
1577 setSubStmt(nullptr);
1578 if (IsGNURange) {
1579 setRHS(rhs);
1580 setEllipsisLoc(ellipsisLoc);
1581 }
1582 }
1583
1584 /// Build an empty switch case statement.
CaseStmt(EmptyShell Empty,bool CaseStmtIsGNURange)1585 explicit CaseStmt(EmptyShell Empty, bool CaseStmtIsGNURange)
1586 : SwitchCase(CaseStmtClass, Empty) {
1587 SwitchCaseBits.CaseStmtIsGNURange = CaseStmtIsGNURange;
1588 }
1589
1590 public:
1591 /// Build a case statement.
1592 static CaseStmt *Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
1593 SourceLocation caseLoc, SourceLocation ellipsisLoc,
1594 SourceLocation colonLoc);
1595
1596 /// Build an empty case statement.
1597 static CaseStmt *CreateEmpty(const ASTContext &Ctx, bool CaseStmtIsGNURange);
1598
1599 /// True if this case statement is of the form case LHS ... RHS, which
1600 /// is a GNU extension. In this case the RHS can be obtained with getRHS()
1601 /// and the location of the ellipsis can be obtained with getEllipsisLoc().
caseStmtIsGNURange()1602 bool caseStmtIsGNURange() const { return SwitchCaseBits.CaseStmtIsGNURange; }
1603
getCaseLoc()1604 SourceLocation getCaseLoc() const { return getKeywordLoc(); }
setCaseLoc(SourceLocation L)1605 void setCaseLoc(SourceLocation L) { setKeywordLoc(L); }
1606
1607 /// Get the location of the ... in a case statement of the form LHS ... RHS.
getEllipsisLoc()1608 SourceLocation getEllipsisLoc() const {
1609 return caseStmtIsGNURange() ? *getTrailingObjects<SourceLocation>()
1610 : SourceLocation();
1611 }
1612
1613 /// Set the location of the ... in a case statement of the form LHS ... RHS.
1614 /// Assert that this case statement is of this form.
setEllipsisLoc(SourceLocation L)1615 void setEllipsisLoc(SourceLocation L) {
1616 assert(
1617 caseStmtIsGNURange() &&
1618 "setEllipsisLoc but this is not a case stmt of the form LHS ... RHS!");
1619 *getTrailingObjects<SourceLocation>() = L;
1620 }
1621
getLHS()1622 Expr *getLHS() {
1623 return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[lhsOffset()]);
1624 }
1625
getLHS()1626 const Expr *getLHS() const {
1627 return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[lhsOffset()]);
1628 }
1629
setLHS(Expr * Val)1630 void setLHS(Expr *Val) {
1631 getTrailingObjects<Stmt *>()[lhsOffset()] = reinterpret_cast<Stmt *>(Val);
1632 }
1633
getRHS()1634 Expr *getRHS() {
1635 return caseStmtIsGNURange() ? reinterpret_cast<Expr *>(
1636 getTrailingObjects<Stmt *>()[rhsOffset()])
1637 : nullptr;
1638 }
1639
getRHS()1640 const Expr *getRHS() const {
1641 return caseStmtIsGNURange() ? reinterpret_cast<Expr *>(
1642 getTrailingObjects<Stmt *>()[rhsOffset()])
1643 : nullptr;
1644 }
1645
setRHS(Expr * Val)1646 void setRHS(Expr *Val) {
1647 assert(caseStmtIsGNURange() &&
1648 "setRHS but this is not a case stmt of the form LHS ... RHS!");
1649 getTrailingObjects<Stmt *>()[rhsOffset()] = reinterpret_cast<Stmt *>(Val);
1650 }
1651
getSubStmt()1652 Stmt *getSubStmt() { return getTrailingObjects<Stmt *>()[subStmtOffset()]; }
getSubStmt()1653 const Stmt *getSubStmt() const {
1654 return getTrailingObjects<Stmt *>()[subStmtOffset()];
1655 }
1656
setSubStmt(Stmt * S)1657 void setSubStmt(Stmt *S) {
1658 getTrailingObjects<Stmt *>()[subStmtOffset()] = S;
1659 }
1660
getBeginLoc()1661 SourceLocation getBeginLoc() const { return getKeywordLoc(); }
getEndLoc()1662 SourceLocation getEndLoc() const LLVM_READONLY {
1663 // Handle deeply nested case statements with iteration instead of recursion.
1664 const CaseStmt *CS = this;
1665 while (const auto *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
1666 CS = CS2;
1667
1668 return CS->getSubStmt()->getEndLoc();
1669 }
1670
classof(const Stmt * T)1671 static bool classof(const Stmt *T) {
1672 return T->getStmtClass() == CaseStmtClass;
1673 }
1674
1675 // Iterators
children()1676 child_range children() {
1677 return child_range(getTrailingObjects<Stmt *>(),
1678 getTrailingObjects<Stmt *>() +
1679 numTrailingObjects(OverloadToken<Stmt *>()));
1680 }
1681
children()1682 const_child_range children() const {
1683 return const_child_range(getTrailingObjects<Stmt *>(),
1684 getTrailingObjects<Stmt *>() +
1685 numTrailingObjects(OverloadToken<Stmt *>()));
1686 }
1687 };
1688
1689 class DefaultStmt : public SwitchCase {
1690 Stmt *SubStmt;
1691
1692 public:
DefaultStmt(SourceLocation DL,SourceLocation CL,Stmt * substmt)1693 DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt)
1694 : SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
1695
1696 /// Build an empty default statement.
DefaultStmt(EmptyShell Empty)1697 explicit DefaultStmt(EmptyShell Empty)
1698 : SwitchCase(DefaultStmtClass, Empty) {}
1699
getSubStmt()1700 Stmt *getSubStmt() { return SubStmt; }
getSubStmt()1701 const Stmt *getSubStmt() const { return SubStmt; }
setSubStmt(Stmt * S)1702 void setSubStmt(Stmt *S) { SubStmt = S; }
1703
getDefaultLoc()1704 SourceLocation getDefaultLoc() const { return getKeywordLoc(); }
setDefaultLoc(SourceLocation L)1705 void setDefaultLoc(SourceLocation L) { setKeywordLoc(L); }
1706
getBeginLoc()1707 SourceLocation getBeginLoc() const { return getKeywordLoc(); }
getEndLoc()1708 SourceLocation getEndLoc() const LLVM_READONLY {
1709 return SubStmt->getEndLoc();
1710 }
1711
classof(const Stmt * T)1712 static bool classof(const Stmt *T) {
1713 return T->getStmtClass() == DefaultStmtClass;
1714 }
1715
1716 // Iterators
children()1717 child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
1718
children()1719 const_child_range children() const {
1720 return const_child_range(&SubStmt, &SubStmt + 1);
1721 }
1722 };
1723
getEndLoc()1724 SourceLocation SwitchCase::getEndLoc() const {
1725 if (const auto *CS = dyn_cast<CaseStmt>(this))
1726 return CS->getEndLoc();
1727 else if (const auto *DS = dyn_cast<DefaultStmt>(this))
1728 return DS->getEndLoc();
1729 llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!");
1730 }
1731
getSubStmt()1732 Stmt *SwitchCase::getSubStmt() {
1733 if (auto *CS = dyn_cast<CaseStmt>(this))
1734 return CS->getSubStmt();
1735 else if (auto *DS = dyn_cast<DefaultStmt>(this))
1736 return DS->getSubStmt();
1737 llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!");
1738 }
1739
1740 /// Represents a statement that could possibly have a value and type. This
1741 /// covers expression-statements, as well as labels and attributed statements.
1742 ///
1743 /// Value statements have a special meaning when they are the last non-null
1744 /// statement in a GNU statement expression, where they determine the value
1745 /// of the statement expression.
1746 class ValueStmt : public Stmt {
1747 protected:
1748 using Stmt::Stmt;
1749
1750 public:
1751 const Expr *getExprStmt() const;
getExprStmt()1752 Expr *getExprStmt() {
1753 const ValueStmt *ConstThis = this;
1754 return const_cast<Expr*>(ConstThis->getExprStmt());
1755 }
1756
classof(const Stmt * T)1757 static bool classof(const Stmt *T) {
1758 return T->getStmtClass() >= firstValueStmtConstant &&
1759 T->getStmtClass() <= lastValueStmtConstant;
1760 }
1761 };
1762
1763 /// LabelStmt - Represents a label, which has a substatement. For example:
1764 /// foo: return;
1765 class LabelStmt : public ValueStmt {
1766 LabelDecl *TheDecl;
1767 Stmt *SubStmt;
1768
1769 public:
1770 /// Build a label statement.
LabelStmt(SourceLocation IL,LabelDecl * D,Stmt * substmt)1771 LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
1772 : ValueStmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) {
1773 setIdentLoc(IL);
1774 }
1775
1776 /// Build an empty label statement.
LabelStmt(EmptyShell Empty)1777 explicit LabelStmt(EmptyShell Empty) : ValueStmt(LabelStmtClass, Empty) {}
1778
getIdentLoc()1779 SourceLocation getIdentLoc() const { return LabelStmtBits.IdentLoc; }
setIdentLoc(SourceLocation L)1780 void setIdentLoc(SourceLocation L) { LabelStmtBits.IdentLoc = L; }
1781
getDecl()1782 LabelDecl *getDecl() const { return TheDecl; }
setDecl(LabelDecl * D)1783 void setDecl(LabelDecl *D) { TheDecl = D; }
1784
1785 const char *getName() const;
getSubStmt()1786 Stmt *getSubStmt() { return SubStmt; }
1787
getSubStmt()1788 const Stmt *getSubStmt() const { return SubStmt; }
setSubStmt(Stmt * SS)1789 void setSubStmt(Stmt *SS) { SubStmt = SS; }
1790
getBeginLoc()1791 SourceLocation getBeginLoc() const { return getIdentLoc(); }
getEndLoc()1792 SourceLocation getEndLoc() const LLVM_READONLY { return SubStmt->getEndLoc();}
1793
children()1794 child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
1795
children()1796 const_child_range children() const {
1797 return const_child_range(&SubStmt, &SubStmt + 1);
1798 }
1799
classof(const Stmt * T)1800 static bool classof(const Stmt *T) {
1801 return T->getStmtClass() == LabelStmtClass;
1802 }
1803 };
1804
1805 /// Represents an attribute applied to a statement.
1806 ///
1807 /// Represents an attribute applied to a statement. For example:
1808 /// [[omp::for(...)]] for (...) { ... }
1809 class AttributedStmt final
1810 : public ValueStmt,
1811 private llvm::TrailingObjects<AttributedStmt, const Attr *> {
1812 friend class ASTStmtReader;
1813 friend TrailingObjects;
1814
1815 Stmt *SubStmt;
1816
AttributedStmt(SourceLocation Loc,ArrayRef<const Attr * > Attrs,Stmt * SubStmt)1817 AttributedStmt(SourceLocation Loc, ArrayRef<const Attr *> Attrs,
1818 Stmt *SubStmt)
1819 : ValueStmt(AttributedStmtClass), SubStmt(SubStmt) {
1820 AttributedStmtBits.NumAttrs = Attrs.size();
1821 AttributedStmtBits.AttrLoc = Loc;
1822 std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr());
1823 }
1824
AttributedStmt(EmptyShell Empty,unsigned NumAttrs)1825 explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
1826 : ValueStmt(AttributedStmtClass, Empty) {
1827 AttributedStmtBits.NumAttrs = NumAttrs;
1828 AttributedStmtBits.AttrLoc = SourceLocation{};
1829 std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr);
1830 }
1831
getAttrArrayPtr()1832 const Attr *const *getAttrArrayPtr() const {
1833 return getTrailingObjects<const Attr *>();
1834 }
getAttrArrayPtr()1835 const Attr **getAttrArrayPtr() { return getTrailingObjects<const Attr *>(); }
1836
1837 public:
1838 static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
1839 ArrayRef<const Attr *> Attrs, Stmt *SubStmt);
1840
1841 // Build an empty attributed statement.
1842 static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);
1843
getAttrLoc()1844 SourceLocation getAttrLoc() const { return AttributedStmtBits.AttrLoc; }
getAttrs()1845 ArrayRef<const Attr *> getAttrs() const {
1846 return llvm::makeArrayRef(getAttrArrayPtr(), AttributedStmtBits.NumAttrs);
1847 }
1848
getSubStmt()1849 Stmt *getSubStmt() { return SubStmt; }
getSubStmt()1850 const Stmt *getSubStmt() const { return SubStmt; }
1851
getBeginLoc()1852 SourceLocation getBeginLoc() const { return getAttrLoc(); }
getEndLoc()1853 SourceLocation getEndLoc() const LLVM_READONLY { return SubStmt->getEndLoc();}
1854
children()1855 child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
1856
children()1857 const_child_range children() const {
1858 return const_child_range(&SubStmt, &SubStmt + 1);
1859 }
1860
classof(const Stmt * T)1861 static bool classof(const Stmt *T) {
1862 return T->getStmtClass() == AttributedStmtClass;
1863 }
1864 };
1865
1866 /// IfStmt - This represents an if/then/else.
1867 class IfStmt final
1868 : public Stmt,
1869 private llvm::TrailingObjects<IfStmt, Stmt *, SourceLocation> {
1870 friend TrailingObjects;
1871
1872 // IfStmt is followed by several trailing objects, some of which optional.
1873 // Note that it would be more convenient to put the optional trailing
1874 // objects at then end but this would change the order of the children.
1875 // The trailing objects are in order:
1876 //
1877 // * A "Stmt *" for the init statement.
1878 // Present if and only if hasInitStorage().
1879 //
1880 // * A "Stmt *" for the condition variable.
1881 // Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
1882 //
1883 // * A "Stmt *" for the condition.
1884 // Always present. This is in fact a "Expr *".
1885 //
1886 // * A "Stmt *" for the then statement.
1887 // Always present.
1888 //
1889 // * A "Stmt *" for the else statement.
1890 // Present if and only if hasElseStorage().
1891 //
1892 // * A "SourceLocation" for the location of the "else".
1893 // Present if and only if hasElseStorage().
1894 enum { InitOffset = 0, ThenOffsetFromCond = 1, ElseOffsetFromCond = 2 };
1895 enum { NumMandatoryStmtPtr = 2 };
1896
numTrailingObjects(OverloadToken<Stmt * >)1897 unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
1898 return NumMandatoryStmtPtr + hasElseStorage() + hasVarStorage() +
1899 hasInitStorage();
1900 }
1901
numTrailingObjects(OverloadToken<SourceLocation>)1902 unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
1903 return hasElseStorage();
1904 }
1905
initOffset()1906 unsigned initOffset() const { return InitOffset; }
varOffset()1907 unsigned varOffset() const { return InitOffset + hasInitStorage(); }
condOffset()1908 unsigned condOffset() const {
1909 return InitOffset + hasInitStorage() + hasVarStorage();
1910 }
thenOffset()1911 unsigned thenOffset() const { return condOffset() + ThenOffsetFromCond; }
elseOffset()1912 unsigned elseOffset() const { return condOffset() + ElseOffsetFromCond; }
1913
1914 /// Build an if/then/else statement.
1915 IfStmt(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr, Stmt *Init,
1916 VarDecl *Var, Expr *Cond, Stmt *Then, SourceLocation EL, Stmt *Else);
1917
1918 /// Build an empty if/then/else statement.
1919 explicit IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit);
1920
1921 public:
1922 /// Create an IfStmt.
1923 static IfStmt *Create(const ASTContext &Ctx, SourceLocation IL,
1924 bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond,
1925 Stmt *Then, SourceLocation EL = SourceLocation(),
1926 Stmt *Else = nullptr);
1927
1928 /// Create an empty IfStmt optionally with storage for an else statement,
1929 /// condition variable and init expression.
1930 static IfStmt *CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar,
1931 bool HasInit);
1932
1933 /// True if this IfStmt has the storage for an init statement.
hasInitStorage()1934 bool hasInitStorage() const { return IfStmtBits.HasInit; }
1935
1936 /// True if this IfStmt has storage for a variable declaration.
hasVarStorage()1937 bool hasVarStorage() const { return IfStmtBits.HasVar; }
1938
1939 /// True if this IfStmt has storage for an else statement.
hasElseStorage()1940 bool hasElseStorage() const { return IfStmtBits.HasElse; }
1941
getCond()1942 Expr *getCond() {
1943 return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
1944 }
1945
getCond()1946 const Expr *getCond() const {
1947 return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
1948 }
1949
setCond(Expr * Cond)1950 void setCond(Expr *Cond) {
1951 getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
1952 }
1953
getThen()1954 Stmt *getThen() { return getTrailingObjects<Stmt *>()[thenOffset()]; }
getThen()1955 const Stmt *getThen() const {
1956 return getTrailingObjects<Stmt *>()[thenOffset()];
1957 }
1958
setThen(Stmt * Then)1959 void setThen(Stmt *Then) {
1960 getTrailingObjects<Stmt *>()[thenOffset()] = Then;
1961 }
1962
getElse()1963 Stmt *getElse() {
1964 return hasElseStorage() ? getTrailingObjects<Stmt *>()[elseOffset()]
1965 : nullptr;
1966 }
1967
getElse()1968 const Stmt *getElse() const {
1969 return hasElseStorage() ? getTrailingObjects<Stmt *>()[elseOffset()]
1970 : nullptr;
1971 }
1972
setElse(Stmt * Else)1973 void setElse(Stmt *Else) {
1974 assert(hasElseStorage() &&
1975 "This if statement has no storage for an else statement!");
1976 getTrailingObjects<Stmt *>()[elseOffset()] = Else;
1977 }
1978
1979 /// Retrieve the variable declared in this "if" statement, if any.
1980 ///
1981 /// In the following example, "x" is the condition variable.
1982 /// \code
1983 /// if (int x = foo()) {
1984 /// printf("x is %d", x);
1985 /// }
1986 /// \endcode
1987 VarDecl *getConditionVariable();
getConditionVariable()1988 const VarDecl *getConditionVariable() const {
1989 return const_cast<IfStmt *>(this)->getConditionVariable();
1990 }
1991
1992 /// Set the condition variable for this if statement.
1993 /// The if statement must have storage for the condition variable.
1994 void setConditionVariable(const ASTContext &Ctx, VarDecl *V);
1995
1996 /// If this IfStmt has a condition variable, return the faux DeclStmt
1997 /// associated with the creation of that condition variable.
getConditionVariableDeclStmt()1998 DeclStmt *getConditionVariableDeclStmt() {
1999 return hasVarStorage() ? static_cast<DeclStmt *>(
2000 getTrailingObjects<Stmt *>()[varOffset()])
2001 : nullptr;
2002 }
2003
getConditionVariableDeclStmt()2004 const DeclStmt *getConditionVariableDeclStmt() const {
2005 return hasVarStorage() ? static_cast<DeclStmt *>(
2006 getTrailingObjects<Stmt *>()[varOffset()])
2007 : nullptr;
2008 }
2009
getInit()2010 Stmt *getInit() {
2011 return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
2012 : nullptr;
2013 }
2014
getInit()2015 const Stmt *getInit() const {
2016 return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
2017 : nullptr;
2018 }
2019
setInit(Stmt * Init)2020 void setInit(Stmt *Init) {
2021 assert(hasInitStorage() &&
2022 "This if statement has no storage for an init statement!");
2023 getTrailingObjects<Stmt *>()[initOffset()] = Init;
2024 }
2025
getIfLoc()2026 SourceLocation getIfLoc() const { return IfStmtBits.IfLoc; }
setIfLoc(SourceLocation IfLoc)2027 void setIfLoc(SourceLocation IfLoc) { IfStmtBits.IfLoc = IfLoc; }
2028
getElseLoc()2029 SourceLocation getElseLoc() const {
2030 return hasElseStorage() ? *getTrailingObjects<SourceLocation>()
2031 : SourceLocation();
2032 }
2033
setElseLoc(SourceLocation ElseLoc)2034 void setElseLoc(SourceLocation ElseLoc) {
2035 assert(hasElseStorage() &&
2036 "This if statement has no storage for an else statement!");
2037 *getTrailingObjects<SourceLocation>() = ElseLoc;
2038 }
2039
isConstexpr()2040 bool isConstexpr() const { return IfStmtBits.IsConstexpr; }
setConstexpr(bool C)2041 void setConstexpr(bool C) { IfStmtBits.IsConstexpr = C; }
2042
2043 /// If this is an 'if constexpr', determine which substatement will be taken.
2044 /// Otherwise, or if the condition is value-dependent, returns None.
2045 Optional<const Stmt*> getNondiscardedCase(const ASTContext &Ctx) const;
2046
2047 bool isObjCAvailabilityCheck() const;
2048
getBeginLoc()2049 SourceLocation getBeginLoc() const { return getIfLoc(); }
getEndLoc()2050 SourceLocation getEndLoc() const LLVM_READONLY {
2051 if (getElse())
2052 return getElse()->getEndLoc();
2053 return getThen()->getEndLoc();
2054 }
2055
2056 // Iterators over subexpressions. The iterators will include iterating
2057 // over the initialization expression referenced by the condition variable.
children()2058 child_range children() {
2059 return child_range(getTrailingObjects<Stmt *>(),
2060 getTrailingObjects<Stmt *>() +
2061 numTrailingObjects(OverloadToken<Stmt *>()));
2062 }
2063
children()2064 const_child_range children() const {
2065 return const_child_range(getTrailingObjects<Stmt *>(),
2066 getTrailingObjects<Stmt *>() +
2067 numTrailingObjects(OverloadToken<Stmt *>()));
2068 }
2069
classof(const Stmt * T)2070 static bool classof(const Stmt *T) {
2071 return T->getStmtClass() == IfStmtClass;
2072 }
2073 };
2074
2075 /// SwitchStmt - This represents a 'switch' stmt.
2076 class SwitchStmt final : public Stmt,
2077 private llvm::TrailingObjects<SwitchStmt, Stmt *> {
2078 friend TrailingObjects;
2079
2080 /// Points to a linked list of case and default statements.
2081 SwitchCase *FirstCase;
2082
2083 // SwitchStmt is followed by several trailing objects,
2084 // some of which optional. Note that it would be more convenient to
2085 // put the optional trailing objects at the end but this would change
2086 // the order in children().
2087 // The trailing objects are in order:
2088 //
2089 // * A "Stmt *" for the init statement.
2090 // Present if and only if hasInitStorage().
2091 //
2092 // * A "Stmt *" for the condition variable.
2093 // Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
2094 //
2095 // * A "Stmt *" for the condition.
2096 // Always present. This is in fact an "Expr *".
2097 //
2098 // * A "Stmt *" for the body.
2099 // Always present.
2100 enum { InitOffset = 0, BodyOffsetFromCond = 1 };
2101 enum { NumMandatoryStmtPtr = 2 };
2102
numTrailingObjects(OverloadToken<Stmt * >)2103 unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
2104 return NumMandatoryStmtPtr + hasInitStorage() + hasVarStorage();
2105 }
2106
initOffset()2107 unsigned initOffset() const { return InitOffset; }
varOffset()2108 unsigned varOffset() const { return InitOffset + hasInitStorage(); }
condOffset()2109 unsigned condOffset() const {
2110 return InitOffset + hasInitStorage() + hasVarStorage();
2111 }
bodyOffset()2112 unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }
2113
2114 /// Build a switch statement.
2115 SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond);
2116
2117 /// Build a empty switch statement.
2118 explicit SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar);
2119
2120 public:
2121 /// Create a switch statement.
2122 static SwitchStmt *Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
2123 Expr *Cond);
2124
2125 /// Create an empty switch statement optionally with storage for
2126 /// an init expression and a condition variable.
2127 static SwitchStmt *CreateEmpty(const ASTContext &Ctx, bool HasInit,
2128 bool HasVar);
2129
2130 /// True if this SwitchStmt has storage for an init statement.
hasInitStorage()2131 bool hasInitStorage() const { return SwitchStmtBits.HasInit; }
2132
2133 /// True if this SwitchStmt has storage for a condition variable.
hasVarStorage()2134 bool hasVarStorage() const { return SwitchStmtBits.HasVar; }
2135
getCond()2136 Expr *getCond() {
2137 return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
2138 }
2139
getCond()2140 const Expr *getCond() const {
2141 return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
2142 }
2143
setCond(Expr * Cond)2144 void setCond(Expr *Cond) {
2145 getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
2146 }
2147
getBody()2148 Stmt *getBody() { return getTrailingObjects<Stmt *>()[bodyOffset()]; }
getBody()2149 const Stmt *getBody() const {
2150 return getTrailingObjects<Stmt *>()[bodyOffset()];
2151 }
2152
setBody(Stmt * Body)2153 void setBody(Stmt *Body) {
2154 getTrailingObjects<Stmt *>()[bodyOffset()] = Body;
2155 }
2156
getInit()2157 Stmt *getInit() {
2158 return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
2159 : nullptr;
2160 }
2161
getInit()2162 const Stmt *getInit() const {
2163 return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
2164 : nullptr;
2165 }
2166
setInit(Stmt * Init)2167 void setInit(Stmt *Init) {
2168 assert(hasInitStorage() &&
2169 "This switch statement has no storage for an init statement!");
2170 getTrailingObjects<Stmt *>()[initOffset()] = Init;
2171 }
2172
2173 /// Retrieve the variable declared in this "switch" statement, if any.
2174 ///
2175 /// In the following example, "x" is the condition variable.
2176 /// \code
2177 /// switch (int x = foo()) {
2178 /// case 0: break;
2179 /// // ...
2180 /// }
2181 /// \endcode
2182 VarDecl *getConditionVariable();
getConditionVariable()2183 const VarDecl *getConditionVariable() const {
2184 return const_cast<SwitchStmt *>(this)->getConditionVariable();
2185 }
2186
2187 /// Set the condition variable in this switch statement.
2188 /// The switch statement must have storage for it.
2189 void setConditionVariable(const ASTContext &Ctx, VarDecl *VD);
2190
2191 /// If this SwitchStmt has a condition variable, return the faux DeclStmt
2192 /// associated with the creation of that condition variable.
getConditionVariableDeclStmt()2193 DeclStmt *getConditionVariableDeclStmt() {
2194 return hasVarStorage() ? static_cast<DeclStmt *>(
2195 getTrailingObjects<Stmt *>()[varOffset()])
2196 : nullptr;
2197 }
2198
getConditionVariableDeclStmt()2199 const DeclStmt *getConditionVariableDeclStmt() const {
2200 return hasVarStorage() ? static_cast<DeclStmt *>(
2201 getTrailingObjects<Stmt *>()[varOffset()])
2202 : nullptr;
2203 }
2204
getSwitchCaseList()2205 SwitchCase *getSwitchCaseList() { return FirstCase; }
getSwitchCaseList()2206 const SwitchCase *getSwitchCaseList() const { return FirstCase; }
setSwitchCaseList(SwitchCase * SC)2207 void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
2208
getSwitchLoc()2209 SourceLocation getSwitchLoc() const { return SwitchStmtBits.SwitchLoc; }
setSwitchLoc(SourceLocation L)2210 void setSwitchLoc(SourceLocation L) { SwitchStmtBits.SwitchLoc = L; }
2211
setBody(Stmt * S,SourceLocation SL)2212 void setBody(Stmt *S, SourceLocation SL) {
2213 setBody(S);
2214 setSwitchLoc(SL);
2215 }
2216
addSwitchCase(SwitchCase * SC)2217 void addSwitchCase(SwitchCase *SC) {
2218 assert(!SC->getNextSwitchCase() &&
2219 "case/default already added to a switch");
2220 SC->setNextSwitchCase(FirstCase);
2221 FirstCase = SC;
2222 }
2223
2224 /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
2225 /// switch over an enum value then all cases have been explicitly covered.
setAllEnumCasesCovered()2226 void setAllEnumCasesCovered() { SwitchStmtBits.AllEnumCasesCovered = true; }
2227
2228 /// Returns true if the SwitchStmt is a switch of an enum value and all cases
2229 /// have been explicitly covered.
isAllEnumCasesCovered()2230 bool isAllEnumCasesCovered() const {
2231 return SwitchStmtBits.AllEnumCasesCovered;
2232 }
2233
getBeginLoc()2234 SourceLocation getBeginLoc() const { return getSwitchLoc(); }
getEndLoc()2235 SourceLocation getEndLoc() const LLVM_READONLY {
2236 return getBody() ? getBody()->getEndLoc()
2237 : reinterpret_cast<const Stmt *>(getCond())->getEndLoc();
2238 }
2239
2240 // Iterators
children()2241 child_range children() {
2242 return child_range(getTrailingObjects<Stmt *>(),
2243 getTrailingObjects<Stmt *>() +
2244 numTrailingObjects(OverloadToken<Stmt *>()));
2245 }
2246
children()2247 const_child_range children() const {
2248 return const_child_range(getTrailingObjects<Stmt *>(),
2249 getTrailingObjects<Stmt *>() +
2250 numTrailingObjects(OverloadToken<Stmt *>()));
2251 }
2252
classof(const Stmt * T)2253 static bool classof(const Stmt *T) {
2254 return T->getStmtClass() == SwitchStmtClass;
2255 }
2256 };
2257
2258 /// WhileStmt - This represents a 'while' stmt.
2259 class WhileStmt final : public Stmt,
2260 private llvm::TrailingObjects<WhileStmt, Stmt *> {
2261 friend TrailingObjects;
2262
2263 // WhileStmt is followed by several trailing objects,
2264 // some of which optional. Note that it would be more
2265 // convenient to put the optional trailing object at the end
2266 // but this would affect children().
2267 // The trailing objects are in order:
2268 //
2269 // * A "Stmt *" for the condition variable.
2270 // Present if and only if hasVarStorage(). This is in fact a "DeclStmt *".
2271 //
2272 // * A "Stmt *" for the condition.
2273 // Always present. This is in fact an "Expr *".
2274 //
2275 // * A "Stmt *" for the body.
2276 // Always present.
2277 //
2278 enum { VarOffset = 0, BodyOffsetFromCond = 1 };
2279 enum { NumMandatoryStmtPtr = 2 };
2280
2281 SourceLocation LParenLoc, RParenLoc;
2282
varOffset()2283 unsigned varOffset() const { return VarOffset; }
condOffset()2284 unsigned condOffset() const { return VarOffset + hasVarStorage(); }
bodyOffset()2285 unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }
2286
numTrailingObjects(OverloadToken<Stmt * >)2287 unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
2288 return NumMandatoryStmtPtr + hasVarStorage();
2289 }
2290
2291 /// Build a while statement.
2292 WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body,
2293 SourceLocation WL, SourceLocation LParenLoc,
2294 SourceLocation RParenLoc);
2295
2296 /// Build an empty while statement.
2297 explicit WhileStmt(EmptyShell Empty, bool HasVar);
2298
2299 public:
2300 /// Create a while statement.
2301 static WhileStmt *Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
2302 Stmt *Body, SourceLocation WL,
2303 SourceLocation LParenLoc, SourceLocation RParenLoc);
2304
2305 /// Create an empty while statement optionally with storage for
2306 /// a condition variable.
2307 static WhileStmt *CreateEmpty(const ASTContext &Ctx, bool HasVar);
2308
2309 /// True if this WhileStmt has storage for a condition variable.
hasVarStorage()2310 bool hasVarStorage() const { return WhileStmtBits.HasVar; }
2311
getCond()2312 Expr *getCond() {
2313 return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
2314 }
2315
getCond()2316 const Expr *getCond() const {
2317 return reinterpret_cast<Expr *>(getTrailingObjects<Stmt *>()[condOffset()]);
2318 }
2319
setCond(Expr * Cond)2320 void setCond(Expr *Cond) {
2321 getTrailingObjects<Stmt *>()[condOffset()] = reinterpret_cast<Stmt *>(Cond);
2322 }
2323
getBody()2324 Stmt *getBody() { return getTrailingObjects<Stmt *>()[bodyOffset()]; }
getBody()2325 const Stmt *getBody() const {
2326 return getTrailingObjects<Stmt *>()[bodyOffset()];
2327 }
2328
setBody(Stmt * Body)2329 void setBody(Stmt *Body) {
2330 getTrailingObjects<Stmt *>()[bodyOffset()] = Body;
2331 }
2332
2333 /// Retrieve the variable declared in this "while" statement, if any.
2334 ///
2335 /// In the following example, "x" is the condition variable.
2336 /// \code
2337 /// while (int x = random()) {
2338 /// // ...
2339 /// }
2340 /// \endcode
2341 VarDecl *getConditionVariable();
getConditionVariable()2342 const VarDecl *getConditionVariable() const {
2343 return const_cast<WhileStmt *>(this)->getConditionVariable();
2344 }
2345
2346 /// Set the condition variable of this while statement.
2347 /// The while statement must have storage for it.
2348 void setConditionVariable(const ASTContext &Ctx, VarDecl *V);
2349
2350 /// If this WhileStmt has a condition variable, return the faux DeclStmt
2351 /// associated with the creation of that condition variable.
getConditionVariableDeclStmt()2352 DeclStmt *getConditionVariableDeclStmt() {
2353 return hasVarStorage() ? static_cast<DeclStmt *>(
2354 getTrailingObjects<Stmt *>()[varOffset()])
2355 : nullptr;
2356 }
2357
getConditionVariableDeclStmt()2358 const DeclStmt *getConditionVariableDeclStmt() const {
2359 return hasVarStorage() ? static_cast<DeclStmt *>(
2360 getTrailingObjects<Stmt *>()[varOffset()])
2361 : nullptr;
2362 }
2363
getWhileLoc()2364 SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; }
setWhileLoc(SourceLocation L)2365 void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; }
2366
getLParenLoc()2367 SourceLocation getLParenLoc() const { return LParenLoc; }
setLParenLoc(SourceLocation L)2368 void setLParenLoc(SourceLocation L) { LParenLoc = L; }
getRParenLoc()2369 SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)2370 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
2371
getBeginLoc()2372 SourceLocation getBeginLoc() const { return getWhileLoc(); }
getEndLoc()2373 SourceLocation getEndLoc() const LLVM_READONLY {
2374 return getBody()->getEndLoc();
2375 }
2376
classof(const Stmt * T)2377 static bool classof(const Stmt *T) {
2378 return T->getStmtClass() == WhileStmtClass;
2379 }
2380
2381 // Iterators
children()2382 child_range children() {
2383 return child_range(getTrailingObjects<Stmt *>(),
2384 getTrailingObjects<Stmt *>() +
2385 numTrailingObjects(OverloadToken<Stmt *>()));
2386 }
2387
children()2388 const_child_range children() const {
2389 return const_child_range(getTrailingObjects<Stmt *>(),
2390 getTrailingObjects<Stmt *>() +
2391 numTrailingObjects(OverloadToken<Stmt *>()));
2392 }
2393 };
2394
2395 /// DoStmt - This represents a 'do/while' stmt.
2396 class DoStmt : public Stmt {
2397 enum { BODY, COND, END_EXPR };
2398 Stmt *SubExprs[END_EXPR];
2399 SourceLocation WhileLoc;
2400 SourceLocation RParenLoc; // Location of final ')' in do stmt condition.
2401
2402 public:
DoStmt(Stmt * Body,Expr * Cond,SourceLocation DL,SourceLocation WL,SourceLocation RP)2403 DoStmt(Stmt *Body, Expr *Cond, SourceLocation DL, SourceLocation WL,
2404 SourceLocation RP)
2405 : Stmt(DoStmtClass), WhileLoc(WL), RParenLoc(RP) {
2406 setCond(Cond);
2407 setBody(Body);
2408 setDoLoc(DL);
2409 }
2410
2411 /// Build an empty do-while statement.
DoStmt(EmptyShell Empty)2412 explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) {}
2413
getCond()2414 Expr *getCond() { return reinterpret_cast<Expr *>(SubExprs[COND]); }
getCond()2415 const Expr *getCond() const {
2416 return reinterpret_cast<Expr *>(SubExprs[COND]);
2417 }
2418
setCond(Expr * Cond)2419 void setCond(Expr *Cond) { SubExprs[COND] = reinterpret_cast<Stmt *>(Cond); }
2420
getBody()2421 Stmt *getBody() { return SubExprs[BODY]; }
getBody()2422 const Stmt *getBody() const { return SubExprs[BODY]; }
setBody(Stmt * Body)2423 void setBody(Stmt *Body) { SubExprs[BODY] = Body; }
2424
getDoLoc()2425 SourceLocation getDoLoc() const { return DoStmtBits.DoLoc; }
setDoLoc(SourceLocation L)2426 void setDoLoc(SourceLocation L) { DoStmtBits.DoLoc = L; }
getWhileLoc()2427 SourceLocation getWhileLoc() const { return WhileLoc; }
setWhileLoc(SourceLocation L)2428 void setWhileLoc(SourceLocation L) { WhileLoc = L; }
getRParenLoc()2429 SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)2430 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
2431
getBeginLoc()2432 SourceLocation getBeginLoc() const { return getDoLoc(); }
getEndLoc()2433 SourceLocation getEndLoc() const { return getRParenLoc(); }
2434
classof(const Stmt * T)2435 static bool classof(const Stmt *T) {
2436 return T->getStmtClass() == DoStmtClass;
2437 }
2438
2439 // Iterators
children()2440 child_range children() {
2441 return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
2442 }
2443
children()2444 const_child_range children() const {
2445 return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
2446 }
2447 };
2448
2449 /// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of
2450 /// the init/cond/inc parts of the ForStmt will be null if they were not
2451 /// specified in the source.
2452 class ForStmt : public Stmt {
2453 enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
2454 Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
2455 SourceLocation LParenLoc, RParenLoc;
2456
2457 public:
2458 ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
2459 Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
2460 SourceLocation RP);
2461
2462 /// Build an empty for statement.
ForStmt(EmptyShell Empty)2463 explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) {}
2464
getInit()2465 Stmt *getInit() { return SubExprs[INIT]; }
2466
2467 /// Retrieve the variable declared in this "for" statement, if any.
2468 ///
2469 /// In the following example, "y" is the condition variable.
2470 /// \code
2471 /// for (int x = random(); int y = mangle(x); ++x) {
2472 /// // ...
2473 /// }
2474 /// \endcode
2475 VarDecl *getConditionVariable() const;
2476 void setConditionVariable(const ASTContext &C, VarDecl *V);
2477
2478 /// If this ForStmt has a condition variable, return the faux DeclStmt
2479 /// associated with the creation of that condition variable.
getConditionVariableDeclStmt()2480 const DeclStmt *getConditionVariableDeclStmt() const {
2481 return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
2482 }
2483
getCond()2484 Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
getInc()2485 Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
getBody()2486 Stmt *getBody() { return SubExprs[BODY]; }
2487
getInit()2488 const Stmt *getInit() const { return SubExprs[INIT]; }
getCond()2489 const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
getInc()2490 const Expr *getInc() const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
getBody()2491 const Stmt *getBody() const { return SubExprs[BODY]; }
2492
setInit(Stmt * S)2493 void setInit(Stmt *S) { SubExprs[INIT] = S; }
setCond(Expr * E)2494 void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
setInc(Expr * E)2495 void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
setBody(Stmt * S)2496 void setBody(Stmt *S) { SubExprs[BODY] = S; }
2497
getForLoc()2498 SourceLocation getForLoc() const { return ForStmtBits.ForLoc; }
setForLoc(SourceLocation L)2499 void setForLoc(SourceLocation L) { ForStmtBits.ForLoc = L; }
getLParenLoc()2500 SourceLocation getLParenLoc() const { return LParenLoc; }
setLParenLoc(SourceLocation L)2501 void setLParenLoc(SourceLocation L) { LParenLoc = L; }
getRParenLoc()2502 SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)2503 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
2504
getBeginLoc()2505 SourceLocation getBeginLoc() const { return getForLoc(); }
getEndLoc()2506 SourceLocation getEndLoc() const { return getBody()->getEndLoc(); }
2507
classof(const Stmt * T)2508 static bool classof(const Stmt *T) {
2509 return T->getStmtClass() == ForStmtClass;
2510 }
2511
2512 // Iterators
children()2513 child_range children() {
2514 return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
2515 }
2516
children()2517 const_child_range children() const {
2518 return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
2519 }
2520 };
2521
2522 /// GotoStmt - This represents a direct goto.
2523 class GotoStmt : public Stmt {
2524 LabelDecl *Label;
2525 SourceLocation LabelLoc;
2526
2527 public:
GotoStmt(LabelDecl * label,SourceLocation GL,SourceLocation LL)2528 GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL)
2529 : Stmt(GotoStmtClass), Label(label), LabelLoc(LL) {
2530 setGotoLoc(GL);
2531 }
2532
2533 /// Build an empty goto statement.
GotoStmt(EmptyShell Empty)2534 explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) {}
2535
getLabel()2536 LabelDecl *getLabel() const { return Label; }
setLabel(LabelDecl * D)2537 void setLabel(LabelDecl *D) { Label = D; }
2538
getGotoLoc()2539 SourceLocation getGotoLoc() const { return GotoStmtBits.GotoLoc; }
setGotoLoc(SourceLocation L)2540 void setGotoLoc(SourceLocation L) { GotoStmtBits.GotoLoc = L; }
getLabelLoc()2541 SourceLocation getLabelLoc() const { return LabelLoc; }
setLabelLoc(SourceLocation L)2542 void setLabelLoc(SourceLocation L) { LabelLoc = L; }
2543
getBeginLoc()2544 SourceLocation getBeginLoc() const { return getGotoLoc(); }
getEndLoc()2545 SourceLocation getEndLoc() const { return getLabelLoc(); }
2546
classof(const Stmt * T)2547 static bool classof(const Stmt *T) {
2548 return T->getStmtClass() == GotoStmtClass;
2549 }
2550
2551 // Iterators
children()2552 child_range children() {
2553 return child_range(child_iterator(), child_iterator());
2554 }
2555
children()2556 const_child_range children() const {
2557 return const_child_range(const_child_iterator(), const_child_iterator());
2558 }
2559 };
2560
2561 /// IndirectGotoStmt - This represents an indirect goto.
2562 class IndirectGotoStmt : public Stmt {
2563 SourceLocation StarLoc;
2564 Stmt *Target;
2565
2566 public:
IndirectGotoStmt(SourceLocation gotoLoc,SourceLocation starLoc,Expr * target)2567 IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc, Expr *target)
2568 : Stmt(IndirectGotoStmtClass), StarLoc(starLoc) {
2569 setTarget(target);
2570 setGotoLoc(gotoLoc);
2571 }
2572
2573 /// Build an empty indirect goto statement.
IndirectGotoStmt(EmptyShell Empty)2574 explicit IndirectGotoStmt(EmptyShell Empty)
2575 : Stmt(IndirectGotoStmtClass, Empty) {}
2576
setGotoLoc(SourceLocation L)2577 void setGotoLoc(SourceLocation L) { GotoStmtBits.GotoLoc = L; }
getGotoLoc()2578 SourceLocation getGotoLoc() const { return GotoStmtBits.GotoLoc; }
setStarLoc(SourceLocation L)2579 void setStarLoc(SourceLocation L) { StarLoc = L; }
getStarLoc()2580 SourceLocation getStarLoc() const { return StarLoc; }
2581
getTarget()2582 Expr *getTarget() { return reinterpret_cast<Expr *>(Target); }
getTarget()2583 const Expr *getTarget() const {
2584 return reinterpret_cast<const Expr *>(Target);
2585 }
setTarget(Expr * E)2586 void setTarget(Expr *E) { Target = reinterpret_cast<Stmt *>(E); }
2587
2588 /// getConstantTarget - Returns the fixed target of this indirect
2589 /// goto, if one exists.
2590 LabelDecl *getConstantTarget();
getConstantTarget()2591 const LabelDecl *getConstantTarget() const {
2592 return const_cast<IndirectGotoStmt *>(this)->getConstantTarget();
2593 }
2594
getBeginLoc()2595 SourceLocation getBeginLoc() const { return getGotoLoc(); }
getEndLoc()2596 SourceLocation getEndLoc() const LLVM_READONLY { return Target->getEndLoc(); }
2597
classof(const Stmt * T)2598 static bool classof(const Stmt *T) {
2599 return T->getStmtClass() == IndirectGotoStmtClass;
2600 }
2601
2602 // Iterators
children()2603 child_range children() { return child_range(&Target, &Target + 1); }
2604
children()2605 const_child_range children() const {
2606 return const_child_range(&Target, &Target + 1);
2607 }
2608 };
2609
2610 /// ContinueStmt - This represents a continue.
2611 class ContinueStmt : public Stmt {
2612 public:
ContinueStmt(SourceLocation CL)2613 ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass) {
2614 setContinueLoc(CL);
2615 }
2616
2617 /// Build an empty continue statement.
ContinueStmt(EmptyShell Empty)2618 explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) {}
2619
getContinueLoc()2620 SourceLocation getContinueLoc() const { return ContinueStmtBits.ContinueLoc; }
setContinueLoc(SourceLocation L)2621 void setContinueLoc(SourceLocation L) { ContinueStmtBits.ContinueLoc = L; }
2622
getBeginLoc()2623 SourceLocation getBeginLoc() const { return getContinueLoc(); }
getEndLoc()2624 SourceLocation getEndLoc() const { return getContinueLoc(); }
2625
classof(const Stmt * T)2626 static bool classof(const Stmt *T) {
2627 return T->getStmtClass() == ContinueStmtClass;
2628 }
2629
2630 // Iterators
children()2631 child_range children() {
2632 return child_range(child_iterator(), child_iterator());
2633 }
2634
children()2635 const_child_range children() const {
2636 return const_child_range(const_child_iterator(), const_child_iterator());
2637 }
2638 };
2639
2640 /// BreakStmt - This represents a break.
2641 class BreakStmt : public Stmt {
2642 public:
BreakStmt(SourceLocation BL)2643 BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass) {
2644 setBreakLoc(BL);
2645 }
2646
2647 /// Build an empty break statement.
BreakStmt(EmptyShell Empty)2648 explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) {}
2649
getBreakLoc()2650 SourceLocation getBreakLoc() const { return BreakStmtBits.BreakLoc; }
setBreakLoc(SourceLocation L)2651 void setBreakLoc(SourceLocation L) { BreakStmtBits.BreakLoc = L; }
2652
getBeginLoc()2653 SourceLocation getBeginLoc() const { return getBreakLoc(); }
getEndLoc()2654 SourceLocation getEndLoc() const { return getBreakLoc(); }
2655
classof(const Stmt * T)2656 static bool classof(const Stmt *T) {
2657 return T->getStmtClass() == BreakStmtClass;
2658 }
2659
2660 // Iterators
children()2661 child_range children() {
2662 return child_range(child_iterator(), child_iterator());
2663 }
2664
children()2665 const_child_range children() const {
2666 return const_child_range(const_child_iterator(), const_child_iterator());
2667 }
2668 };
2669
2670 /// ReturnStmt - This represents a return, optionally of an expression:
2671 /// return;
2672 /// return 4;
2673 ///
2674 /// Note that GCC allows return with no argument in a function declared to
2675 /// return a value, and it allows returning a value in functions declared to
2676 /// return void. We explicitly model this in the AST, which means you can't
2677 /// depend on the return type of the function and the presence of an argument.
2678 class ReturnStmt final
2679 : public Stmt,
2680 private llvm::TrailingObjects<ReturnStmt, const VarDecl *> {
2681 friend TrailingObjects;
2682
2683 /// The return expression.
2684 Stmt *RetExpr;
2685
2686 // ReturnStmt is followed optionally by a trailing "const VarDecl *"
2687 // for the NRVO candidate. Present if and only if hasNRVOCandidate().
2688
2689 /// True if this ReturnStmt has storage for an NRVO candidate.
hasNRVOCandidate()2690 bool hasNRVOCandidate() const { return ReturnStmtBits.HasNRVOCandidate; }
2691
numTrailingObjects(OverloadToken<const VarDecl * >)2692 unsigned numTrailingObjects(OverloadToken<const VarDecl *>) const {
2693 return hasNRVOCandidate();
2694 }
2695
2696 /// Build a return statement.
2697 ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate);
2698
2699 /// Build an empty return statement.
2700 explicit ReturnStmt(EmptyShell Empty, bool HasNRVOCandidate);
2701
2702 public:
2703 /// Create a return statement.
2704 static ReturnStmt *Create(const ASTContext &Ctx, SourceLocation RL, Expr *E,
2705 const VarDecl *NRVOCandidate);
2706
2707 /// Create an empty return statement, optionally with
2708 /// storage for an NRVO candidate.
2709 static ReturnStmt *CreateEmpty(const ASTContext &Ctx, bool HasNRVOCandidate);
2710
getRetValue()2711 Expr *getRetValue() { return reinterpret_cast<Expr *>(RetExpr); }
getRetValue()2712 const Expr *getRetValue() const { return reinterpret_cast<Expr *>(RetExpr); }
setRetValue(Expr * E)2713 void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt *>(E); }
2714
2715 /// Retrieve the variable that might be used for the named return
2716 /// value optimization.
2717 ///
2718 /// The optimization itself can only be performed if the variable is
2719 /// also marked as an NRVO object.
getNRVOCandidate()2720 const VarDecl *getNRVOCandidate() const {
2721 return hasNRVOCandidate() ? *getTrailingObjects<const VarDecl *>()
2722 : nullptr;
2723 }
2724
2725 /// Set the variable that might be used for the named return value
2726 /// optimization. The return statement must have storage for it,
2727 /// which is the case if and only if hasNRVOCandidate() is true.
setNRVOCandidate(const VarDecl * Var)2728 void setNRVOCandidate(const VarDecl *Var) {
2729 assert(hasNRVOCandidate() &&
2730 "This return statement has no storage for an NRVO candidate!");
2731 *getTrailingObjects<const VarDecl *>() = Var;
2732 }
2733
getReturnLoc()2734 SourceLocation getReturnLoc() const { return ReturnStmtBits.RetLoc; }
setReturnLoc(SourceLocation L)2735 void setReturnLoc(SourceLocation L) { ReturnStmtBits.RetLoc = L; }
2736
getBeginLoc()2737 SourceLocation getBeginLoc() const { return getReturnLoc(); }
getEndLoc()2738 SourceLocation getEndLoc() const LLVM_READONLY {
2739 return RetExpr ? RetExpr->getEndLoc() : getReturnLoc();
2740 }
2741
classof(const Stmt * T)2742 static bool classof(const Stmt *T) {
2743 return T->getStmtClass() == ReturnStmtClass;
2744 }
2745
2746 // Iterators
children()2747 child_range children() {
2748 if (RetExpr)
2749 return child_range(&RetExpr, &RetExpr + 1);
2750 return child_range(child_iterator(), child_iterator());
2751 }
2752
children()2753 const_child_range children() const {
2754 if (RetExpr)
2755 return const_child_range(&RetExpr, &RetExpr + 1);
2756 return const_child_range(const_child_iterator(), const_child_iterator());
2757 }
2758 };
2759
2760 /// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
2761 class AsmStmt : public Stmt {
2762 protected:
2763 friend class ASTStmtReader;
2764
2765 SourceLocation AsmLoc;
2766
2767 /// True if the assembly statement does not have any input or output
2768 /// operands.
2769 bool IsSimple;
2770
2771 /// If true, treat this inline assembly as having side effects.
2772 /// This assembly statement should not be optimized, deleted or moved.
2773 bool IsVolatile;
2774
2775 unsigned NumOutputs;
2776 unsigned NumInputs;
2777 unsigned NumClobbers;
2778
2779 Stmt **Exprs = nullptr;
2780
AsmStmt(StmtClass SC,SourceLocation asmloc,bool issimple,bool isvolatile,unsigned numoutputs,unsigned numinputs,unsigned numclobbers)2781 AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile,
2782 unsigned numoutputs, unsigned numinputs, unsigned numclobbers)
2783 : Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
2784 NumOutputs(numoutputs), NumInputs(numinputs),
2785 NumClobbers(numclobbers) {}
2786
2787 public:
2788 /// Build an empty inline-assembly statement.
AsmStmt(StmtClass SC,EmptyShell Empty)2789 explicit AsmStmt(StmtClass SC, EmptyShell Empty) : Stmt(SC, Empty) {}
2790
getAsmLoc()2791 SourceLocation getAsmLoc() const { return AsmLoc; }
setAsmLoc(SourceLocation L)2792 void setAsmLoc(SourceLocation L) { AsmLoc = L; }
2793
isSimple()2794 bool isSimple() const { return IsSimple; }
setSimple(bool V)2795 void setSimple(bool V) { IsSimple = V; }
2796
isVolatile()2797 bool isVolatile() const { return IsVolatile; }
setVolatile(bool V)2798 void setVolatile(bool V) { IsVolatile = V; }
2799
getBeginLoc()2800 SourceLocation getBeginLoc() const LLVM_READONLY { return {}; }
getEndLoc()2801 SourceLocation getEndLoc() const LLVM_READONLY { return {}; }
2802
2803 //===--- Asm String Analysis ---===//
2804
2805 /// Assemble final IR asm string.
2806 std::string generateAsmString(const ASTContext &C) const;
2807
2808 //===--- Output operands ---===//
2809
getNumOutputs()2810 unsigned getNumOutputs() const { return NumOutputs; }
2811
2812 /// getOutputConstraint - Return the constraint string for the specified
2813 /// output operand. All output constraints are known to be non-empty (either
2814 /// '=' or '+').
2815 StringRef getOutputConstraint(unsigned i) const;
2816
2817 /// isOutputPlusConstraint - Return true if the specified output constraint
2818 /// is a "+" constraint (which is both an input and an output) or false if it
2819 /// is an "=" constraint (just an output).
isOutputPlusConstraint(unsigned i)2820 bool isOutputPlusConstraint(unsigned i) const {
2821 return getOutputConstraint(i)[0] == '+';
2822 }
2823
2824 const Expr *getOutputExpr(unsigned i) const;
2825
2826 /// getNumPlusOperands - Return the number of output operands that have a "+"
2827 /// constraint.
2828 unsigned getNumPlusOperands() const;
2829
2830 //===--- Input operands ---===//
2831
getNumInputs()2832 unsigned getNumInputs() const { return NumInputs; }
2833
2834 /// getInputConstraint - Return the specified input constraint. Unlike output
2835 /// constraints, these can be empty.
2836 StringRef getInputConstraint(unsigned i) const;
2837
2838 const Expr *getInputExpr(unsigned i) const;
2839
2840 //===--- Other ---===//
2841
getNumClobbers()2842 unsigned getNumClobbers() const { return NumClobbers; }
2843 StringRef getClobber(unsigned i) const;
2844
classof(const Stmt * T)2845 static bool classof(const Stmt *T) {
2846 return T->getStmtClass() == GCCAsmStmtClass ||
2847 T->getStmtClass() == MSAsmStmtClass;
2848 }
2849
2850 // Input expr iterators.
2851
2852 using inputs_iterator = ExprIterator;
2853 using const_inputs_iterator = ConstExprIterator;
2854 using inputs_range = llvm::iterator_range<inputs_iterator>;
2855 using inputs_const_range = llvm::iterator_range<const_inputs_iterator>;
2856
begin_inputs()2857 inputs_iterator begin_inputs() {
2858 return &Exprs[0] + NumOutputs;
2859 }
2860
end_inputs()2861 inputs_iterator end_inputs() {
2862 return &Exprs[0] + NumOutputs + NumInputs;
2863 }
2864
inputs()2865 inputs_range inputs() { return inputs_range(begin_inputs(), end_inputs()); }
2866
begin_inputs()2867 const_inputs_iterator begin_inputs() const {
2868 return &Exprs[0] + NumOutputs;
2869 }
2870
end_inputs()2871 const_inputs_iterator end_inputs() const {
2872 return &Exprs[0] + NumOutputs + NumInputs;
2873 }
2874
inputs()2875 inputs_const_range inputs() const {
2876 return inputs_const_range(begin_inputs(), end_inputs());
2877 }
2878
2879 // Output expr iterators.
2880
2881 using outputs_iterator = ExprIterator;
2882 using const_outputs_iterator = ConstExprIterator;
2883 using outputs_range = llvm::iterator_range<outputs_iterator>;
2884 using outputs_const_range = llvm::iterator_range<const_outputs_iterator>;
2885
begin_outputs()2886 outputs_iterator begin_outputs() {
2887 return &Exprs[0];
2888 }
2889
end_outputs()2890 outputs_iterator end_outputs() {
2891 return &Exprs[0] + NumOutputs;
2892 }
2893
outputs()2894 outputs_range outputs() {
2895 return outputs_range(begin_outputs(), end_outputs());
2896 }
2897
begin_outputs()2898 const_outputs_iterator begin_outputs() const {
2899 return &Exprs[0];
2900 }
2901
end_outputs()2902 const_outputs_iterator end_outputs() const {
2903 return &Exprs[0] + NumOutputs;
2904 }
2905
outputs()2906 outputs_const_range outputs() const {
2907 return outputs_const_range(begin_outputs(), end_outputs());
2908 }
2909
children()2910 child_range children() {
2911 return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
2912 }
2913
children()2914 const_child_range children() const {
2915 return const_child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
2916 }
2917 };
2918
2919 /// This represents a GCC inline-assembly statement extension.
2920 class GCCAsmStmt : public AsmStmt {
2921 friend class ASTStmtReader;
2922
2923 SourceLocation RParenLoc;
2924 StringLiteral *AsmStr;
2925
2926 // FIXME: If we wanted to, we could allocate all of these in one big array.
2927 StringLiteral **Constraints = nullptr;
2928 StringLiteral **Clobbers = nullptr;
2929 IdentifierInfo **Names = nullptr;
2930 unsigned NumLabels = 0;
2931
2932 public:
2933 GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
2934 bool isvolatile, unsigned numoutputs, unsigned numinputs,
2935 IdentifierInfo **names, StringLiteral **constraints, Expr **exprs,
2936 StringLiteral *asmstr, unsigned numclobbers,
2937 StringLiteral **clobbers, unsigned numlabels,
2938 SourceLocation rparenloc);
2939
2940 /// Build an empty inline-assembly statement.
GCCAsmStmt(EmptyShell Empty)2941 explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty) {}
2942
getRParenLoc()2943 SourceLocation getRParenLoc() const { return RParenLoc; }
setRParenLoc(SourceLocation L)2944 void setRParenLoc(SourceLocation L) { RParenLoc = L; }
2945
2946 //===--- Asm String Analysis ---===//
2947
getAsmString()2948 const StringLiteral *getAsmString() const { return AsmStr; }
getAsmString()2949 StringLiteral *getAsmString() { return AsmStr; }
setAsmString(StringLiteral * E)2950 void setAsmString(StringLiteral *E) { AsmStr = E; }
2951
2952 /// AsmStringPiece - this is part of a decomposed asm string specification
2953 /// (for use with the AnalyzeAsmString function below). An asm string is
2954 /// considered to be a concatenation of these parts.
2955 class AsmStringPiece {
2956 public:
2957 enum Kind {
2958 String, // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
2959 Operand // Operand reference, with optional modifier %c4.
2960 };
2961
2962 private:
2963 Kind MyKind;
2964 std::string Str;
2965 unsigned OperandNo;
2966
2967 // Source range for operand references.
2968 CharSourceRange Range;
2969
2970 public:
AsmStringPiece(const std::string & S)2971 AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
AsmStringPiece(unsigned OpNo,const std::string & S,SourceLocation Begin,SourceLocation End)2972 AsmStringPiece(unsigned OpNo, const std::string &S, SourceLocation Begin,
2973 SourceLocation End)
2974 : MyKind(Operand), Str(S), OperandNo(OpNo),
2975 Range(CharSourceRange::getCharRange(Begin, End)) {}
2976
isString()2977 bool isString() const { return MyKind == String; }
isOperand()2978 bool isOperand() const { return MyKind == Operand; }
2979
getString()2980 const std::string &getString() const { return Str; }
2981
getOperandNo()2982 unsigned getOperandNo() const {
2983 assert(isOperand());
2984 return OperandNo;
2985 }
2986
getRange()2987 CharSourceRange getRange() const {
2988 assert(isOperand() && "Range is currently used only for Operands.");
2989 return Range;
2990 }
2991
2992 /// getModifier - Get the modifier for this operand, if present. This
2993 /// returns '\0' if there was no modifier.
2994 char getModifier() const;
2995 };
2996
2997 /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
2998 /// it into pieces. If the asm string is erroneous, emit errors and return
2999 /// true, otherwise return false. This handles canonicalization and
3000 /// translation of strings from GCC syntax to LLVM IR syntax, and handles
3001 //// flattening of named references like %[foo] to Operand AsmStringPiece's.
3002 unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces,
3003 const ASTContext &C, unsigned &DiagOffs) const;
3004
3005 /// Assemble final IR asm string.
3006 std::string generateAsmString(const ASTContext &C) const;
3007
3008 //===--- Output operands ---===//
3009
getOutputIdentifier(unsigned i)3010 IdentifierInfo *getOutputIdentifier(unsigned i) const { return Names[i]; }
3011
getOutputName(unsigned i)3012 StringRef getOutputName(unsigned i) const {
3013 if (IdentifierInfo *II = getOutputIdentifier(i))
3014 return II->getName();
3015
3016 return {};
3017 }
3018
3019 StringRef getOutputConstraint(unsigned i) const;
3020
getOutputConstraintLiteral(unsigned i)3021 const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
3022 return Constraints[i];
3023 }
getOutputConstraintLiteral(unsigned i)3024 StringLiteral *getOutputConstraintLiteral(unsigned i) {
3025 return Constraints[i];
3026 }
3027
3028 Expr *getOutputExpr(unsigned i);
3029
getOutputExpr(unsigned i)3030 const Expr *getOutputExpr(unsigned i) const {
3031 return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i);
3032 }
3033
3034 //===--- Input operands ---===//
3035
getInputIdentifier(unsigned i)3036 IdentifierInfo *getInputIdentifier(unsigned i) const {
3037 return Names[i + NumOutputs];
3038 }
3039
getInputName(unsigned i)3040 StringRef getInputName(unsigned i) const {
3041 if (IdentifierInfo *II = getInputIdentifier(i))
3042 return II->getName();
3043
3044 return {};
3045 }
3046
3047 StringRef getInputConstraint(unsigned i) const;
3048
getInputConstraintLiteral(unsigned i)3049 const StringLiteral *getInputConstraintLiteral(unsigned i) const {
3050 return Constraints[i + NumOutputs];
3051 }
getInputConstraintLiteral(unsigned i)3052 StringLiteral *getInputConstraintLiteral(unsigned i) {
3053 return Constraints[i + NumOutputs];
3054 }
3055
3056 Expr *getInputExpr(unsigned i);
3057 void setInputExpr(unsigned i, Expr *E);
3058
getInputExpr(unsigned i)3059 const Expr *getInputExpr(unsigned i) const {
3060 return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
3061 }
3062
3063 //===--- Labels ---===//
3064
isAsmGoto()3065 bool isAsmGoto() const {
3066 return NumLabels > 0;
3067 }
3068
getNumLabels()3069 unsigned getNumLabels() const {
3070 return NumLabels;
3071 }
3072
getLabelIdentifier(unsigned i)3073 IdentifierInfo *getLabelIdentifier(unsigned i) const {
3074 return Names[i + NumOutputs + NumInputs];
3075 }
3076
3077 AddrLabelExpr *getLabelExpr(unsigned i) const;
3078 StringRef getLabelName(unsigned i) const;
3079 using labels_iterator = CastIterator<AddrLabelExpr>;
3080 using const_labels_iterator = ConstCastIterator<AddrLabelExpr>;
3081 using labels_range = llvm::iterator_range<labels_iterator>;
3082 using labels_const_range = llvm::iterator_range<const_labels_iterator>;
3083
begin_labels()3084 labels_iterator begin_labels() {
3085 return &Exprs[0] + NumOutputs + NumInputs;
3086 }
3087
end_labels()3088 labels_iterator end_labels() {
3089 return &Exprs[0] + NumOutputs + NumInputs + NumLabels;
3090 }
3091
labels()3092 labels_range labels() {
3093 return labels_range(begin_labels(), end_labels());
3094 }
3095
begin_labels()3096 const_labels_iterator begin_labels() const {
3097 return &Exprs[0] + NumOutputs + NumInputs;
3098 }
3099
end_labels()3100 const_labels_iterator end_labels() const {
3101 return &Exprs[0] + NumOutputs + NumInputs + NumLabels;
3102 }
3103
labels()3104 labels_const_range labels() const {
3105 return labels_const_range(begin_labels(), end_labels());
3106 }
3107
3108 private:
3109 void setOutputsAndInputsAndClobbers(const ASTContext &C,
3110 IdentifierInfo **Names,
3111 StringLiteral **Constraints,
3112 Stmt **Exprs,
3113 unsigned NumOutputs,
3114 unsigned NumInputs,
3115 unsigned NumLabels,
3116 StringLiteral **Clobbers,
3117 unsigned NumClobbers);
3118
3119 public:
3120 //===--- Other ---===//
3121
3122 /// getNamedOperand - Given a symbolic operand reference like %[foo],
3123 /// translate this into a numeric value needed to reference the same operand.
3124 /// This returns -1 if the operand name is invalid.
3125 int getNamedOperand(StringRef SymbolicName) const;
3126
3127 StringRef getClobber(unsigned i) const;
3128
getClobberStringLiteral(unsigned i)3129 StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; }
getClobberStringLiteral(unsigned i)3130 const StringLiteral *getClobberStringLiteral(unsigned i) const {
3131 return Clobbers[i];
3132 }
3133
getBeginLoc()3134 SourceLocation getBeginLoc() const LLVM_READONLY { return AsmLoc; }
getEndLoc()3135 SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
3136
classof(const Stmt * T)3137 static bool classof(const Stmt *T) {
3138 return T->getStmtClass() == GCCAsmStmtClass;
3139 }
3140 };
3141
3142 /// This represents a Microsoft inline-assembly statement extension.
3143 class MSAsmStmt : public AsmStmt {
3144 friend class ASTStmtReader;
3145
3146 SourceLocation LBraceLoc, EndLoc;
3147 StringRef AsmStr;
3148
3149 unsigned NumAsmToks = 0;
3150
3151 Token *AsmToks = nullptr;
3152 StringRef *Constraints = nullptr;
3153 StringRef *Clobbers = nullptr;
3154
3155 public:
3156 MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
3157 SourceLocation lbraceloc, bool issimple, bool isvolatile,
3158 ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs,
3159 ArrayRef<StringRef> constraints,
3160 ArrayRef<Expr*> exprs, StringRef asmstr,
3161 ArrayRef<StringRef> clobbers, SourceLocation endloc);
3162
3163 /// Build an empty MS-style inline-assembly statement.
MSAsmStmt(EmptyShell Empty)3164 explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty) {}
3165
getLBraceLoc()3166 SourceLocation getLBraceLoc() const { return LBraceLoc; }
setLBraceLoc(SourceLocation L)3167 void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
getEndLoc()3168 SourceLocation getEndLoc() const { return EndLoc; }
setEndLoc(SourceLocation L)3169 void setEndLoc(SourceLocation L) { EndLoc = L; }
3170
hasBraces()3171 bool hasBraces() const { return LBraceLoc.isValid(); }
3172
getNumAsmToks()3173 unsigned getNumAsmToks() { return NumAsmToks; }
getAsmToks()3174 Token *getAsmToks() { return AsmToks; }
3175
3176 //===--- Asm String Analysis ---===//
getAsmString()3177 StringRef getAsmString() const { return AsmStr; }
3178
3179 /// Assemble final IR asm string.
3180 std::string generateAsmString(const ASTContext &C) const;
3181
3182 //===--- Output operands ---===//
3183
getOutputConstraint(unsigned i)3184 StringRef getOutputConstraint(unsigned i) const {
3185 assert(i < NumOutputs);
3186 return Constraints[i];
3187 }
3188
3189 Expr *getOutputExpr(unsigned i);
3190
getOutputExpr(unsigned i)3191 const Expr *getOutputExpr(unsigned i) const {
3192 return const_cast<MSAsmStmt*>(this)->getOutputExpr(i);
3193 }
3194
3195 //===--- Input operands ---===//
3196
getInputConstraint(unsigned i)3197 StringRef getInputConstraint(unsigned i) const {
3198 assert(i < NumInputs);
3199 return Constraints[i + NumOutputs];
3200 }
3201
3202 Expr *getInputExpr(unsigned i);
3203 void setInputExpr(unsigned i, Expr *E);
3204
getInputExpr(unsigned i)3205 const Expr *getInputExpr(unsigned i) const {
3206 return const_cast<MSAsmStmt*>(this)->getInputExpr(i);
3207 }
3208
3209 //===--- Other ---===//
3210
getAllConstraints()3211 ArrayRef<StringRef> getAllConstraints() const {
3212 return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs);
3213 }
3214
getClobbers()3215 ArrayRef<StringRef> getClobbers() const {
3216 return llvm::makeArrayRef(Clobbers, NumClobbers);
3217 }
3218
getAllExprs()3219 ArrayRef<Expr*> getAllExprs() const {
3220 return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs),
3221 NumInputs + NumOutputs);
3222 }
3223
getClobber(unsigned i)3224 StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
3225
3226 private:
3227 void initialize(const ASTContext &C, StringRef AsmString,
3228 ArrayRef<Token> AsmToks, ArrayRef<StringRef> Constraints,
3229 ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers);
3230
3231 public:
getBeginLoc()3232 SourceLocation getBeginLoc() const LLVM_READONLY { return AsmLoc; }
3233
classof(const Stmt * T)3234 static bool classof(const Stmt *T) {
3235 return T->getStmtClass() == MSAsmStmtClass;
3236 }
3237
children()3238 child_range children() {
3239 return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
3240 }
3241
children()3242 const_child_range children() const {
3243 return const_child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
3244 }
3245 };
3246
3247 class SEHExceptStmt : public Stmt {
3248 friend class ASTReader;
3249 friend class ASTStmtReader;
3250
3251 SourceLocation Loc;
3252 Stmt *Children[2];
3253
3254 enum { FILTER_EXPR, BLOCK };
3255
3256 SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block);
SEHExceptStmt(EmptyShell E)3257 explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) {}
3258
3259 public:
3260 static SEHExceptStmt* Create(const ASTContext &C,
3261 SourceLocation ExceptLoc,
3262 Expr *FilterExpr,
3263 Stmt *Block);
3264
getBeginLoc()3265 SourceLocation getBeginLoc() const LLVM_READONLY { return getExceptLoc(); }
3266
getExceptLoc()3267 SourceLocation getExceptLoc() const { return Loc; }
getEndLoc()3268 SourceLocation getEndLoc() const { return getBlock()->getEndLoc(); }
3269
getFilterExpr()3270 Expr *getFilterExpr() const {
3271 return reinterpret_cast<Expr*>(Children[FILTER_EXPR]);
3272 }
3273
getBlock()3274 CompoundStmt *getBlock() const {
3275 return cast<CompoundStmt>(Children[BLOCK]);
3276 }
3277
children()3278 child_range children() {
3279 return child_range(Children, Children+2);
3280 }
3281
children()3282 const_child_range children() const {
3283 return const_child_range(Children, Children + 2);
3284 }
3285
classof(const Stmt * T)3286 static bool classof(const Stmt *T) {
3287 return T->getStmtClass() == SEHExceptStmtClass;
3288 }
3289 };
3290
3291 class SEHFinallyStmt : public Stmt {
3292 friend class ASTReader;
3293 friend class ASTStmtReader;
3294
3295 SourceLocation Loc;
3296 Stmt *Block;
3297
3298 SEHFinallyStmt(SourceLocation Loc, Stmt *Block);
SEHFinallyStmt(EmptyShell E)3299 explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) {}
3300
3301 public:
3302 static SEHFinallyStmt* Create(const ASTContext &C,
3303 SourceLocation FinallyLoc,
3304 Stmt *Block);
3305
getBeginLoc()3306 SourceLocation getBeginLoc() const LLVM_READONLY { return getFinallyLoc(); }
3307
getFinallyLoc()3308 SourceLocation getFinallyLoc() const { return Loc; }
getEndLoc()3309 SourceLocation getEndLoc() const { return Block->getEndLoc(); }
3310
getBlock()3311 CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); }
3312
children()3313 child_range children() {
3314 return child_range(&Block,&Block+1);
3315 }
3316
children()3317 const_child_range children() const {
3318 return const_child_range(&Block, &Block + 1);
3319 }
3320
classof(const Stmt * T)3321 static bool classof(const Stmt *T) {
3322 return T->getStmtClass() == SEHFinallyStmtClass;
3323 }
3324 };
3325
3326 class SEHTryStmt : public Stmt {
3327 friend class ASTReader;
3328 friend class ASTStmtReader;
3329
3330 bool IsCXXTry;
3331 SourceLocation TryLoc;
3332 Stmt *Children[2];
3333
3334 enum { TRY = 0, HANDLER = 1 };
3335
3336 SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try'
3337 SourceLocation TryLoc,
3338 Stmt *TryBlock,
3339 Stmt *Handler);
3340
SEHTryStmt(EmptyShell E)3341 explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) {}
3342
3343 public:
3344 static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry,
3345 SourceLocation TryLoc, Stmt *TryBlock,
3346 Stmt *Handler);
3347
getBeginLoc()3348 SourceLocation getBeginLoc() const LLVM_READONLY { return getTryLoc(); }
3349
getTryLoc()3350 SourceLocation getTryLoc() const { return TryLoc; }
getEndLoc()3351 SourceLocation getEndLoc() const { return Children[HANDLER]->getEndLoc(); }
3352
getIsCXXTry()3353 bool getIsCXXTry() const { return IsCXXTry; }
3354
getTryBlock()3355 CompoundStmt* getTryBlock() const {
3356 return cast<CompoundStmt>(Children[TRY]);
3357 }
3358
getHandler()3359 Stmt *getHandler() const { return Children[HANDLER]; }
3360
3361 /// Returns 0 if not defined
3362 SEHExceptStmt *getExceptHandler() const;
3363 SEHFinallyStmt *getFinallyHandler() const;
3364
children()3365 child_range children() {
3366 return child_range(Children, Children+2);
3367 }
3368
children()3369 const_child_range children() const {
3370 return const_child_range(Children, Children + 2);
3371 }
3372
classof(const Stmt * T)3373 static bool classof(const Stmt *T) {
3374 return T->getStmtClass() == SEHTryStmtClass;
3375 }
3376 };
3377
3378 /// Represents a __leave statement.
3379 class SEHLeaveStmt : public Stmt {
3380 SourceLocation LeaveLoc;
3381
3382 public:
SEHLeaveStmt(SourceLocation LL)3383 explicit SEHLeaveStmt(SourceLocation LL)
3384 : Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {}
3385
3386 /// Build an empty __leave statement.
SEHLeaveStmt(EmptyShell Empty)3387 explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) {}
3388
getLeaveLoc()3389 SourceLocation getLeaveLoc() const { return LeaveLoc; }
setLeaveLoc(SourceLocation L)3390 void setLeaveLoc(SourceLocation L) { LeaveLoc = L; }
3391
getBeginLoc()3392 SourceLocation getBeginLoc() const LLVM_READONLY { return LeaveLoc; }
getEndLoc()3393 SourceLocation getEndLoc() const LLVM_READONLY { return LeaveLoc; }
3394
classof(const Stmt * T)3395 static bool classof(const Stmt *T) {
3396 return T->getStmtClass() == SEHLeaveStmtClass;
3397 }
3398
3399 // Iterators
children()3400 child_range children() {
3401 return child_range(child_iterator(), child_iterator());
3402 }
3403
children()3404 const_child_range children() const {
3405 return const_child_range(const_child_iterator(), const_child_iterator());
3406 }
3407 };
3408
3409 /// This captures a statement into a function. For example, the following
3410 /// pragma annotated compound statement can be represented as a CapturedStmt,
3411 /// and this compound statement is the body of an anonymous outlined function.
3412 /// @code
3413 /// #pragma omp parallel
3414 /// {
3415 /// compute();
3416 /// }
3417 /// @endcode
3418 class CapturedStmt : public Stmt {
3419 public:
3420 /// The different capture forms: by 'this', by reference, capture for
3421 /// variable-length array type etc.
3422 enum VariableCaptureKind {
3423 VCK_This,
3424 VCK_ByRef,
3425 VCK_ByCopy,
3426 VCK_VLAType,
3427 };
3428
3429 /// Describes the capture of either a variable, or 'this', or
3430 /// variable-length array type.
3431 class Capture {
3432 llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind;
3433 SourceLocation Loc;
3434
3435 public:
3436 friend class ASTStmtReader;
3437
3438 /// Create a new capture.
3439 ///
3440 /// \param Loc The source location associated with this capture.
3441 ///
3442 /// \param Kind The kind of capture (this, ByRef, ...).
3443 ///
3444 /// \param Var The variable being captured, or null if capturing this.
3445 Capture(SourceLocation Loc, VariableCaptureKind Kind,
3446 VarDecl *Var = nullptr);
3447
3448 /// Determine the kind of capture.
3449 VariableCaptureKind getCaptureKind() const;
3450
3451 /// Retrieve the source location at which the variable or 'this' was
3452 /// first used.
getLocation()3453 SourceLocation getLocation() const { return Loc; }
3454
3455 /// Determine whether this capture handles the C++ 'this' pointer.
capturesThis()3456 bool capturesThis() const { return getCaptureKind() == VCK_This; }
3457
3458 /// Determine whether this capture handles a variable (by reference).
capturesVariable()3459 bool capturesVariable() const { return getCaptureKind() == VCK_ByRef; }
3460
3461 /// Determine whether this capture handles a variable by copy.
capturesVariableByCopy()3462 bool capturesVariableByCopy() const {
3463 return getCaptureKind() == VCK_ByCopy;
3464 }
3465
3466 /// Determine whether this capture handles a variable-length array
3467 /// type.
capturesVariableArrayType()3468 bool capturesVariableArrayType() const {
3469 return getCaptureKind() == VCK_VLAType;
3470 }
3471
3472 /// Retrieve the declaration of the variable being captured.
3473 ///
3474 /// This operation is only valid if this capture captures a variable.
3475 VarDecl *getCapturedVar() const;
3476 };
3477
3478 private:
3479 /// The number of variable captured, including 'this'.
3480 unsigned NumCaptures;
3481
3482 /// The pointer part is the implicit the outlined function and the
3483 /// int part is the captured region kind, 'CR_Default' etc.
3484 llvm::PointerIntPair<CapturedDecl *, 2, CapturedRegionKind> CapDeclAndKind;
3485
3486 /// The record for captured variables, a RecordDecl or CXXRecordDecl.
3487 RecordDecl *TheRecordDecl = nullptr;
3488
3489 /// Construct a captured statement.
3490 CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures,
3491 ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD);
3492
3493 /// Construct an empty captured statement.
3494 CapturedStmt(EmptyShell Empty, unsigned NumCaptures);
3495
getStoredStmts()3496 Stmt **getStoredStmts() { return reinterpret_cast<Stmt **>(this + 1); }
3497
getStoredStmts()3498 Stmt *const *getStoredStmts() const {
3499 return reinterpret_cast<Stmt *const *>(this + 1);
3500 }
3501
3502 Capture *getStoredCaptures() const;
3503
setCapturedStmt(Stmt * S)3504 void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; }
3505
3506 public:
3507 friend class ASTStmtReader;
3508
3509 static CapturedStmt *Create(const ASTContext &Context, Stmt *S,
3510 CapturedRegionKind Kind,
3511 ArrayRef<Capture> Captures,
3512 ArrayRef<Expr *> CaptureInits,
3513 CapturedDecl *CD, RecordDecl *RD);
3514
3515 static CapturedStmt *CreateDeserialized(const ASTContext &Context,
3516 unsigned NumCaptures);
3517
3518 /// Retrieve the statement being captured.
getCapturedStmt()3519 Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; }
getCapturedStmt()3520 const Stmt *getCapturedStmt() const { return getStoredStmts()[NumCaptures]; }
3521
3522 /// Retrieve the outlined function declaration.
3523 CapturedDecl *getCapturedDecl();
3524 const CapturedDecl *getCapturedDecl() const;
3525
3526 /// Set the outlined function declaration.
3527 void setCapturedDecl(CapturedDecl *D);
3528
3529 /// Retrieve the captured region kind.
3530 CapturedRegionKind getCapturedRegionKind() const;
3531
3532 /// Set the captured region kind.
3533 void setCapturedRegionKind(CapturedRegionKind Kind);
3534
3535 /// Retrieve the record declaration for captured variables.
getCapturedRecordDecl()3536 const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; }
3537
3538 /// Set the record declaration for captured variables.
setCapturedRecordDecl(RecordDecl * D)3539 void setCapturedRecordDecl(RecordDecl *D) {
3540 assert(D && "null RecordDecl");
3541 TheRecordDecl = D;
3542 }
3543
3544 /// True if this variable has been captured.
3545 bool capturesVariable(const VarDecl *Var) const;
3546
3547 /// An iterator that walks over the captures.
3548 using capture_iterator = Capture *;
3549 using const_capture_iterator = const Capture *;
3550 using capture_range = llvm::iterator_range<capture_iterator>;
3551 using capture_const_range = llvm::iterator_range<const_capture_iterator>;
3552
captures()3553 capture_range captures() {
3554 return capture_range(capture_begin(), capture_end());
3555 }
captures()3556 capture_const_range captures() const {
3557 return capture_const_range(capture_begin(), capture_end());
3558 }
3559
3560 /// Retrieve an iterator pointing to the first capture.
capture_begin()3561 capture_iterator capture_begin() { return getStoredCaptures(); }
capture_begin()3562 const_capture_iterator capture_begin() const { return getStoredCaptures(); }
3563
3564 /// Retrieve an iterator pointing past the end of the sequence of
3565 /// captures.
capture_end()3566 capture_iterator capture_end() const {
3567 return getStoredCaptures() + NumCaptures;
3568 }
3569
3570 /// Retrieve the number of captures, including 'this'.
capture_size()3571 unsigned capture_size() const { return NumCaptures; }
3572
3573 /// Iterator that walks over the capture initialization arguments.
3574 using capture_init_iterator = Expr **;
3575 using capture_init_range = llvm::iterator_range<capture_init_iterator>;
3576
3577 /// Const iterator that walks over the capture initialization
3578 /// arguments.
3579 using const_capture_init_iterator = Expr *const *;
3580 using const_capture_init_range =
3581 llvm::iterator_range<const_capture_init_iterator>;
3582
capture_inits()3583 capture_init_range capture_inits() {
3584 return capture_init_range(capture_init_begin(), capture_init_end());
3585 }
3586
capture_inits()3587 const_capture_init_range capture_inits() const {
3588 return const_capture_init_range(capture_init_begin(), capture_init_end());
3589 }
3590
3591 /// Retrieve the first initialization argument.
capture_init_begin()3592 capture_init_iterator capture_init_begin() {
3593 return reinterpret_cast<Expr **>(getStoredStmts());
3594 }
3595
capture_init_begin()3596 const_capture_init_iterator capture_init_begin() const {
3597 return reinterpret_cast<Expr *const *>(getStoredStmts());
3598 }
3599
3600 /// Retrieve the iterator pointing one past the last initialization
3601 /// argument.
capture_init_end()3602 capture_init_iterator capture_init_end() {
3603 return capture_init_begin() + NumCaptures;
3604 }
3605
capture_init_end()3606 const_capture_init_iterator capture_init_end() const {
3607 return capture_init_begin() + NumCaptures;
3608 }
3609
getBeginLoc()3610 SourceLocation getBeginLoc() const LLVM_READONLY {
3611 return getCapturedStmt()->getBeginLoc();
3612 }
3613
getEndLoc()3614 SourceLocation getEndLoc() const LLVM_READONLY {
3615 return getCapturedStmt()->getEndLoc();
3616 }
3617
getSourceRange()3618 SourceRange getSourceRange() const LLVM_READONLY {
3619 return getCapturedStmt()->getSourceRange();
3620 }
3621
classof(const Stmt * T)3622 static bool classof(const Stmt *T) {
3623 return T->getStmtClass() == CapturedStmtClass;
3624 }
3625
3626 child_range children();
3627
3628 const_child_range children() const;
3629 };
3630
3631 } // namespace clang
3632
3633 #endif // LLVM_CLANG_AST_STMT_H
3634